From d996dd48d0e298a093bf453215aa7c07d630d76b Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Fri, 30 May 2025 17:16:15 +0200 Subject: [PATCH] GH-2332 - Move to jSpecify for nullability verification. --- .mvn/jvm.config | 10 ++++ pom.xml | 55 +++++++++++++++++++ .../springframework/hateoas/Affordance.java | 24 +++++++- .../hateoas/AffordanceModel.java | 2 +- .../hateoas/CollectionModel.java | 6 +- .../springframework/hateoas/EntityModel.java | 13 ++--- .../springframework/hateoas/InputType.java | 2 - .../org/springframework/hateoas/Link.java | 5 +- .../org/springframework/hateoas/Links.java | 2 +- .../springframework/hateoas/NonComposite.java | 2 - .../springframework/hateoas/PagedModel.java | 7 +-- .../hateoas/QueryParameter.java | 2 +- .../hateoas/RepresentationModel.java | 2 +- .../springframework/hateoas/SlicedModel.java | 7 +-- .../hateoas/StringLinkRelation.java | 2 +- .../hateoas/TemplateVariable.java | 3 +- .../hateoas/TemplateVariables.java | 2 +- .../springframework/hateoas/UriTemplate.java | 2 +- ...ontrollerMethodReturnTypeAotProcessor.java | 8 +-- .../hateoas/aot/HateoasTypesRuntimeHints.java | 3 +- .../aot/HypermediaTypeAotProcessor.java | 3 +- .../aot/HypermediaTypesRuntimeHints.java | 3 +- ...resentationModelAssemblerAotProcessor.java | 7 +-- .../hateoas/aot/package-info.java | 8 +++ .../springframework/hateoas/client/Hop.java | 2 +- .../client/JsonPathLinkDiscoverer.java | 2 +- .../hateoas/client/LinkDiscoverers.java | 1 - .../springframework/hateoas/client/Rels.java | 2 +- .../hateoas/client/Traverson.java | 31 ++++++----- .../hateoas/client/package-info.java | 2 +- .../hateoas/config/HateoasConfiguration.java | 2 +- ...HypermediaConfigurationImportSelector.java | 9 ++- .../config/HypermediaMappingInformation.java | 2 +- ...ypermediaMappingInformationComparator.java | 2 +- .../config/HypermediaWebClientConfigurer.java | 4 -- .../HypermediaWebTestClientConfigurer.java | 2 +- .../RestTemplateHateoasConfiguration.java | 2 +- .../config/WebClientHateoasConfiguration.java | 2 +- .../WebMvcEntityLinksConfiguration.java | 1 - .../config/WebMvcHateoasConfiguration.java | 7 ++- .../config/WebStackImportSelector.java | 2 +- .../config/WebfluxCodecCustomizer.java | 2 +- .../hateoas/config/package-info.java | 2 +- .../mediatype/AffordanceOperations.java | 1 - .../hateoas/mediatype/Affordances.java | 2 +- .../mediatype/ConfigurableAffordance.java | 3 +- .../ConfigurableHandlerInstantiator.java | 2 +- .../mediatype/ConfiguredAffordance.java | 2 - .../mediatype/DefaultOnlyMessageResolver.java | 2 +- .../hateoas/mediatype/InputTypeFactory.java | 3 +- .../MediaTypeConfigurationFactory.java | 3 +- .../hateoas/mediatype/MessageResolver.java | 3 +- .../mediatype/MessageSourceResolver.java | 2 +- .../hateoas/mediatype/PropertyUtils.java | 6 +- .../mediatype/TypeBasedPayloadMetadata.java | 2 +- .../hateoas/mediatype/alps/Alps.java | 38 ++++++++----- .../mediatype/alps/AlpsLinkDiscoverer.java | 1 - .../hateoas/mediatype/alps/Descriptor.java | 49 ++++++++++------- .../hateoas/mediatype/alps/Doc.java | 30 ++++++---- .../hateoas/mediatype/alps/Ext.java | 22 +++++--- .../hateoas/mediatype/alps/package-info.java | 2 +- .../collectionjson/CollectionJson.java | 2 +- .../CollectionJsonAffordanceModel.java | 4 +- .../collectionjson/CollectionJsonData.java | 2 +- .../collectionjson/CollectionJsonError.java | 11 +++- .../collectionjson/CollectionJsonItem.java | 15 +++-- .../CollectionJsonLinkDiscoverer.java | 1 - .../CollectionJsonMediaTypeConfiguration.java | 2 +- .../collectionjson/CollectionJsonQuery.java | 11 +++- .../CollectionJsonTemplate.java | 15 +++-- .../Jackson2CollectionJsonModule.java | 9 ++- .../collectionjson/package-info.java | 2 +- .../mediatype/hal/DefaultCurieProvider.java | 6 +- .../mediatype/hal/HalEmbeddedBuilder.java | 9 ++- .../mediatype/hal/HalLinkDiscoverer.java | 8 ++- .../mediatype/hal/HalLinkRelation.java | 8 +-- .../mediatype/hal/HalModelBuilder.java | 26 ++++++--- .../mediatype/hal/Jackson2HalModule.java | 9 ++- .../hal/RepresentationModelMixin.java | 1 - .../hal/forms/HalFormsAffordanceModel.java | 1 - .../hal/forms/HalFormsConfiguration.java | 2 +- .../hal/forms/HalFormsDeserializers.java | 2 +- .../forms/HalFormsHttpMessageConverter.java | 2 +- .../hal/forms/HalFormsLinkDiscoverer.java | 1 - .../mediatype/hal/forms/HalFormsOptions.java | 2 +- .../hal/forms/HalFormsOptionsFactory.java | 2 +- .../mediatype/hal/forms/HalFormsProperty.java | 4 +- .../hal/forms/HalFormsPropertyFactory.java | 8 +-- .../mediatype/hal/forms/HalFormsTemplate.java | 4 +- .../hal/forms/HalFormsTemplateBuilder.java | 8 +-- .../mediatype/hal/forms/package-info.java | 4 +- .../hateoas/mediatype/hal/package-info.java | 2 +- .../hateoas/mediatype/html/HtmlInputType.java | 3 +- .../mediatype/html/HtmlInputTypeFactory.java | 2 +- .../hateoas/mediatype/html/package-info.java | 2 +- .../hateoas/mediatype/package-info.java | 4 +- .../hateoas/mediatype/problem/Problem.java | 21 +++++-- .../mediatype/problem/package-info.java | 2 +- .../mediatype/uber/Jackson2UberModule.java | 10 ++-- .../hateoas/mediatype/uber/Uber.java | 10 +++- .../hateoas/mediatype/uber/UberAction.java | 2 +- .../mediatype/uber/UberAffordanceModel.java | 2 +- .../hateoas/mediatype/uber/UberData.java | 24 +++++--- .../hateoas/mediatype/uber/UberDocument.java | 2 +- .../hateoas/mediatype/uber/UberError.java | 11 +++- .../uber/UberMediaTypeConfiguration.java | 2 +- .../hateoas/mediatype/uber/package-info.java | 4 +- .../mediatype/vnderrors/VndErrors.java | 4 +- .../mediatype/vnderrors/package-info.java | 4 +- .../springframework/hateoas/package-info.java | 2 +- .../hateoas/server/EntityLinks.java | 1 - .../hateoas/server/ExposesResourceFor.java | 2 - .../hateoas/server/LinkBuilder.java | 3 +- .../hateoas/server/LinkRelationProvider.java | 15 ++--- .../server/MethodLinkBuilderFactory.java | 3 - .../server/RepresentationModelProcessor.java | 2 - .../hateoas/server/TypedEntityLinks.java | 1 - .../server/core/AnnotationAttribute.java | 4 +- .../core/AnnotationLinkRelationProvider.java | 2 +- .../core/AnnotationMappingDiscoverer.java | 4 +- .../server/core/CachingMappingDiscoverer.java | 2 +- .../server/core/ControllerEntityLinks.java | 2 - .../ControllerEntityLinksFactoryBean.java | 18 ++++-- .../server/core/DefaultMethodInvocation.java | 2 +- .../server/core/DummyInvocationUtils.java | 7 +-- .../hateoas/server/core/EmbeddedWrapper.java | 3 +- .../hateoas/server/core/EmbeddedWrappers.java | 4 +- .../EvoInflectorLinkRelationProvider.java | 1 - .../core/HeaderLinksResponseEntity.java | 3 - .../server/core/LastInvocationAware.java | 3 + .../server/core/LinkBuilderSupport.java | 2 +- .../server/core/MappingDiscoverer.java | 2 +- .../hateoas/server/core/MethodParameters.java | 8 +-- .../PropertyResolvingMappingDiscoverer.java | 2 +- .../hateoas/server/core/Relation.java | 2 - .../server/core/SpringAffordanceBuilder.java | 2 +- .../hateoas/server/core/TypeReferences.java | 2 +- .../hateoas/server/core/UriMapping.java | 2 +- .../server/core/UriTemplateFactory.java | 2 +- .../hateoas/server/core/WebHandler.java | 19 ++++--- .../hateoas/server/core/package-info.java | 4 +- .../hateoas/server/mvc/BasicLinkBuilder.java | 2 - .../server/mvc/JacksonSerializers.java | 1 - ...cessorHandlerMethodReturnValueHandler.java | 7 ++- .../RepresentationModelProcessorInvoker.java | 2 +- ...edMappingJackson2HttpMessageConverter.java | 2 +- .../mvc/UriComponentsBuilderFactory.java | 2 +- .../server/mvc/UriComponentsContributor.java | 4 +- .../hateoas/server/mvc/WebMvcLinkBuilder.java | 1 - .../server/mvc/WebMvcLinkBuilderFactory.java | 2 - .../hateoas/server/mvc/package-info.java | 4 +- .../hateoas/server/package-info.java | 4 +- .../ReactiveRepresentationModelAssembler.java | 2 - ...eReactiveRepresentationModelAssembler.java | 2 - .../server/reactive/WebFluxLinkBuilder.java | 23 ++++---- .../hateoas/server/reactive/package-info.java | 4 +- .../hateoas/support/ClassUtils.java | 2 +- .../hateoas/support/package-info.java | 4 +- .../server/mvc/WebMvcAffordanceBuilderDsl.kt | 4 +- .../server/mvc/WebMvcLinkBuilderDsl.kt | 10 ++-- .../hateoas/ArchitectureTest.java | 2 +- .../hateoas/CollectionModelUnitTest.java | 2 +- ...nableHypermediaSupportIntegrationTest.java | 2 +- .../hal/Jackson2HalIntegrationTest.java | 2 +- .../Jackson2HalFormsIntegrationTest.java | 2 +- .../uber/Jackson2UberIntegrationTest.java | 3 +- .../server/mvc/WebMvcLinkBuilderUnitTest.java | 3 +- .../reactive/WebFluxLinkBuilderTest.java | 2 +- .../hateoas/support/ContextTester.java | 3 +- .../hateoas/support/JsonPathUtils.java | 3 +- .../mvc/WebMvcAffordanceBuilderDslUnitTest.kt | 14 ++--- 171 files changed, 560 insertions(+), 415 deletions(-) create mode 100644 .mvn/jvm.config create mode 100644 src/main/java/org/springframework/hateoas/aot/package-info.java diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 00000000..32599cef --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1,10 @@ +--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED +--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED diff --git a/pom.xml b/pom.xml index b4d33f6f..2cd53a4b 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,7 @@ 3.6.2 3.27.3 0.0.7 + 2.36.0 1.3 1.5.18 0.8.12 @@ -81,6 +82,7 @@ 2.9.0 5.12.2 1.18.38 + 0.12.7 2024.0.6 2.0.17 7.0.0-M5 @@ -149,6 +151,54 @@ + + nullaway + + + + org.apache.maven.plugins + maven-compiler-plugin + + true + + + + + default-compile + none + + + java-compile + compile + + compile + + + + + com.google.errorprone + error_prone_core + ${errorprone.version} + + + com.uber.nullaway + nullaway + ${nullaway.version} + + + + -XDcompilePolicy=simple + --should-stop=ifError=FLOW + -Xplugin:ErrorProne -XepDisableAllChecks -Xep:NullAway:ERROR -XepOpt:NullAway:OnlyNullMarked=true -XepOpt:NullAway:CustomContractAnnotations=org.springframework.lang.Contract + + + + + + + + + artifactory @@ -469,6 +519,11 @@ kotlinx-coroutines-reactor true + + org.jspecify + jspecify + 1.0.0 + org.jetbrains.kotlin kotlin-test diff --git a/src/main/java/org/springframework/hateoas/Affordance.java b/src/main/java/org/springframework/hateoas/Affordance.java index 56a35465..2109c1c4 100644 --- a/src/main/java/org/springframework/hateoas/Affordance.java +++ b/src/main/java/org/springframework/hateoas/Affordance.java @@ -19,8 +19,9 @@ import java.util.Iterator; import java.util.Map; import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * Hold the {@link AffordanceModel}s for all supported media types. @@ -42,8 +43,8 @@ public final class Affordance implements Iterable { /** * Look up the {@link AffordanceModel} for the requested {@link MediaType}. * - * @param mediaType - * @return + * @param mediaType must not be {@literal null}. + * @return can be {@literal null}. */ @Nullable @SuppressWarnings("unchecked") @@ -51,6 +52,23 @@ public final class Affordance implements Iterable { return (T) this.models.get(mediaType); } + /** + * Look up the {@link AffordanceModel} for the requested {@link MediaType}. + * + * @param mediaType must not be {@literal null}. + * @return will never be {@literal null}. + * @since 3.0 + */ + @SuppressWarnings("unchecked") + public T getRequiredAffordanceModel(MediaType mediaType) { + + var result = getAffordanceModel(mediaType); + + Assert.notNull(result, () -> "No affordance model found for %s!".formatted(mediaType)); + + return (T) result; + } + /* * (non-Javadoc) * @see java.lang.Iterable#iterator() diff --git a/src/main/java/org/springframework/hateoas/AffordanceModel.java b/src/main/java/org/springframework/hateoas/AffordanceModel.java index 51d30549..35c86350 100644 --- a/src/main/java/org/springframework/hateoas/AffordanceModel.java +++ b/src/main/java/org/springframework/hateoas/AffordanceModel.java @@ -24,10 +24,10 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.core.ResolvableType; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/hateoas/CollectionModel.java b/src/main/java/org/springframework/hateoas/CollectionModel.java index a662813e..312dd27e 100644 --- a/src/main/java/org/springframework/hateoas/CollectionModel.java +++ b/src/main/java/org/springframework/hateoas/CollectionModel.java @@ -22,11 +22,11 @@ import java.util.Collections; import java.util.Iterator; import java.util.Objects; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableTypeProvider; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -44,7 +44,7 @@ public class CollectionModel extends RepresentationModel> private final Collection content; private final @Nullable ResolvableType fallbackType; - private ResolvableType fullType; + private @Nullable ResolvableType fullType; /** * Creates an empty {@link CollectionModel} instance. diff --git a/src/main/java/org/springframework/hateoas/EntityModel.java b/src/main/java/org/springframework/hateoas/EntityModel.java index d74354ea..0fcc2adc 100644 --- a/src/main/java/org/springframework/hateoas/EntityModel.java +++ b/src/main/java/org/springframework/hateoas/EntityModel.java @@ -21,9 +21,10 @@ import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonAnyGetter; @@ -50,7 +51,7 @@ import com.fasterxml.jackson.databind.util.NameTransformer; */ public class EntityModel extends RepresentationModel> { - private T content; + private @Nullable T content; /** * Creates an empty {@link EntityModel}. @@ -118,19 +119,17 @@ public class EntityModel extends RepresentationModel> { * * @return the content */ - @Nullable @JsonUnwrapped @JsonSerialize(using = MapSuppressingUnwrappingSerializer.class) public T getContent() { - return content; + return Objects.requireNonNull(content); } // Hacks to allow deserialization into an EntityModel> - @Nullable @JsonAnyGetter @SuppressWarnings("unchecked") - private Map getMapContent() { + private @Nullable Map getMapContent() { return Map.class.isInstance(content) ? (Map) content : null; } diff --git a/src/main/java/org/springframework/hateoas/InputType.java b/src/main/java/org/springframework/hateoas/InputType.java index a2d07adf..5ed3aed0 100644 --- a/src/main/java/org/springframework/hateoas/InputType.java +++ b/src/main/java/org/springframework/hateoas/InputType.java @@ -22,8 +22,6 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import org.springframework.hateoas.mediatype.html.HtmlInputType; - /** * Annotation to declare a dedicated input type for a property of an representation model. Input types are usually * derived from the property's type or JSR-303 validation annotations. Use this annotation to override the type. diff --git a/src/main/java/org/springframework/hateoas/Link.java b/src/main/java/org/springframework/hateoas/Link.java index c277599a..aa2468a2 100755 --- a/src/main/java/org/springframework/hateoas/Link.java +++ b/src/main/java/org/springframework/hateoas/Link.java @@ -23,7 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -184,7 +184,10 @@ public class Link implements Serializable { * Empty constructor required by the marshaling framework. */ protected Link() { + this.affordances = new ArrayList<>(); + this.rel = LinkRelation.of("__synthetic__"); + this.href = "__synthetic__"; } /** diff --git a/src/main/java/org/springframework/hateoas/Links.java b/src/main/java/org/springframework/hateoas/Links.java index 548dd0de..1d302d4d 100644 --- a/src/main/java/org/springframework/hateoas/Links.java +++ b/src/main/java/org/springframework/hateoas/Links.java @@ -28,7 +28,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/src/main/java/org/springframework/hateoas/NonComposite.java b/src/main/java/org/springframework/hateoas/NonComposite.java index e5ebc698..ca853f24 100644 --- a/src/main/java/org/springframework/hateoas/NonComposite.java +++ b/src/main/java/org/springframework/hateoas/NonComposite.java @@ -21,8 +21,6 @@ import static java.lang.annotation.RetentionPolicy.*; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import org.springframework.web.bind.annotation.RequestParam; - /** * Annotation to be used in combination with {@link RequestParam} to indicate that collection based values are supposed * to be rendered as non-composite values, i.e. like {@code param=value1,value2,value3} rather than diff --git a/src/main/java/org/springframework/hateoas/PagedModel.java b/src/main/java/org/springframework/hateoas/PagedModel.java index 2bb3298e..5ee3a0b0 100644 --- a/src/main/java/org/springframework/hateoas/PagedModel.java +++ b/src/main/java/org/springframework/hateoas/PagedModel.java @@ -23,9 +23,9 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ResolvableType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -41,7 +41,7 @@ public class PagedModel extends CollectionModel { public static PagedModel NO_PAGE = new PagedModel<>(); - private final PageMetadata metadata; + private final @Nullable PageMetadata metadata; private final @Nullable ResolvableType fallbackType; /** @@ -273,8 +273,7 @@ public class PagedModel extends CollectionModel { * @return the metadata */ @JsonProperty("page") - @Nullable - public PageMetadata getMetadata() { + public @Nullable PageMetadata getMetadata() { return metadata; } diff --git a/src/main/java/org/springframework/hateoas/QueryParameter.java b/src/main/java/org/springframework/hateoas/QueryParameter.java index faccad23..bf8f07e7 100644 --- a/src/main/java/org/springframework/hateoas/QueryParameter.java +++ b/src/main/java/org/springframework/hateoas/QueryParameter.java @@ -18,10 +18,10 @@ package org.springframework.hateoas; import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestParam; diff --git a/src/main/java/org/springframework/hateoas/RepresentationModel.java b/src/main/java/org/springframework/hateoas/RepresentationModel.java index 0d7125ac..8d69a59a 100755 --- a/src/main/java/org/springframework/hateoas/RepresentationModel.java +++ b/src/main/java/org/springframework/hateoas/RepresentationModel.java @@ -25,7 +25,7 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/org/springframework/hateoas/SlicedModel.java b/src/main/java/org/springframework/hateoas/SlicedModel.java index eef2841e..a9d87053 100644 --- a/src/main/java/org/springframework/hateoas/SlicedModel.java +++ b/src/main/java/org/springframework/hateoas/SlicedModel.java @@ -23,9 +23,9 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ResolvableType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -42,7 +42,7 @@ public class SlicedModel extends CollectionModel { public static SlicedModel NO_SLICE = new SlicedModel<>(); - private final SliceMetadata metadata; + private final @Nullable SliceMetadata metadata; private final @Nullable ResolvableType fallbackType; /** @@ -290,9 +290,8 @@ public class SlicedModel extends CollectionModel { * * @return the metadata can be {@literal null}. */ - @Nullable @JsonProperty("page") - public SliceMetadata getMetadata() { + public @Nullable SliceMetadata getMetadata() { return metadata; } diff --git a/src/main/java/org/springframework/hateoas/StringLinkRelation.java b/src/main/java/org/springframework/hateoas/StringLinkRelation.java index a121c2c8..ee25d8c6 100644 --- a/src/main/java/org/springframework/hateoas/StringLinkRelation.java +++ b/src/main/java/org/springframework/hateoas/StringLinkRelation.java @@ -20,7 +20,7 @@ import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/src/main/java/org/springframework/hateoas/TemplateVariable.java b/src/main/java/org/springframework/hateoas/TemplateVariable.java index 23b75bd8..47b5e1d3 100644 --- a/src/main/java/org/springframework/hateoas/TemplateVariable.java +++ b/src/main/java/org/springframework/hateoas/TemplateVariable.java @@ -28,7 +28,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.util.UriUtils; @@ -498,6 +498,7 @@ public final class TemplateVariable implements Serializable, UriTemplate.Expanda /** * @deprecated since 1.4. Use the actual type and call {@link TemplateVariable#composite()}. */ + @Deprecated COMPOSITE_PARAM("*", "", true); private static final EnumSet COMBINABLE_TYPES = EnumSet.of(REQUEST_PARAM, REQUEST_PARAM_CONTINUED); diff --git a/src/main/java/org/springframework/hateoas/TemplateVariables.java b/src/main/java/org/springframework/hateoas/TemplateVariables.java index 6eabdfe1..a71f809e 100644 --- a/src/main/java/org/springframework/hateoas/TemplateVariables.java +++ b/src/main/java/org/springframework/hateoas/TemplateVariables.java @@ -27,8 +27,8 @@ import java.util.List; import java.util.Objects; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.TemplateVariable.VariableType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/hateoas/UriTemplate.java b/src/main/java/org/springframework/hateoas/UriTemplate.java index d2f5f24e..4f7680c7 100644 --- a/src/main/java/org/springframework/hateoas/UriTemplate.java +++ b/src/main/java/org/springframework/hateoas/UriTemplate.java @@ -29,8 +29,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.TemplateVariable.VariableType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; diff --git a/src/main/java/org/springframework/hateoas/aot/ControllerMethodReturnTypeAotProcessor.java b/src/main/java/org/springframework/hateoas/aot/ControllerMethodReturnTypeAotProcessor.java index be21ece4..17c5a76b 100644 --- a/src/main/java/org/springframework/hateoas/aot/ControllerMethodReturnTypeAotProcessor.java +++ b/src/main/java/org/springframework/hateoas/aot/ControllerMethodReturnTypeAotProcessor.java @@ -15,6 +15,7 @@ */ package org.springframework.hateoas.aot; +import static java.util.Objects.*; import static org.springframework.hateoas.aot.AotUtils.*; import java.lang.annotation.Annotation; @@ -23,6 +24,7 @@ import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.aop.framework.AopConfigException; @@ -36,9 +38,7 @@ import org.springframework.beans.factory.aot.BeanRegistrationCode; import org.springframework.beans.factory.support.RegisteredBean; import org.springframework.core.ResolvableType; import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.hateoas.server.core.DummyInvocationUtils; import org.springframework.hateoas.server.core.LastInvocationAware; -import org.springframework.lang.Nullable; import org.springframework.stereotype.Controller; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -176,8 +176,8 @@ public class ControllerMethodReturnTypeAotProcessor implements BeanRegistrationA reflection.registerType(result, MemberCategory.INVOKE_DECLARED_METHODS); - reflection.registerField(ReflectionUtils.findField(result, "CGLIB$FACTORY_DATA")); - reflection.registerField(ReflectionUtils.findField(result, "CGLIB$CALLBACK_FILTER")); + reflection.registerField(requireNonNull(ReflectionUtils.findField(result, "CGLIB$FACTORY_DATA"))); + reflection.registerField(requireNonNull(ReflectionUtils.findField(result, "CGLIB$CALLBACK_FILTER"))); } return result; diff --git a/src/main/java/org/springframework/hateoas/aot/HateoasTypesRuntimeHints.java b/src/main/java/org/springframework/hateoas/aot/HateoasTypesRuntimeHints.java index 79e72b19..b3ce350b 100644 --- a/src/main/java/org/springframework/hateoas/aot/HateoasTypesRuntimeHints.java +++ b/src/main/java/org/springframework/hateoas/aot/HateoasTypesRuntimeHints.java @@ -15,6 +15,7 @@ */ package org.springframework.hateoas.aot; +import org.jspecify.annotations.Nullable; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.hateoas.RepresentationModel; @@ -31,7 +32,7 @@ class HateoasTypesRuntimeHints implements RuntimeHintsRegistrar { * @see org.springframework.aot.hint.RuntimeHintsRegistrar#registerHints(org.springframework.aot.hint.RuntimeHints, java.lang.ClassLoader) */ @Override - public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { var packageName = RepresentationModel.class.getPackageName(); var reflection = hints.reflection(); diff --git a/src/main/java/org/springframework/hateoas/aot/HypermediaTypeAotProcessor.java b/src/main/java/org/springframework/hateoas/aot/HypermediaTypeAotProcessor.java index 26f99d2a..e6ae1c41 100644 --- a/src/main/java/org/springframework/hateoas/aot/HypermediaTypeAotProcessor.java +++ b/src/main/java/org/springframework/hateoas/aot/HypermediaTypeAotProcessor.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Set; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.aot.generate.GenerationContext; import org.springframework.beans.factory.aot.BeanRegistrationAotContribution; import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor; @@ -46,7 +47,7 @@ class HypermediaTypeAotProcessor implements BeanRegistrationAotProcessor { * @see org.springframework.beans.factory.aot.BeanRegistrationAotProcessor#processAheadOfTime(org.springframework.beans.factory.support.RegisteredBean) */ @Override - public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) { + public @Nullable BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) { EnableHypermediaSupport annotation = AnnotatedElementUtils.findMergedAnnotation(registeredBean.getBeanClass(), EnableHypermediaSupport.class); diff --git a/src/main/java/org/springframework/hateoas/aot/HypermediaTypesRuntimeHints.java b/src/main/java/org/springframework/hateoas/aot/HypermediaTypesRuntimeHints.java index 04fafb54..94fd12e0 100644 --- a/src/main/java/org/springframework/hateoas/aot/HypermediaTypesRuntimeHints.java +++ b/src/main/java/org/springframework/hateoas/aot/HypermediaTypesRuntimeHints.java @@ -18,6 +18,7 @@ package org.springframework.hateoas.aot; import java.io.IOException; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.core.annotation.MergedAnnotation; @@ -56,7 +57,7 @@ class HypermediaTypesRuntimeHints implements RuntimeHintsRegistrar { * @see org.springframework.aot.hint.RuntimeHintsRegistrar#registerHints(org.springframework.aot.hint.RuntimeHints, java.lang.ClassLoader) */ @Override - public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { AotUtils.registerTypesForReflection(hypermediaPackage, hints.reflection(), HAS_JACKSON_SUPER_TYPE_FILTER, IS_JACKSON_ANNOTATION_PRESENT_FILTER); diff --git a/src/main/java/org/springframework/hateoas/aot/RepresentationModelAssemblerAotProcessor.java b/src/main/java/org/springframework/hateoas/aot/RepresentationModelAssemblerAotProcessor.java index 926783b1..66fccb4e 100644 --- a/src/main/java/org/springframework/hateoas/aot/RepresentationModelAssemblerAotProcessor.java +++ b/src/main/java/org/springframework/hateoas/aot/RepresentationModelAssemblerAotProcessor.java @@ -17,11 +17,10 @@ package org.springframework.hateoas.aot; import static org.springframework.hateoas.aot.AotUtils.*; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.aot.BeanRegistrationAotContribution; import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor; import org.springframework.beans.factory.support.RegisteredBean; -import org.springframework.hateoas.CollectionModel; -import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.server.RepresentationModelAssembler; /** @@ -38,11 +37,11 @@ class RepresentationModelAssemblerAotProcessor implements BeanRegistrationAotPro * @see org.springframework.beans.factory.aot.BeanRegistrationAotProcessor#processAheadOfTime(org.springframework.beans.factory.support.RegisteredBean) */ @Override - public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) { + public @Nullable BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) { var beanClass = registeredBean.getBeanClass(); - if (!RepresentationModelAssembler.class.isAssignableFrom(beanClass)) { + if (beanClass == null || !RepresentationModelAssembler.class.isAssignableFrom(beanClass)) { return null; } diff --git a/src/main/java/org/springframework/hateoas/aot/package-info.java b/src/main/java/org/springframework/hateoas/aot/package-info.java new file mode 100644 index 00000000..a4fa7f8c --- /dev/null +++ b/src/main/java/org/springframework/hateoas/aot/package-info.java @@ -0,0 +1,8 @@ +/** + * AOT support. + * + * @author Christoph Strobl + * @author Oliver Drotbohm + */ +@org.jspecify.annotations.NullMarked +package org.springframework.hateoas.aot; diff --git a/src/main/java/org/springframework/hateoas/client/Hop.java b/src/main/java/org/springframework/hateoas/client/Hop.java index 85fcd56c..5cc17c7c 100644 --- a/src/main/java/org/springframework/hateoas/client/Hop.java +++ b/src/main/java/org/springframework/hateoas/client/Hop.java @@ -20,8 +20,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.springframework.http.HttpHeaders; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/hateoas/client/JsonPathLinkDiscoverer.java b/src/main/java/org/springframework/hateoas/client/JsonPathLinkDiscoverer.java index ad179a10..892bc6ec 100644 --- a/src/main/java/org/springframework/hateoas/client/JsonPathLinkDiscoverer.java +++ b/src/main/java/org/springframework/hateoas/client/JsonPathLinkDiscoverer.java @@ -24,11 +24,11 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Stream; +import org.jspecify.annotations.NonNull; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.Links; import org.springframework.http.MediaType; -import org.springframework.lang.NonNull; import org.springframework.util.Assert; import com.jayway.jsonpath.InvalidPathException; diff --git a/src/main/java/org/springframework/hateoas/client/LinkDiscoverers.java b/src/main/java/org/springframework/hateoas/client/LinkDiscoverers.java index c73baed7..cae97531 100644 --- a/src/main/java/org/springframework/hateoas/client/LinkDiscoverers.java +++ b/src/main/java/org/springframework/hateoas/client/LinkDiscoverers.java @@ -17,7 +17,6 @@ package org.springframework.hateoas.client; import java.util.Optional; -import org.springframework.hateoas.MediaTypes; import org.springframework.http.MediaType; import org.springframework.plugin.core.PluginRegistry; import org.springframework.util.Assert; diff --git a/src/main/java/org/springframework/hateoas/client/Rels.java b/src/main/java/org/springframework/hateoas/client/Rels.java index 58fe3cbf..0f24670c 100644 --- a/src/main/java/org/springframework/hateoas/client/Rels.java +++ b/src/main/java/org/springframework/hateoas/client/Rels.java @@ -17,9 +17,9 @@ package org.springframework.hateoas.client; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.Link; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.jayway.jsonpath.JsonPath; diff --git a/src/main/java/org/springframework/hateoas/client/Traverson.java b/src/main/java/org/springframework/hateoas/client/Traverson.java index e697695c..8e674788 100644 --- a/src/main/java/org/springframework/hateoas/client/Traverson.java +++ b/src/main/java/org/springframework/hateoas/client/Traverson.java @@ -27,18 +27,17 @@ import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.hateoas.Link; import org.springframework.hateoas.UriTemplate; import org.springframework.hateoas.client.Rels.Rel; -import org.springframework.hateoas.mediatype.hal.HalLinkDiscoverer; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.lang.Nullable; import org.springframework.plugin.core.PluginRegistry; import org.springframework.util.Assert; import org.springframework.web.client.RestOperations; @@ -109,9 +108,8 @@ public class Traverson { this.mediaTypes = mediaTypes; this.baseUri = baseUri; - - setLinkDiscoverers(DEFAULTS.getLinkDiscoverers(mediaTypes)); - setRestOperations(createDefaultTemplate(this.mediaTypes)); + this.discoverers = defaultLinkDiscoverers(DEFAULTS.getLinkDiscoverers(mediaTypes)); + this.operations = createDefaultTemplate(this.mediaTypes); } /** @@ -141,27 +139,21 @@ public class Traverson { */ public Traverson setRestOperations(@Nullable RestOperations operations) { - this.operations = operations == null // - ? createDefaultTemplate(this.mediaTypes) // - : operations; + this.operations = defaultRestOperations(operations); return this; } /** * Sets the {@link LinkDiscoverers} to use. By default a single {@link HalLinkDiscoverer} is registered. If - * {@literal null} is provided the default is reapplied. + * {@literal null} is provided the default is re-applied. * * @param discoverer can be {@literal null}. * @return */ public Traverson setLinkDiscoverers(@Nullable List discoverer) { - List defaultedDiscoverers = discoverer == null // - ? DEFAULTS.getLinkDiscoverers(mediaTypes) // - : discoverer; - - this.discoverers = new LinkDiscoverers(PluginRegistry.of(defaultedDiscoverers)); + this.discoverers = defaultLinkDiscoverers(discoverer); return this; } @@ -187,6 +179,17 @@ public class Traverson { return new TraversalBuilder().follow(hop); } + private RestOperations defaultRestOperations(@Nullable RestOperations operations) { + return operations == null ? createDefaultTemplate(this.mediaTypes) : operations; + } + + private LinkDiscoverers defaultLinkDiscoverers(@Nullable List discoverer) { + + var defaultedDiscoverers = discoverer == null ? DEFAULTS.getLinkDiscoverers(mediaTypes) : discoverer; + + return new LinkDiscoverers(PluginRegistry.of(defaultedDiscoverers)); + } + private HttpEntity prepareRequest(HttpHeaders headers) { HttpHeaders toSend = new HttpHeaders(); diff --git a/src/main/java/org/springframework/hateoas/client/package-info.java b/src/main/java/org/springframework/hateoas/client/package-info.java index 67c03370..a46f7421 100644 --- a/src/main/java/org/springframework/hateoas/client/package-info.java +++ b/src/main/java/org/springframework/hateoas/client/package-info.java @@ -1,5 +1,5 @@ /** * Client side support. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.client; diff --git a/src/main/java/org/springframework/hateoas/config/HateoasConfiguration.java b/src/main/java/org/springframework/hateoas/config/HateoasConfiguration.java index ff80f0ac..2905eeaa 100644 --- a/src/main/java/org/springframework/hateoas/config/HateoasConfiguration.java +++ b/src/main/java/org/springframework/hateoas/config/HateoasConfiguration.java @@ -24,6 +24,7 @@ import java.util.Optional; import java.util.Properties; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; @@ -45,7 +46,6 @@ import org.springframework.hateoas.server.core.DefaultLinkRelationProvider; import org.springframework.hateoas.server.core.DelegatingLinkRelationProvider; import org.springframework.hateoas.server.core.EvoInflectorLinkRelationProvider; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import org.springframework.plugin.core.OrderAwarePluginRegistry; import org.springframework.plugin.core.PluginRegistry; import org.springframework.plugin.core.config.EnablePluginRegistries; diff --git a/src/main/java/org/springframework/hateoas/config/HypermediaConfigurationImportSelector.java b/src/main/java/org/springframework/hateoas/config/HypermediaConfigurationImportSelector.java index 70d1edd9..bf9660fd 100644 --- a/src/main/java/org/springframework/hateoas/config/HypermediaConfigurationImportSelector.java +++ b/src/main/java/org/springframework/hateoas/config/HypermediaConfigurationImportSelector.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -46,8 +47,8 @@ class HypermediaConfigurationImportSelector implements ImportSelector, ResourceL public static final String SPRING_TEST = "org.springframework.test.web.reactive.server.WebTestClient"; - private ResourceLoader resourceLoader; - private ConfigurableBeanFactory beanFactory; + private @Nullable ResourceLoader resourceLoader; + private @Nullable ConfigurableBeanFactory beanFactory; /* * (non-Javadoc) @@ -74,6 +75,10 @@ class HypermediaConfigurationImportSelector implements ImportSelector, ResourceL @Override public String[] selectImports(AnnotationMetadata metadata) { + if (beanFactory == null || resourceLoader == null) { + return new String[0]; + } + Map attributes = metadata.getAnnotationAttributes(EnableHypermediaSupport.class.getName()); List types = attributes == null // diff --git a/src/main/java/org/springframework/hateoas/config/HypermediaMappingInformation.java b/src/main/java/org/springframework/hateoas/config/HypermediaMappingInformation.java index a35817b4..daf98d5e 100644 --- a/src/main/java/org/springframework/hateoas/config/HypermediaMappingInformation.java +++ b/src/main/java/org/springframework/hateoas/config/HypermediaMappingInformation.java @@ -18,9 +18,9 @@ package org.springframework.hateoas.config; import java.util.List; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.RepresentationModel; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.Module; diff --git a/src/main/java/org/springframework/hateoas/config/HypermediaMappingInformationComparator.java b/src/main/java/org/springframework/hateoas/config/HypermediaMappingInformationComparator.java index a516522c..5ab2d901 100644 --- a/src/main/java/org/springframework/hateoas/config/HypermediaMappingInformationComparator.java +++ b/src/main/java/org/springframework/hateoas/config/HypermediaMappingInformationComparator.java @@ -18,8 +18,8 @@ package org.springframework.hateoas.config; import java.util.Comparator; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/hateoas/config/HypermediaWebClientConfigurer.java b/src/main/java/org/springframework/hateoas/config/HypermediaWebClientConfigurer.java index 1f4e9459..6a048db7 100644 --- a/src/main/java/org/springframework/hateoas/config/HypermediaWebClientConfigurer.java +++ b/src/main/java/org/springframework/hateoas/config/HypermediaWebClientConfigurer.java @@ -15,12 +15,8 @@ */ package org.springframework.hateoas.config; -import org.springframework.http.codec.json.Jackson2JsonDecoder; -import org.springframework.http.codec.json.Jackson2JsonEncoder; import org.springframework.web.reactive.function.client.WebClient; -import com.fasterxml.jackson.databind.ObjectMapper; - /** * Assembles {@link Jackson2JsonEncoder}s and {@link Jackson2JsonDecoder}s needed to wire a {@link WebClient} with * hypermedia support. diff --git a/src/main/java/org/springframework/hateoas/config/HypermediaWebTestClientConfigurer.java b/src/main/java/org/springframework/hateoas/config/HypermediaWebTestClientConfigurer.java index 4d1d920e..d3e7e114 100644 --- a/src/main/java/org/springframework/hateoas/config/HypermediaWebTestClientConfigurer.java +++ b/src/main/java/org/springframework/hateoas/config/HypermediaWebTestClientConfigurer.java @@ -18,11 +18,11 @@ package org.springframework.hateoas.config; import java.util.List; import java.util.function.Consumer; +import org.jspecify.annotations.Nullable; import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.http.codec.ClientCodecConfigurer; import org.springframework.http.codec.json.Jackson2JsonDecoder; import org.springframework.http.codec.json.Jackson2JsonEncoder; -import org.springframework.lang.Nullable; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClientConfigurer; import org.springframework.util.Assert; diff --git a/src/main/java/org/springframework/hateoas/config/RestTemplateHateoasConfiguration.java b/src/main/java/org/springframework/hateoas/config/RestTemplateHateoasConfiguration.java index 13652103..591c546b 100644 --- a/src/main/java/org/springframework/hateoas/config/RestTemplateHateoasConfiguration.java +++ b/src/main/java/org/springframework/hateoas/config/RestTemplateHateoasConfiguration.java @@ -15,13 +15,13 @@ */ package org.springframework.hateoas.config; +import org.jspecify.annotations.NonNull; import org.springframework.beans.BeansException; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; -import org.springframework.lang.NonNull; import org.springframework.web.client.RestTemplate; /** diff --git a/src/main/java/org/springframework/hateoas/config/WebClientHateoasConfiguration.java b/src/main/java/org/springframework/hateoas/config/WebClientHateoasConfiguration.java index f4cef7a9..cb0b7588 100644 --- a/src/main/java/org/springframework/hateoas/config/WebClientHateoasConfiguration.java +++ b/src/main/java/org/springframework/hateoas/config/WebClientHateoasConfiguration.java @@ -17,6 +17,7 @@ package org.springframework.hateoas.config; import java.util.List; +import org.jspecify.annotations.NonNull; import org.springframework.beans.BeansException; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.ObjectProvider; @@ -24,7 +25,6 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; -import org.springframework.lang.NonNull; import org.springframework.web.reactive.function.client.WebClient; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/org/springframework/hateoas/config/WebMvcEntityLinksConfiguration.java b/src/main/java/org/springframework/hateoas/config/WebMvcEntityLinksConfiguration.java index 5e5517c1..e4775692 100644 --- a/src/main/java/org/springframework/hateoas/config/WebMvcEntityLinksConfiguration.java +++ b/src/main/java/org/springframework/hateoas/config/WebMvcEntityLinksConfiguration.java @@ -18,7 +18,6 @@ package org.springframework.hateoas.config; import org.springframework.beans.factory.ObjectProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.hateoas.server.EntityLinks; import org.springframework.hateoas.server.core.ControllerEntityLinksFactoryBean; import org.springframework.hateoas.server.mvc.WebMvcLinkBuilderFactory; import org.springframework.stereotype.Controller; diff --git a/src/main/java/org/springframework/hateoas/config/WebMvcHateoasConfiguration.java b/src/main/java/org/springframework/hateoas/config/WebMvcHateoasConfiguration.java index 34979eab..687f5fcf 100644 --- a/src/main/java/org/springframework/hateoas/config/WebMvcHateoasConfiguration.java +++ b/src/main/java/org/springframework/hateoas/config/WebMvcHateoasConfiguration.java @@ -22,6 +22,8 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.BeanPostProcessor; @@ -35,7 +37,6 @@ import org.springframework.hateoas.server.mvc.RepresentationModelProcessorInvoke import org.springframework.hateoas.server.mvc.UriComponentsContributor; import org.springframework.hateoas.server.mvc.WebMvcLinkBuilderFactory; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.lang.NonNull; import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; @@ -162,8 +163,8 @@ class WebMvcHateoasConfiguration { * @see org.springframework.web.servlet.HandlerInterceptor#afterCompletion(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception) */ @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) - throws Exception { + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable Exception ex) { DummyInvocationUtils.resetCache(); } diff --git a/src/main/java/org/springframework/hateoas/config/WebStackImportSelector.java b/src/main/java/org/springframework/hateoas/config/WebStackImportSelector.java index ae250715..7db900e9 100644 --- a/src/main/java/org/springframework/hateoas/config/WebStackImportSelector.java +++ b/src/main/java/org/springframework/hateoas/config/WebStackImportSelector.java @@ -48,7 +48,7 @@ class WebStackImportSelector implements ImportSelector { WebStack[] stacks = (WebStack[]) attributes.get("stacks"); - if (stacks.length == 0) { + if (stacks == null || stacks.length == 0) { throw new IllegalStateException(String.format(WEB_STACK_MISSING, metadata.getClassName())); } diff --git a/src/main/java/org/springframework/hateoas/config/WebfluxCodecCustomizer.java b/src/main/java/org/springframework/hateoas/config/WebfluxCodecCustomizer.java index 839e05b3..ee0273da 100644 --- a/src/main/java/org/springframework/hateoas/config/WebfluxCodecCustomizer.java +++ b/src/main/java/org/springframework/hateoas/config/WebfluxCodecCustomizer.java @@ -19,9 +19,9 @@ import java.util.List; import java.util.function.Consumer; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.http.MediaType; import org.springframework.http.codec.json.Jackson2CodecSupport; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/org/springframework/hateoas/config/package-info.java b/src/main/java/org/springframework/hateoas/config/package-info.java index ca44d9dc..2b33f862 100644 --- a/src/main/java/org/springframework/hateoas/config/package-info.java +++ b/src/main/java/org/springframework/hateoas/config/package-info.java @@ -1,5 +1,5 @@ /** * Spring container configuration support. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.config; diff --git a/src/main/java/org/springframework/hateoas/mediatype/AffordanceOperations.java b/src/main/java/org/springframework/hateoas/mediatype/AffordanceOperations.java index 3421b3a6..0d53ff95 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/AffordanceOperations.java +++ b/src/main/java/org/springframework/hateoas/mediatype/AffordanceOperations.java @@ -15,7 +15,6 @@ */ package org.springframework.hateoas.mediatype; -import org.springframework.hateoas.Affordance; import org.springframework.hateoas.Link; /** diff --git a/src/main/java/org/springframework/hateoas/mediatype/Affordances.java b/src/main/java/org/springframework/hateoas/mediatype/Affordances.java index 990ffe89..db473377 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/Affordances.java +++ b/src/main/java/org/springframework/hateoas/mediatype/Affordances.java @@ -23,6 +23,7 @@ import java.util.Collections; import java.util.List; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.core.ResolvableType; import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.hateoas.Affordance; @@ -32,7 +33,6 @@ import org.springframework.hateoas.Link; import org.springframework.hateoas.QueryParameter; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/hateoas/mediatype/ConfigurableAffordance.java b/src/main/java/org/springframework/hateoas/mediatype/ConfigurableAffordance.java index 4161532c..173f225b 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/ConfigurableAffordance.java +++ b/src/main/java/org/springframework/hateoas/mediatype/ConfigurableAffordance.java @@ -17,14 +17,13 @@ package org.springframework.hateoas.mediatype; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.core.ResolvableType; -import org.springframework.hateoas.Affordance; import org.springframework.hateoas.AffordanceModel.PayloadMetadata; import org.springframework.hateoas.Link; import org.springframework.hateoas.QueryParameter; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; /** * An affordance in creation. API to build up affordances manually to clearly distinguish between building the diff --git a/src/main/java/org/springframework/hateoas/mediatype/ConfigurableHandlerInstantiator.java b/src/main/java/org/springframework/hateoas/mediatype/ConfigurableHandlerInstantiator.java index b9b92365..2e79f1b4 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/ConfigurableHandlerInstantiator.java +++ b/src/main/java/org/springframework/hateoas/mediatype/ConfigurableHandlerInstantiator.java @@ -18,8 +18,8 @@ package org.springframework.hateoas.mediatype; import java.util.HashMap; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.databind.DeserializationConfig; diff --git a/src/main/java/org/springframework/hateoas/mediatype/ConfiguredAffordance.java b/src/main/java/org/springframework/hateoas/mediatype/ConfiguredAffordance.java index 5aca41cc..79517d4e 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/ConfiguredAffordance.java +++ b/src/main/java/org/springframework/hateoas/mediatype/ConfiguredAffordance.java @@ -17,8 +17,6 @@ package org.springframework.hateoas.mediatype; import java.util.List; -import org.springframework.hateoas.Affordance; -import org.springframework.hateoas.AffordanceModel; import org.springframework.hateoas.AffordanceModel.InputPayloadMetadata; import org.springframework.hateoas.AffordanceModel.PayloadMetadata; import org.springframework.hateoas.Link; diff --git a/src/main/java/org/springframework/hateoas/mediatype/DefaultOnlyMessageResolver.java b/src/main/java/org/springframework/hateoas/mediatype/DefaultOnlyMessageResolver.java index a4772f0c..5d80369c 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/DefaultOnlyMessageResolver.java +++ b/src/main/java/org/springframework/hateoas/mediatype/DefaultOnlyMessageResolver.java @@ -15,8 +15,8 @@ */ package org.springframework.hateoas.mediatype; +import org.jspecify.annotations.Nullable; import org.springframework.context.MessageSourceResolvable; -import org.springframework.lang.Nullable; /** * {@link MessageResolver} to always resort to the {@link MessageSourceResolvable}'s default message. diff --git a/src/main/java/org/springframework/hateoas/mediatype/InputTypeFactory.java b/src/main/java/org/springframework/hateoas/mediatype/InputTypeFactory.java index 17362b2b..74b1aaf9 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/InputTypeFactory.java +++ b/src/main/java/org/springframework/hateoas/mediatype/InputTypeFactory.java @@ -15,8 +15,7 @@ */ package org.springframework.hateoas.mediatype; -import org.springframework.core.ResolvableType; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * SPI interface for components that can derive an input type from a {@link ResolvableType}. Primary usage to enable to diff --git a/src/main/java/org/springframework/hateoas/mediatype/MediaTypeConfigurationFactory.java b/src/main/java/org/springframework/hateoas/mediatype/MediaTypeConfigurationFactory.java index 6abad732..7593295f 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/MediaTypeConfigurationFactory.java +++ b/src/main/java/org/springframework/hateoas/mediatype/MediaTypeConfigurationFactory.java @@ -18,6 +18,7 @@ package org.springframework.hateoas.mediatype; import java.util.function.Supplier; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.ObjectProvider; import org.springframework.util.Assert; @@ -33,7 +34,7 @@ public class MediaTypeConfigurationFactory supplier; private final Supplier> customizers; - private T resolved; + private @Nullable T resolved; /** * Creates a new {@link MediaTypeConfigurationFactory} for the given supplier of the original instance and all diff --git a/src/main/java/org/springframework/hateoas/mediatype/MessageResolver.java b/src/main/java/org/springframework/hateoas/mediatype/MessageResolver.java index 4f741a43..9656455b 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/MessageResolver.java +++ b/src/main/java/org/springframework/hateoas/mediatype/MessageResolver.java @@ -15,10 +15,9 @@ */ package org.springframework.hateoas.mediatype; +import org.jspecify.annotations.Nullable; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceResolvable; -import org.springframework.context.support.MessageSourceAccessor; -import org.springframework.lang.Nullable; /** * A simplified variant of {@link MessageSourceAccessor} to allow more direct replacement with a no-op implementation in diff --git a/src/main/java/org/springframework/hateoas/mediatype/MessageSourceResolver.java b/src/main/java/org/springframework/hateoas/mediatype/MessageSourceResolver.java index 05103e00..0311e52d 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/MessageSourceResolver.java +++ b/src/main/java/org/springframework/hateoas/mediatype/MessageSourceResolver.java @@ -15,10 +15,10 @@ */ package org.springframework.hateoas.mediatype; +import org.jspecify.annotations.Nullable; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceResolvable; import org.springframework.context.support.MessageSourceAccessor; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java b/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java index a6529923..d47cee19 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java +++ b/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java @@ -36,6 +36,7 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanWrapper; @@ -51,7 +52,6 @@ import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.InputType; import org.springframework.http.HttpEntity; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ConcurrentReferenceHashMap; @@ -703,14 +703,14 @@ public class PropertyUtils { .map(BigDecimal::new); } - private String cacheAndReturn(String value) { + private @Nullable String cacheAndReturn(@Nullable String value) { this.inputType = Optional.ofNullable(value); return value; } - private String lookupFromTypeMap() { + private @Nullable String lookupFromTypeMap() { return TYPE_MAP.entrySet().stream() // .flatMap(it -> { diff --git a/src/main/java/org/springframework/hateoas/mediatype/TypeBasedPayloadMetadata.java b/src/main/java/org/springframework/hateoas/mediatype/TypeBasedPayloadMetadata.java index 66a6e1f7..0009af75 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/TypeBasedPayloadMetadata.java +++ b/src/main/java/org/springframework/hateoas/mediatype/TypeBasedPayloadMetadata.java @@ -24,11 +24,11 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.NonNull; import org.springframework.hateoas.AffordanceModel.InputPayloadMetadata; import org.springframework.hateoas.AffordanceModel.Named; import org.springframework.hateoas.AffordanceModel.PropertyMetadata; import org.springframework.http.MediaType; -import org.springframework.lang.NonNull; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/hateoas/mediatype/alps/Alps.java b/src/main/java/org/springframework/hateoas/mediatype/alps/Alps.java index a7bd3357..2bf85dbc 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/alps/Alps.java +++ b/src/main/java/org/springframework/hateoas/mediatype/alps/Alps.java @@ -18,6 +18,9 @@ package org.springframework.hateoas.mediatype.alps; import java.util.List; import java.util.Objects; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import org.springframework.hateoas.mediatype.alps.Descriptor.DescriptorBuilder; import org.springframework.hateoas.mediatype.alps.Doc.DocBuilder; import org.springframework.hateoas.mediatype.alps.Ext.ExtBuilder; @@ -29,7 +32,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; /** * An ALPS document. - * + * * @author Oliver Gierke * @author Greg Turnquist * @since 0.15 @@ -38,6 +41,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; */ @JsonPropertyOrder({ "version", "doc", "descriptor" }) @JsonInclude(JsonInclude.Include.NON_NULL) +@NullUnmarked public final class Alps { private final String version; @@ -58,13 +62,13 @@ public final class Alps { * * @return */ - public static AlpsBuilder alps() { + public static @NullMarked AlpsBuilder alps() { return new AlpsBuilder(); } /** * Returns a new {@link DescriptorBuilder}. - * + * * @return */ public static DescriptorBuilder descriptor() { @@ -73,7 +77,7 @@ public final class Alps { /** * Returns a new {@link DocBuilder}. - * + * * @return */ public static DocBuilder doc() { @@ -82,7 +86,7 @@ public final class Alps { /** * Returns a new {@link ExtBuilder}. - * + * * @return */ public static ExtBuilder ext() { @@ -104,13 +108,17 @@ public final class Alps { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + + if (!(o instanceof Alps that)) { return false; - Alps alps = (Alps) o; - return Objects.equals(this.version, alps.version) && Objects.equals(this.doc, alps.doc) - && Objects.equals(this.descriptor, alps.descriptor); + } + + return Objects.equals(this.version, that.version) + && Objects.equals(this.doc, that.doc) + && Objects.equals(this.descriptor, that.descriptor); } @Override @@ -118,6 +126,7 @@ public final class Alps { return Objects.hash(this.version, this.doc, this.descriptor); } + @Override public String toString() { return "Alps(version=" + this.version + ", doc=" + this.doc + ", descriptor=" + this.descriptor + ")"; } @@ -130,28 +139,29 @@ public final class Alps { AlpsBuilder() {} - public Alps.AlpsBuilder version(String version) { + public Alps.AlpsBuilder version(@NonNull String version) { this.version = version; return this; } - public Alps.AlpsBuilder doc(Doc doc) { + public Alps.AlpsBuilder doc(@NonNull Doc doc) { this.doc = doc; return this; } - public Alps.AlpsBuilder descriptor(List descriptor) { + public Alps.AlpsBuilder descriptor(@NonNull List descriptor) { this.descriptor = descriptor; return this; } - public Alps build() { + public @NonNull Alps build() { return new Alps(this.version, this.doc, this.descriptor); } + @Override public String toString() { return "Alps.AlpsBuilder(version=" + this.version + ", doc=" + this.doc + ", descriptor=" + this.descriptor + ")"; } diff --git a/src/main/java/org/springframework/hateoas/mediatype/alps/AlpsLinkDiscoverer.java b/src/main/java/org/springframework/hateoas/mediatype/alps/AlpsLinkDiscoverer.java index 576f86e0..1582d49e 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/alps/AlpsLinkDiscoverer.java +++ b/src/main/java/org/springframework/hateoas/mediatype/alps/AlpsLinkDiscoverer.java @@ -17,7 +17,6 @@ package org.springframework.hateoas.mediatype.alps; import org.springframework.hateoas.MediaTypes; import org.springframework.hateoas.client.JsonPathLinkDiscoverer; -import org.springframework.hateoas.client.LinkDiscoverer; /** * {@link LinkDiscoverer} implementation to find ALPS-based links. diff --git a/src/main/java/org/springframework/hateoas/mediatype/alps/Descriptor.java b/src/main/java/org/springframework/hateoas/mediatype/alps/Descriptor.java index f984d367..4205bb6e 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/alps/Descriptor.java +++ b/src/main/java/org/springframework/hateoas/mediatype/alps/Descriptor.java @@ -18,6 +18,10 @@ package org.springframework.hateoas.mediatype.alps; import java.util.List; import java.util.Objects; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; + import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -25,7 +29,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; /** * A value object for an ALPS descriptor. - * + * * @author Oliver Gierke * @author Greg Turnquist * @since 0.15 @@ -33,6 +37,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; */ @JsonPropertyOrder({ "id", "href", "name", "type", "doc", "descriptor", "ext" }) @JsonInclude(JsonInclude.Include.NON_NULL) +@NullUnmarked public final class Descriptor { private final String id; @@ -60,49 +65,51 @@ public final class Descriptor { this.descriptor = descriptor; } - public static DescriptorBuilder builder() { + public static @NonNull DescriptorBuilder builder() { return new DescriptorBuilder(); } - public String getId() { + public @Nullable String getId() { return this.id; } - public String getHref() { + public @Nullable String getHref() { return this.href; } - public String getName() { + public @Nullable String getName() { return this.name; } - public Doc getDoc() { + public @Nullable Doc getDoc() { return this.doc; } - public Type getType() { + public @Nullable Type getType() { return this.type; } - public Ext getExt() { + public @Nullable Ext getExt() { return this.ext; } - public String getRt() { + public @Nullable String getRt() { return this.rt; } - public List getDescriptor() { + public @Nullable List getDescriptor() { return this.descriptor; } @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + if (o == null || getClass() != o.getClass()) { return false; + } Descriptor that = (Descriptor) o; return Objects.equals(this.id, that.id) && Objects.equals(this.href, that.href) && Objects.equals(this.name, that.name) && Objects.equals(this.doc, that.doc) && this.type == that.type @@ -115,6 +122,7 @@ public final class Descriptor { return Objects.hash(this.id, this.href, this.name, this.doc, this.type, this.ext, this.rt, this.descriptor); } + @Override public String toString() { return "Descriptor(id=" + this.id + ", href=" + this.href + ", name=" + this.name + ", doc=" + this.doc + ", type=" @@ -134,49 +142,49 @@ public final class Descriptor { DescriptorBuilder() {} - public Descriptor.DescriptorBuilder id(String id) { + public Descriptor.DescriptorBuilder id(@Nullable String id) { this.id = id; return this; } - public Descriptor.DescriptorBuilder href(String href) { + public Descriptor.DescriptorBuilder href(@Nullable String href) { this.href = href; return this; } - public Descriptor.DescriptorBuilder name(String name) { + public Descriptor.DescriptorBuilder name(@Nullable String name) { this.name = name; return this; } - public Descriptor.DescriptorBuilder doc(Doc doc) { + public Descriptor.DescriptorBuilder doc(@Nullable Doc doc) { this.doc = doc; return this; } - public Descriptor.DescriptorBuilder type(Type type) { + public Descriptor.DescriptorBuilder type(@Nullable Type type) { this.type = type; return this; } - public Descriptor.DescriptorBuilder ext(Ext ext) { + public Descriptor.DescriptorBuilder ext(@Nullable Ext ext) { this.ext = ext; return this; } - public Descriptor.DescriptorBuilder rt(String rt) { + public Descriptor.DescriptorBuilder rt(@Nullable String rt) { this.rt = rt; return this; } - public Descriptor.DescriptorBuilder descriptor(List descriptor) { + public Descriptor.DescriptorBuilder descriptor(@Nullable List descriptor) { this.descriptor = descriptor; return this; @@ -186,6 +194,7 @@ public final class Descriptor { return new Descriptor(this.id, this.href, this.name, this.doc, this.type, this.ext, this.rt, this.descriptor); } + @Override public String toString() { return "Descriptor.DescriptorBuilder(id=" + this.id + ", href=" + this.href + ", name=" + this.name + ", doc=" diff --git a/src/main/java/org/springframework/hateoas/mediatype/alps/Doc.java b/src/main/java/org/springframework/hateoas/mediatype/alps/Doc.java index 408da4eb..e262b3da 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/alps/Doc.java +++ b/src/main/java/org/springframework/hateoas/mediatype/alps/Doc.java @@ -17,6 +17,8 @@ package org.springframework.hateoas.mediatype.alps; import java.util.Objects; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonCreator; @@ -26,7 +28,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; /** * A value object for an ALPS doc element. - * + * * @author Oliver Gierke * @author Greg Turnquist * @since 0.15 @@ -34,6 +36,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; */ @JsonPropertyOrder({ "format", "href", "value" }) @JsonInclude(JsonInclude.Include.NON_NULL) +@NullUnmarked public final class Doc { private final String href; @@ -42,11 +45,11 @@ public final class Doc { /** * Creates a new {@link Doc} instance with the given value and {@link Format}. - * + * * @param value must not be {@literal null} or empty. * @param format must not be {@literal null}. */ - public Doc(String value, Format format) { + public Doc(@NonNull String value, @NonNull Format format) { Assert.hasText(value, "Value must not be null or empty!"); Assert.notNull(format, "Format must not be null!"); @@ -82,14 +85,17 @@ public final class Doc { } @Override - public boolean equals(Object o) { + public boolean equals(Object obj) { - if (this == o) + if (this == obj) { return true; - if (o == null || getClass() != o.getClass()) + } + + if (!(obj instanceof Doc that)) { return false; - Doc doc = (Doc) o; - return Objects.equals(this.href, doc.href) && Objects.equals(this.value, doc.value) && this.format == doc.format; + } + + return Objects.equals(this.href, that.href) && Objects.equals(this.value, that.value) && this.format == that.format; } @Override @@ -97,6 +103,7 @@ public final class Doc { return Objects.hash(this.href, this.value, this.format); } + @Override public String toString() { return "Doc(href=" + this.href + ", value=" + this.value + ", format=" + this.format + ")"; } @@ -109,19 +116,19 @@ public final class Doc { DocBuilder() {} - public Doc.DocBuilder href(String href) { + public Doc.DocBuilder href(@NonNull String href) { this.href = href; return this; } - public Doc.DocBuilder value(String value) { + public Doc.DocBuilder value(@NonNull String value) { this.value = value; return this; } - public Doc.DocBuilder format(Format format) { + public Doc.DocBuilder format(@NonNull Format format) { this.format = format; return this; @@ -131,6 +138,7 @@ public final class Doc { return new Doc(this.href, this.value, this.format); } + @Override public String toString() { return "Doc.DocBuilder(href=" + this.href + ", value=" + this.value + ", format=" + this.format + ")"; } diff --git a/src/main/java/org/springframework/hateoas/mediatype/alps/Ext.java b/src/main/java/org/springframework/hateoas/mediatype/alps/Ext.java index 78092f39..4b971025 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/alps/Ext.java +++ b/src/main/java/org/springframework/hateoas/mediatype/alps/Ext.java @@ -17,19 +17,23 @@ package org.springframework.hateoas.mediatype.alps; import java.util.Objects; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; + import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; /** * A value object for an ALPS ext element. - * + * * @author Oliver Gierke * @author Greg Turnquist * @since 0.15 * @see http://alps.io/spec/#prop-ext */ @JsonPropertyOrder({ "id", "href", "value" }) +@NullUnmarked public final class Ext { private final String id; @@ -44,7 +48,7 @@ public final class Ext { this.value = value; } - public static ExtBuilder builder() { + public static @NonNull ExtBuilder builder() { return new ExtBuilder(); } @@ -63,10 +67,12 @@ public final class Ext { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + if (o == null || getClass() != o.getClass()) { return false; + } Ext ext = (Ext) o; return Objects.equals(this.id, ext.id) && Objects.equals(this.href, ext.href) && Objects.equals(this.value, ext.value); @@ -77,6 +83,7 @@ public final class Ext { return Objects.hash(this.id, this.href, this.value); } + @Override public String toString() { return "Ext(id=" + this.id + ", href=" + this.href + ", value=" + this.value + ")"; } @@ -89,19 +96,19 @@ public final class Ext { ExtBuilder() {} - public Ext.ExtBuilder id(String id) { + public Ext.ExtBuilder id(@NonNull String id) { this.id = id; return this; } - public Ext.ExtBuilder href(String href) { + public Ext.ExtBuilder href(@NonNull String href) { this.href = href; return this; } - public Ext.ExtBuilder value(String value) { + public Ext.ExtBuilder value(@NonNull String value) { this.value = value; return this; @@ -111,6 +118,7 @@ public final class Ext { return new Ext(this.id, this.href, this.value); } + @Override public String toString() { return "Ext.ExtBuilder(id=" + this.id + ", href=" + this.href + ", value=" + this.value + ")"; } diff --git a/src/main/java/org/springframework/hateoas/mediatype/alps/package-info.java b/src/main/java/org/springframework/hateoas/mediatype/alps/package-info.java index 8b93b04d..a251dd44 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/alps/package-info.java +++ b/src/main/java/org/springframework/hateoas/mediatype/alps/package-info.java @@ -3,5 +3,5 @@ * * @see https://alps.io */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.mediatype.alps; diff --git a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJson.java b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJson.java index afc5e7a6..229dd610 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJson.java +++ b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJson.java @@ -20,10 +20,10 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.Link; import org.springframework.hateoas.Links; import org.springframework.hateoas.Links.MergeMode; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonAffordanceModel.java b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonAffordanceModel.java index b7250eaf..bd33e8c1 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonAffordanceModel.java +++ b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonAffordanceModel.java @@ -21,12 +21,10 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import org.springframework.hateoas.Affordance; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.AffordanceModel; -import org.springframework.hateoas.QueryParameter; import org.springframework.hateoas.mediatype.ConfiguredAffordance; import org.springframework.http.HttpMethod; -import org.springframework.lang.Nullable; /** * {@link AffordanceModel} for Collection+JSON. diff --git a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonData.java b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonData.java index 9c494304..6ed675aa 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonData.java +++ b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonData.java @@ -17,7 +17,7 @@ package org.springframework.hateoas.mediatype.collectionjson; import java.util.Objects; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonError.java b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonError.java index 17d1202e..400ca02e 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonError.java +++ b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonError.java @@ -17,7 +17,8 @@ package org.springframework.hateoas.mediatype.collectionjson; import java.util.Objects; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -25,6 +26,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** * @author Greg Turnquist */ +@NullUnmarked final class CollectionJsonError { private final String title; @@ -89,10 +91,12 @@ final class CollectionJsonError { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + if (o == null || getClass() != o.getClass()) { return false; + } CollectionJsonError that = (CollectionJsonError) o; return Objects.equals(this.title, that.title) && Objects.equals(this.code, that.code) && Objects.equals(this.message, that.message); @@ -103,6 +107,7 @@ final class CollectionJsonError { return Objects.hash(this.title, this.code, this.message); } + @Override public String toString() { return "CollectionJsonError(title=" + this.title + ", code=" + this.code + ", message=" + this.message + ")"; } diff --git a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonItem.java b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonItem.java index 38d6152c..35e46bd6 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonItem.java +++ b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonItem.java @@ -21,11 +21,12 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.Link; import org.springframework.hateoas.Links; import org.springframework.hateoas.Links.MergeMode; import org.springframework.hateoas.mediatype.PropertyUtils; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -39,6 +40,7 @@ import com.fasterxml.jackson.databind.JavaType; * * @author Greg Turnquist */ +@NullUnmarked final class CollectionJsonItem { private @Nullable final String href; @@ -86,7 +88,7 @@ final class CollectionJsonItem { /** * Create new {@link CollectionJsonItem} by copying attributes and replacing the {@link Links}. - * + * * @param links * @return */ @@ -97,7 +99,7 @@ final class CollectionJsonItem { /** * Create new {@link CollectionJsonItem} by copying attributes and replacing the {@literal links} with a * {@literal self} link. - * + * * @return */ CollectionJsonItem withOwnSelfLink() { @@ -210,10 +212,12 @@ final class CollectionJsonItem { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + if (o == null || getClass() != o.getClass()) { return false; + } CollectionJsonItem that = (CollectionJsonItem) o; return Objects.equals(this.href, that.href) && Objects.equals(this.data, that.data) && Objects.equals(this.links, that.links) && Objects.equals(this.rawData, that.rawData); @@ -224,6 +228,7 @@ final class CollectionJsonItem { return Objects.hash(this.href, this.data, this.links, this.rawData); } + @Override public String toString() { return "CollectionJsonItem(href=" + this.href + ", data=" + this.data + ", links=" + this.links + ", rawData=" diff --git a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonLinkDiscoverer.java b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonLinkDiscoverer.java index bc4da1a0..d28a4f95 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonLinkDiscoverer.java +++ b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonLinkDiscoverer.java @@ -24,7 +24,6 @@ import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.Links; import org.springframework.hateoas.MediaTypes; import org.springframework.hateoas.client.JsonPathLinkDiscoverer; -import org.springframework.hateoas.client.LinkDiscoverer; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonMediaTypeConfiguration.java b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonMediaTypeConfiguration.java index 9e7eb2a0..d3019a34 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonMediaTypeConfiguration.java +++ b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonMediaTypeConfiguration.java @@ -17,13 +17,13 @@ package org.springframework.hateoas.mediatype.collectionjson; import java.util.List; +import org.jspecify.annotations.NonNull; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.hateoas.client.LinkDiscoverer; import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType; import org.springframework.hateoas.config.HypermediaMappingInformation; import org.springframework.http.MediaType; -import org.springframework.lang.NonNull; import com.fasterxml.jackson.databind.Module; diff --git a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonQuery.java b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonQuery.java index 6584326a..4c62c9b6 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonQuery.java +++ b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonQuery.java @@ -18,7 +18,8 @@ package org.springframework.hateoas.mediatype.collectionjson; import java.util.List; import java.util.Objects; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; @@ -28,6 +29,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** * @author Greg Turnquist */ +@NullUnmarked final class CollectionJsonQuery { private @JsonInclude(Include.NON_NULL) final String rel; @@ -108,10 +110,12 @@ final class CollectionJsonQuery { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + if (o == null || getClass() != o.getClass()) { return false; + } CollectionJsonQuery that = (CollectionJsonQuery) o; return Objects.equals(this.rel, that.rel) && Objects.equals(this.href, that.href) && Objects.equals(this.prompt, that.prompt) && Objects.equals(this.data, that.data); @@ -122,6 +126,7 @@ final class CollectionJsonQuery { return Objects.hash(this.rel, this.href, this.prompt, this.data); } + @Override public String toString() { return "CollectionJsonQuery(rel=" + this.rel + ", href=" + this.href + ", prompt=" + this.prompt + ", data=" diff --git a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonTemplate.java b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonTemplate.java index 677f707c..72113143 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonTemplate.java +++ b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonTemplate.java @@ -18,7 +18,8 @@ package org.springframework.hateoas.mediatype.collectionjson; import java.util.List; import java.util.Objects; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -26,6 +27,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** * @author Greg Turnquist */ +@NullUnmarked final class CollectionJsonTemplate { private final List data; @@ -48,13 +50,15 @@ final class CollectionJsonTemplate { } @Override - public boolean equals(Object o) { + public boolean equals(Object obj) { - if (this == o) + if (this == obj) { return true; - if (o == null || getClass() != o.getClass()) + } + if (obj == null || getClass() != obj.getClass()) { return false; - CollectionJsonTemplate that = (CollectionJsonTemplate) o; + } + CollectionJsonTemplate that = (CollectionJsonTemplate) obj; return Objects.equals(this.data, that.data); } @@ -63,6 +67,7 @@ final class CollectionJsonTemplate { return Objects.hash(this.data); } + @Override public String toString() { return "CollectionJsonTemplate(data=" + this.data + ")"; } diff --git a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/Jackson2CollectionJsonModule.java b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/Jackson2CollectionJsonModule.java index ef84a00c..40b517a5 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/Jackson2CollectionJsonModule.java +++ b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/Jackson2CollectionJsonModule.java @@ -23,7 +23,7 @@ import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; -import org.springframework.hateoas.Affordance; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.IanaLinkRelations; @@ -36,7 +36,6 @@ import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.mediatype.JacksonHelper; import org.springframework.hateoas.mediatype.PropertyUtils; import org.springframework.http.HttpMethod; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.core.JsonGenerator; @@ -170,7 +169,7 @@ public class Jackson2CollectionJsonModule extends SimpleModule { private static final long serialVersionUID = 6127711241993352699L; - private final BeanProperty property; + private final @Nullable BeanProperty property; CollectionJsonResourceSupportSerializer() { this(null); @@ -272,7 +271,7 @@ public class Jackson2CollectionJsonModule extends SimpleModule { private static final long serialVersionUID = 2212535956767860364L; - private final BeanProperty property; + private final @Nullable BeanProperty property; CollectionJsonResourceSerializer() { this(null); @@ -453,7 +452,7 @@ public class Jackson2CollectionJsonModule extends SimpleModule { private static final long serialVersionUID = -6703190072925382402L; - private final BeanProperty property; + private final @Nullable BeanProperty property; CollectionJsonPagedResourcesSerializer() { this(null); diff --git a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/package-info.java b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/package-info.java index aaa9e792..72808d6f 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/collectionjson/package-info.java +++ b/src/main/java/org/springframework/hateoas/mediatype/collectionjson/package-info.java @@ -1,5 +1,5 @@ /** * Value objects to build Collection+JSON representations. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.mediatype.collectionjson; diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/DefaultCurieProvider.java b/src/main/java/org/springframework/hateoas/mediatype/hal/DefaultCurieProvider.java index d86ac48b..5d8cffbb 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/DefaultCurieProvider.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/DefaultCurieProvider.java @@ -20,12 +20,12 @@ import java.util.Collections; import java.util.Map; import java.util.stream.Collectors; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.Links; import org.springframework.hateoas.UriTemplate; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @@ -41,7 +41,7 @@ import org.springframework.web.servlet.support.ServletUriComponentsBuilder; public class DefaultCurieProvider implements CurieProvider { private final Map curies; - private final String defaultCurie; + private final @Nullable String defaultCurie; /** * Creates a new {@link DefaultCurieProvider} for the given name and {@link UriTemplate}. The curie will be used to diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/HalEmbeddedBuilder.java b/src/main/java/org/springframework/hateoas/mediatype/hal/HalEmbeddedBuilder.java index 6dce6fe2..118f8478 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/HalEmbeddedBuilder.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/HalEmbeddedBuilder.java @@ -23,12 +23,11 @@ import java.util.List; import java.util.Map; import java.util.function.Function; -import org.springframework.hateoas.EntityModel; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.server.LinkRelationProvider; import org.springframework.hateoas.server.core.EmbeddedWrapper; import org.springframework.hateoas.server.core.EmbeddedWrappers; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -88,6 +87,10 @@ class HalEmbeddedBuilder { */ void add(@Nullable Object source) { + if (source == null) { + return; + } + EmbeddedWrapper wrapper = wrappers.wrap(source); if (wrapper == null) { @@ -160,7 +163,7 @@ class HalEmbeddedBuilder { /** * Create new {@link HalEmbeddedBuilder} by copying attributes and replacing the {@literal relationTransformer}. - * + * * @param relationTransformer * @return */ diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/HalLinkDiscoverer.java b/src/main/java/org/springframework/hateoas/mediatype/hal/HalLinkDiscoverer.java index d7d21516..b2dea8e6 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/HalLinkDiscoverer.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/HalLinkDiscoverer.java @@ -22,6 +22,7 @@ import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.MediaTypes; import org.springframework.hateoas.client.JsonPathLinkDiscoverer; import org.springframework.http.MediaType; +import org.springframework.util.Assert; /** * {@link org.springframework.hateoas.client.LinkDiscoverer} implementation based on HAL link structure. @@ -54,9 +55,12 @@ public class HalLinkDiscoverer extends JsonPathLinkDiscoverer { return super.extractLink(element, rel); } - Map json = (Map) element; + var json = (Map) element; + var href = json.get("href"); - return Link.of(json.get("href"), rel) // + Assert.state(href != null, "No href found in link data!"); + + return Link.of(href, rel) // .withHreflang(json.get("hreflang")) // .withMedia(json.get("media")) // .withTitle(json.get("title")) // diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/HalLinkRelation.java b/src/main/java/org/springframework/hateoas/mediatype/hal/HalLinkRelation.java index cc20e5d6..65b6a630 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/HalLinkRelation.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/HalLinkRelation.java @@ -19,11 +19,12 @@ import java.util.Objects; import java.util.function.Function; import java.util.stream.Stream; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.context.MessageSourceResolvable; import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.IanaUriSchemes; import org.springframework.hateoas.LinkRelation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonCreator; @@ -184,8 +185,7 @@ public class HalLinkRelation implements LinkRelation, MessageSourceResolvable { * @see org.springframework.context.MessageSourceResolvable#getCodes() */ @Override - @org.springframework.lang.NonNull - public String[] getCodes() { + public String @NonNull[] getCodes() { return Stream.of(value(), localPart) // .map(it -> String.format(RELATION_MESSAGE_TEMPLATE, it)) // @@ -197,7 +197,7 @@ public class HalLinkRelation implements LinkRelation, MessageSourceResolvable { * @see org.springframework.context.MessageSourceResolvable#getDefaultMessage() */ @Override - @org.springframework.lang.NonNull + @NonNull public String getDefaultMessage() { return ""; } diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/HalModelBuilder.java b/src/main/java/org/springframework/hateoas/mediatype/hal/HalModelBuilder.java index f9789d5e..3481937b 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/HalModelBuilder.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/HalModelBuilder.java @@ -21,15 +21,14 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.Links; -import org.springframework.hateoas.MediaTypes; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.server.core.EmbeddedWrappers; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonUnwrapped; @@ -47,7 +46,7 @@ public class HalModelBuilder { private final EmbeddedWrappers wrappers; - private Object model; + private @Nullable Object model; private Links links = Links.NONE; private final List embeddeds = new ArrayList<>(); @@ -358,7 +357,10 @@ public class HalModelBuilder { */ @SuppressWarnings("unchecked") public > RepresentationModel build() { - return (T) new HalRepresentationModel<>(model, embeddeds, links); + + return model == null + ? (T) new EmbedsOnlyHalRepresentationModel(embeddeds, links) + : (T) new HalRepresentationModel<>(model, embeddeds, links); } /** @@ -377,19 +379,28 @@ public class HalModelBuilder { return this; } + private static class EmbedsOnlyHalRepresentationModel extends CollectionModel { + + public EmbedsOnlyHalRepresentationModel(List embeddeds, Links links) { + + super(embeddeds); + add(links); + } + } + private static class HalRepresentationModel extends EntityModel { - private final @Nullable T entity; + private final T entity; private final List embeddeds; - public HalRepresentationModel(@Nullable T entity, List embeddeds, Links links) { + public HalRepresentationModel(T entity, List embeddeds, Links links) { this(entity, embeddeds); add(links); } - private HalRepresentationModel(@Nullable T entity, List embeddeds) { + private HalRepresentationModel(T entity, List embeddeds) { Assert.notNull(embeddeds, "Embedds must not be null!"); @@ -401,7 +412,6 @@ public class HalModelBuilder { * (non-Javadoc) * @see org.springframework.hateoas.EntityModel#getContent() */ - @Nullable @Override public T getContent() { return entity; diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/Jackson2HalModule.java b/src/main/java/org/springframework/hateoas/mediatype/hal/Jackson2HalModule.java index fc7d5840..3dd28e31 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/Jackson2HalModule.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/Jackson2HalModule.java @@ -26,10 +26,10 @@ import java.util.List; import java.util.Map; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.hateoas.CollectionModel; -import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.Links; @@ -39,7 +39,6 @@ import org.springframework.hateoas.mediatype.MessageResolver; import org.springframework.hateoas.mediatype.MessageSourceResolvableSerializer; import org.springframework.hateoas.mediatype.hal.HalConfiguration.RenderSingleLinks; import org.springframework.hateoas.server.LinkRelationProvider; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -293,7 +292,7 @@ public class Jackson2HalModule extends SimpleModule { private final EmbeddedMapper embeddedMapper; private final HalConfiguration configuration; - private final BeanProperty property; + private final @Nullable BeanProperty property; public HalResourcesSerializer(EmbeddedMapper embeddedMapper, HalConfiguration configuration) { this(embeddedMapper, configuration, null); @@ -617,7 +616,7 @@ public class Jackson2HalModule extends SimpleModule { private static final long serialVersionUID = 4755806754621032622L; - private JavaType contentType; + private @Nullable JavaType contentType; public HalResourcesDeserializer() { this(TypeFactory.defaultInstance().constructCollectionLikeType(List.class, Object.class), null); @@ -905,7 +904,7 @@ public class Jackson2HalModule extends SimpleModule { static class HalLink { private final Link link; - private final String title; + private final @Nullable String title; public HalLink(Link link, @Nullable String title) { diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/RepresentationModelMixin.java b/src/main/java/org/springframework/hateoas/mediatype/hal/RepresentationModelMixin.java index 2af7fe13..fa713816 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/RepresentationModelMixin.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/RepresentationModelMixin.java @@ -15,7 +15,6 @@ */ package org.springframework.hateoas.mediatype.hal; -import org.springframework.hateoas.Link; import org.springframework.hateoas.Links; import org.springframework.hateoas.RepresentationModel; diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsAffordanceModel.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsAffordanceModel.java index d5ada3b1..d7fd72ff 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsAffordanceModel.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsAffordanceModel.java @@ -17,7 +17,6 @@ package org.springframework.hateoas.mediatype.hal.forms; import org.springframework.hateoas.AffordanceModel; import org.springframework.hateoas.mediatype.ConfiguredAffordance; -import org.springframework.http.MediaType; /** * {@link AffordanceModel} for a HAL-FORMS {@link MediaType}. diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsConfiguration.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsConfiguration.java index 3c863ae4..778d051e 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsConfiguration.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsConfiguration.java @@ -24,13 +24,13 @@ import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.springframework.core.ResolvableType; import org.springframework.hateoas.AffordanceModel.PropertyMetadata; import org.springframework.hateoas.MediaTypes; import org.springframework.hateoas.mediatype.hal.HalConfiguration; import org.springframework.http.MediaType; import org.springframework.lang.Contract; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsDeserializers.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsDeserializers.java index 6da302a3..99615d14 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsDeserializers.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsDeserializers.java @@ -19,8 +19,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsHttpMessageConverter.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsHttpMessageConverter.java index 43af6759..7e5ac619 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsHttpMessageConverter.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsHttpMessageConverter.java @@ -19,13 +19,13 @@ import java.io.IOException; import java.lang.reflect.Type; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.BeanFactory; import org.springframework.hateoas.MediaTypes; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2HttpMessageConverter; import org.springframework.http.HttpOutputMessage; import org.springframework.http.converter.HttpMessageNotWritableException; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsLinkDiscoverer.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsLinkDiscoverer.java index b7de9c29..d626b53a 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsLinkDiscoverer.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsLinkDiscoverer.java @@ -16,7 +16,6 @@ package org.springframework.hateoas.mediatype.hal.forms; import org.springframework.hateoas.MediaTypes; -import org.springframework.hateoas.client.JsonPathLinkDiscoverer; import org.springframework.hateoas.mediatype.hal.HalLinkDiscoverer; /** diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptions.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptions.java index 50058fb7..941d7093 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptions.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptions.java @@ -18,8 +18,8 @@ package org.springframework.hateoas.mediatype.hal.forms; import java.util.Arrays; import java.util.Collection; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.Link; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptionsFactory.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptionsFactory.java index 09597144..d208d3ed 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptionsFactory.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptionsFactory.java @@ -19,9 +19,9 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.AffordanceModel.PayloadMetadata; import org.springframework.hateoas.AffordanceModel.PropertyMetadata; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsProperty.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsProperty.java index faf19676..aebb668a 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsProperty.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsProperty.java @@ -18,8 +18,9 @@ package org.springframework.hateoas.mediatype.hal.forms; import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.AffordanceModel.Named; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -35,6 +36,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; * @see https://mamund.site44.com/misc/hal-forms/ */ @JsonInclude(Include.NON_DEFAULT) +@NullUnmarked final class HalFormsProperty implements Named { private final String name, prompt, regex, placeholder; diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsPropertyFactory.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsPropertyFactory.java index 210f0602..661b7db3 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsPropertyFactory.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsPropertyFactory.java @@ -24,13 +24,13 @@ import java.util.Optional; import java.util.Set; import java.util.function.Function; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.context.MessageSourceResolvable; import org.springframework.hateoas.AffordanceModel.InputPayloadMetadata; import org.springframework.hateoas.AffordanceModel.PropertyMetadata; import org.springframework.hateoas.mediatype.MessageResolver; import org.springframework.http.HttpMethod; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -157,13 +157,13 @@ class HalFormsPropertyFactory { return ""; } + /* * (non-Javadoc) * @see org.springframework.context.MessageSourceResolvable#getCodes() */ - @NonNull @Override - public String[] getCodes() { + public String @NonNull[] getCodes() { String globalCode = String.format(template, property.getName()); diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplate.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplate.java index 5510899b..1efd92c9 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplate.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplate.java @@ -21,9 +21,10 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonAutoDetect; @@ -43,6 +44,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; @JsonAutoDetect(getterVisibility = Visibility.NON_PRIVATE) @JsonIgnoreProperties({ "httpMethod", "contentTypes" }) @JsonPropertyOrder({ "title", "method", "contentType", "properties" }) +@NullUnmarked final class HalFormsTemplate { static final String DEFAULT_KEY = "default"; diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplateBuilder.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplateBuilder.java index 7db06bbd..c0295935 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplateBuilder.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplateBuilder.java @@ -20,6 +20,8 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Stream; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.context.MessageSourceResolvable; import org.springframework.hateoas.AffordanceModel.InputPayloadMetadata; import org.springframework.hateoas.IanaLinkRelations; @@ -28,8 +30,6 @@ import org.springframework.hateoas.MediaTypes; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.mediatype.MessageResolver; import org.springframework.http.HttpMethod; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -112,13 +112,13 @@ class HalFormsTemplateBuilder { return new TemplateTitle(affordance, soleTemplate); } + /* * (non-Javadoc) * @see org.springframework.context.MessageSourceResolvable#getCodes() */ - @NonNull @Override - public String[] getCodes() { + public String @NonNull[] getCodes() { Stream seed = Stream.concat(// Stream.of(affordance.getName()), // diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/package-info.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/package-info.java index d2add7fb..56544ca4 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/package-info.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/package-info.java @@ -1,7 +1,5 @@ /** * HAL-FORMS extension media type. */ -@NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.mediatype.hal.forms; - -import org.springframework.lang.NonNullApi; diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/package-info.java b/src/main/java/org/springframework/hateoas/mediatype/hal/package-info.java index d06af2a8..9b3a517f 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/package-info.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/package-info.java @@ -3,5 +3,5 @@ * * @see http://stateless.co/hal_specification.html */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.mediatype.hal; diff --git a/src/main/java/org/springframework/hateoas/mediatype/html/HtmlInputType.java b/src/main/java/org/springframework/hateoas/mediatype/html/HtmlInputType.java index 6bf2237a..8d491587 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/html/HtmlInputType.java +++ b/src/main/java/org/springframework/hateoas/mediatype/html/HtmlInputType.java @@ -24,10 +24,9 @@ import java.time.LocalTime; import java.util.Arrays; import java.util.Collection; +import org.jspecify.annotations.Nullable; import org.springframework.core.Constants; import org.springframework.core.Constants.ConstantException; -import org.springframework.core.ResolvableType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/src/main/java/org/springframework/hateoas/mediatype/html/HtmlInputTypeFactory.java b/src/main/java/org/springframework/hateoas/mediatype/html/HtmlInputTypeFactory.java index 2b9c859b..c2f0d307 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/html/HtmlInputTypeFactory.java +++ b/src/main/java/org/springframework/hateoas/mediatype/html/HtmlInputTypeFactory.java @@ -15,8 +15,8 @@ */ package org.springframework.hateoas.mediatype.html; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.mediatype.InputTypeFactory; -import org.springframework.lang.Nullable; /** * An {@link InputTypeFactory} based on {@link HtmlInputType}. diff --git a/src/main/java/org/springframework/hateoas/mediatype/html/package-info.java b/src/main/java/org/springframework/hateoas/mediatype/html/package-info.java index d3d8e9c4..295f3da4 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/html/package-info.java +++ b/src/main/java/org/springframework/hateoas/mediatype/html/package-info.java @@ -1,5 +1,5 @@ /** * Support for HTML media type. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.mediatype.html; diff --git a/src/main/java/org/springframework/hateoas/mediatype/package-info.java b/src/main/java/org/springframework/hateoas/mediatype/package-info.java index b40850e9..e046688a 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/package-info.java +++ b/src/main/java/org/springframework/hateoas/mediatype/package-info.java @@ -1,5 +1,5 @@ /** - * Spring container configuration support. + * General media type support. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.mediatype; diff --git a/src/main/java/org/springframework/hateoas/mediatype/problem/Problem.java b/src/main/java/org/springframework/hateoas/mediatype/problem/Problem.java index 3ebffa2f..53ea51cb 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/problem/Problem.java +++ b/src/main/java/org/springframework/hateoas/mediatype/problem/Problem.java @@ -22,8 +22,9 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.http.HttpStatus; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.annotation.JsonAnyGetter; @@ -43,6 +44,7 @@ import com.fasterxml.jackson.annotation.JsonUnwrapped; * @author Oliver Drotbohm */ @JsonInclude(Include.NON_NULL) +@NullUnmarked public class Problem { private static Problem EMPTY = new Problem(); @@ -242,10 +244,12 @@ public class Problem { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof Problem)) + } + if (!(o instanceof Problem)) { return false; + } Problem problem = (Problem) o; return Objects.equals(this.type, problem.type) && Objects.equals(this.title, problem.title) && this.status == problem.status && Objects.equals(this.detail, problem.detail) @@ -257,6 +261,7 @@ public class Problem { return Objects.hash(this.type, this.title, this.status, this.detail, this.instance); } + @Override public String toString() { return "Problem(type=" + this.type + ", title=" + this.title + ", status=" + this.status + ", detail=" + this.detail + ", instance=" + this.instance + ")"; @@ -386,12 +391,15 @@ public class Problem { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof ExtendedProblem)) + } + if (!(o instanceof ExtendedProblem)) { return false; - if (!super.equals(o)) + } + if (!super.equals(o)) { return false; + } ExtendedProblem that = (ExtendedProblem) o; return Objects.equals(this.extendedProperties, that.extendedProperties); } @@ -401,6 +409,7 @@ public class Problem { return Objects.hash(super.hashCode(), extendedProperties); } + @Override public String toString() { return "Problem.ExtendedProblem(extendedProperties=" + this.extendedProperties + ")"; } diff --git a/src/main/java/org/springframework/hateoas/mediatype/problem/package-info.java b/src/main/java/org/springframework/hateoas/mediatype/problem/package-info.java index c41f1fee..43bc722f 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/problem/package-info.java +++ b/src/main/java/org/springframework/hateoas/mediatype/problem/package-info.java @@ -1,5 +1,5 @@ /** * Value objects to build Problem representations. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.mediatype.problem; diff --git a/src/main/java/org/springframework/hateoas/mediatype/uber/Jackson2UberModule.java b/src/main/java/org/springframework/hateoas/mediatype/uber/Jackson2UberModule.java index a6d1add8..80e42c78 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/uber/Jackson2UberModule.java +++ b/src/main/java/org/springframework/hateoas/mediatype/uber/Jackson2UberModule.java @@ -27,6 +27,7 @@ import java.util.Optional; import java.util.stream.Collectors; import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; @@ -37,7 +38,6 @@ import org.springframework.hateoas.PagedModel.PageMetadata; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.mediatype.JacksonHelper; import org.springframework.hateoas.mediatype.PropertyUtils; -import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; import com.fasterxml.jackson.core.JsonGenerator; @@ -129,7 +129,7 @@ public class Jackson2UberModule extends SimpleModule { implements ContextualSerializer { private static final long serialVersionUID = -572866287910993300L; - private final BeanProperty property; + private final @Nullable BeanProperty property; UberRepresentationModelSerializer(@Nullable BeanProperty property) { @@ -220,7 +220,7 @@ public class Jackson2UberModule extends SimpleModule { private static final long serialVersionUID = -5538560800604582741L; - private final BeanProperty property; + private final @Nullable BeanProperty property; UberEntityModelSerializer(@Nullable BeanProperty property) { @@ -310,7 +310,7 @@ public class Jackson2UberModule extends SimpleModule { private static final long serialVersionUID = 3422019794262694127L; - private BeanProperty property; + private @Nullable BeanProperty property; UberCollectionModelSerializer(@Nullable BeanProperty property) { @@ -400,7 +400,7 @@ public class Jackson2UberModule extends SimpleModule { private static final long serialVersionUID = -7892297813593085984L; - private BeanProperty property; + private @Nullable BeanProperty property; UberPagedModelSerializer(@Nullable BeanProperty property) { diff --git a/src/main/java/org/springframework/hateoas/mediatype/uber/Uber.java b/src/main/java/org/springframework/hateoas/mediatype/uber/Uber.java index 8ecdaa07..cce7b2b6 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/uber/Uber.java +++ b/src/main/java/org/springframework/hateoas/mediatype/uber/Uber.java @@ -18,8 +18,9 @@ package org.springframework.hateoas.mediatype.uber; import java.util.List; import java.util.Objects; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.Links; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -34,6 +35,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; * @since 1.0 */ @JsonInclude(Include.NON_NULL) +@NullUnmarked final class Uber { private final String version; @@ -118,10 +120,12 @@ final class Uber { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof Uber)) + } + if (!(o instanceof Uber)) { return false; + } Uber uber = (Uber) o; return Objects.equals(this.version, uber.version) && Objects.equals(this.data, uber.data) && Objects.equals(this.error, uber.error); diff --git a/src/main/java/org/springframework/hateoas/mediatype/uber/UberAction.java b/src/main/java/org/springframework/hateoas/mediatype/uber/UberAction.java index ccc06214..ae951d61 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/uber/UberAction.java +++ b/src/main/java/org/springframework/hateoas/mediatype/uber/UberAction.java @@ -18,9 +18,9 @@ package org.springframework.hateoas.mediatype.uber; import java.util.Arrays; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.mediatype.uber.Jackson2UberModule.UberActionDeserializer; import org.springframework.http.HttpMethod; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/src/main/java/org/springframework/hateoas/mediatype/uber/UberAffordanceModel.java b/src/main/java/org/springframework/hateoas/mediatype/uber/UberAffordanceModel.java index cba47118..e1473ab4 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/uber/UberAffordanceModel.java +++ b/src/main/java/org/springframework/hateoas/mediatype/uber/UberAffordanceModel.java @@ -21,12 +21,12 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.AffordanceModel; import org.springframework.hateoas.MediaTypes; import org.springframework.hateoas.mediatype.ConfiguredAffordance; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; /** * {@link AffordanceModel} for {@literal UBER+JSON}. diff --git a/src/main/java/org/springframework/hateoas/mediatype/uber/UberData.java b/src/main/java/org/springframework/hateoas/mediatype/uber/UberData.java index 7cdae1dd..52f6d5f5 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/uber/UberData.java +++ b/src/main/java/org/springframework/hateoas/mediatype/uber/UberData.java @@ -26,7 +26,8 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; -import org.springframework.hateoas.Affordance; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; @@ -37,7 +38,6 @@ import org.springframework.hateoas.PagedModel; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.mediatype.PropertyUtils; import org.springframework.http.HttpMethod; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -56,6 +56,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@NullUnmarked final class UberData { private @Nullable final String id, name, label; @@ -513,7 +514,7 @@ final class UberData { /** * Create new {@link UberData} by copying attributes and replacing {@literal accepting}. - * + * * @param accepting * @return */ @@ -526,7 +527,7 @@ final class UberData { /** * Create new {@link UberData} by copying attributes and replacing {@literal value}. - * + * * @param value * @return */ @@ -539,7 +540,7 @@ final class UberData { /** * Create new {@link UberData} by copying attributes and replacing {@literal data}. - * + * * @param data * @return */ @@ -613,10 +614,12 @@ final class UberData { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof UberData)) + } + if (!(o instanceof UberData)) { return false; + } UberData uberData = (UberData) o; return this.transclude == uberData.transclude && Objects.equals(this.id, uberData.id) && Objects.equals(this.name, uberData.name) && Objects.equals(this.label, uberData.label) @@ -671,10 +674,12 @@ final class UberData { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof LinkAndRels)) + } + if (!(o instanceof LinkAndRels)) { return false; + } LinkAndRels that = (LinkAndRels) o; return Objects.equals(this.link, that.link) && Objects.equals(this.rels, that.rels); } @@ -684,6 +689,7 @@ final class UberData { return Objects.hash(this.link, this.rels); } + @Override public String toString() { return "UberData.LinkAndRels(link=" + this.link + ", rels=" + this.rels + ")"; } diff --git a/src/main/java/org/springframework/hateoas/mediatype/uber/UberDocument.java b/src/main/java/org/springframework/hateoas/mediatype/uber/UberDocument.java index 89f12717..542ad487 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/uber/UberDocument.java +++ b/src/main/java/org/springframework/hateoas/mediatype/uber/UberDocument.java @@ -18,7 +18,7 @@ package org.springframework.hateoas.mediatype.uber; import java.util.List; import java.util.Objects; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/org/springframework/hateoas/mediatype/uber/UberError.java b/src/main/java/org/springframework/hateoas/mediatype/uber/UberError.java index 884cd6a0..35f2ca42 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/uber/UberError.java +++ b/src/main/java/org/springframework/hateoas/mediatype/uber/UberError.java @@ -18,7 +18,8 @@ package org.springframework.hateoas.mediatype.uber; import java.util.List; import java.util.Objects; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -29,6 +30,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; * @author Greg Turnquist * @since 1.0 */ +@NullUnmarked final class UberError { private final List data; @@ -53,10 +55,12 @@ final class UberError { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof UberError)) + } + if (!(o instanceof UberError)) { return false; + } UberError uberError = (UberError) o; return Objects.equals(this.data, uberError.data); } @@ -66,6 +70,7 @@ final class UberError { return Objects.hash(this.data); } + @Override public String toString() { return "UberError(data=" + this.data + ")"; } diff --git a/src/main/java/org/springframework/hateoas/mediatype/uber/UberMediaTypeConfiguration.java b/src/main/java/org/springframework/hateoas/mediatype/uber/UberMediaTypeConfiguration.java index 4557201b..0be44eac 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/uber/UberMediaTypeConfiguration.java +++ b/src/main/java/org/springframework/hateoas/mediatype/uber/UberMediaTypeConfiguration.java @@ -17,13 +17,13 @@ package org.springframework.hateoas.mediatype.uber; import java.util.List; +import org.jspecify.annotations.NonNull; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.hateoas.client.LinkDiscoverer; import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType; import org.springframework.hateoas.config.HypermediaMappingInformation; import org.springframework.http.MediaType; -import org.springframework.lang.NonNull; import com.fasterxml.jackson.databind.Module; diff --git a/src/main/java/org/springframework/hateoas/mediatype/uber/package-info.java b/src/main/java/org/springframework/hateoas/mediatype/uber/package-info.java index 22c466da..be867b16 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/uber/package-info.java +++ b/src/main/java/org/springframework/hateoas/mediatype/uber/package-info.java @@ -1,7 +1,5 @@ /** * UBER media type objects. */ -@NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.mediatype.uber; - -import org.springframework.lang.NonNullApi; diff --git a/src/main/java/org/springframework/hateoas/mediatype/vnderrors/VndErrors.java b/src/main/java/org/springframework/hateoas/mediatype/vnderrors/VndErrors.java index c64c2ad1..3e578875 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/vnderrors/VndErrors.java +++ b/src/main/java/org/springframework/hateoas/mediatype/vnderrors/VndErrors.java @@ -23,12 +23,13 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.Link; import org.springframework.hateoas.Links; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.server.core.Relation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -50,6 +51,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; @JsonPropertyOrder({ "message", "logref", "total", "_links", "_embedded" }) @JsonIgnoreProperties(ignoreUnknown = true) @Deprecated +@NullUnmarked public class VndErrors extends CollectionModel { /** diff --git a/src/main/java/org/springframework/hateoas/mediatype/vnderrors/package-info.java b/src/main/java/org/springframework/hateoas/mediatype/vnderrors/package-info.java index f4e96ff9..118e21c9 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/vnderrors/package-info.java +++ b/src/main/java/org/springframework/hateoas/mediatype/vnderrors/package-info.java @@ -1,7 +1,5 @@ /** * Vnd.Error media type. */ -@NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.mediatype.vnderrors; - -import org.springframework.lang.NonNullApi; diff --git a/src/main/java/org/springframework/hateoas/package-info.java b/src/main/java/org/springframework/hateoas/package-info.java index 7e409b15..1a09680f 100644 --- a/src/main/java/org/springframework/hateoas/package-info.java +++ b/src/main/java/org/springframework/hateoas/package-info.java @@ -6,5 +6,5 @@ * @author Jens Schauder * @author Greg Turnquist */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas; diff --git a/src/main/java/org/springframework/hateoas/server/EntityLinks.java b/src/main/java/org/springframework/hateoas/server/EntityLinks.java index 3e776d32..124089cc 100644 --- a/src/main/java/org/springframework/hateoas/server/EntityLinks.java +++ b/src/main/java/org/springframework/hateoas/server/EntityLinks.java @@ -17,7 +17,6 @@ package org.springframework.hateoas.server; import java.util.function.Function; -import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; import org.springframework.hateoas.server.TypedEntityLinks.ExtendedTypedEntityLinks; import org.springframework.plugin.core.Plugin; diff --git a/src/main/java/org/springframework/hateoas/server/ExposesResourceFor.java b/src/main/java/org/springframework/hateoas/server/ExposesResourceFor.java index daf805fb..1629adc8 100644 --- a/src/main/java/org/springframework/hateoas/server/ExposesResourceFor.java +++ b/src/main/java/org/springframework/hateoas/server/ExposesResourceFor.java @@ -22,8 +22,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import org.springframework.hateoas.server.core.ControllerEntityLinks; - /** * Annotation to demarcate controllers that expose URI templates of a structure according to * {@link ControllerEntityLinks}. diff --git a/src/main/java/org/springframework/hateoas/server/LinkBuilder.java b/src/main/java/org/springframework/hateoas/server/LinkBuilder.java index d1ef77a9..e8511077 100644 --- a/src/main/java/org/springframework/hateoas/server/LinkBuilder.java +++ b/src/main/java/org/springframework/hateoas/server/LinkBuilder.java @@ -17,10 +17,9 @@ package org.springframework.hateoas.server; import java.net.URI; -import org.springframework.hateoas.IanaLinkRelations; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkRelation; -import org.springframework.lang.Nullable; /** * Builder to ease building {@link Link} instances. diff --git a/src/main/java/org/springframework/hateoas/server/LinkRelationProvider.java b/src/main/java/org/springframework/hateoas/server/LinkRelationProvider.java index f70ea954..3ba0a920 100644 --- a/src/main/java/org/springframework/hateoas/server/LinkRelationProvider.java +++ b/src/main/java/org/springframework/hateoas/server/LinkRelationProvider.java @@ -17,10 +17,9 @@ package org.springframework.hateoas.server; import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.server.LinkRelationProvider.LookupContext; -import org.springframework.hateoas.server.core.DelegatingLinkRelationProvider; -import org.springframework.lang.Nullable; import org.springframework.plugin.core.Plugin; import org.springframework.util.Assert; @@ -73,7 +72,7 @@ public interface LinkRelationProvider extends Plugin { private final Class type; private final @Nullable ResourceType resourceType; - private LookupContext(Class type, ResourceType resourceType) { + private LookupContext(Class type, @Nullable ResourceType resourceType) { Assert.notNull(type, "type must not be null!"); @@ -81,10 +80,6 @@ public interface LinkRelationProvider extends Plugin { this.resourceType = resourceType; } - private static LookupContext of(Class type, ResourceType resourceType) { - return new LookupContext(type, resourceType); - } - public Class getType() { return this.type; } @@ -154,10 +149,12 @@ public interface LinkRelationProvider extends Plugin { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof LookupContext)) + } + if (!(o instanceof LookupContext)) { return false; + } LookupContext that = (LookupContext) o; return Objects.equals(this.type, that.type) && this.resourceType == that.resourceType; } diff --git a/src/main/java/org/springframework/hateoas/server/MethodLinkBuilderFactory.java b/src/main/java/org/springframework/hateoas/server/MethodLinkBuilderFactory.java index 0781cf65..f1293ed4 100644 --- a/src/main/java/org/springframework/hateoas/server/MethodLinkBuilderFactory.java +++ b/src/main/java/org/springframework/hateoas/server/MethodLinkBuilderFactory.java @@ -17,9 +17,6 @@ package org.springframework.hateoas.server; import java.lang.reflect.Method; -import org.springframework.hateoas.server.core.DummyInvocationUtils; -import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder; - /** * Extension of {@link LinkBuilderFactory} for implementations that also support creating {@link LinkBuilder}s by * pointing to a method. diff --git a/src/main/java/org/springframework/hateoas/server/RepresentationModelProcessor.java b/src/main/java/org/springframework/hateoas/server/RepresentationModelProcessor.java index 9cd17475..9b472ab7 100644 --- a/src/main/java/org/springframework/hateoas/server/RepresentationModelProcessor.java +++ b/src/main/java/org/springframework/hateoas/server/RepresentationModelProcessor.java @@ -15,8 +15,6 @@ */ package org.springframework.hateoas.server; -import org.springframework.hateoas.CollectionModel; -import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.RepresentationModel; /** diff --git a/src/main/java/org/springframework/hateoas/server/TypedEntityLinks.java b/src/main/java/org/springframework/hateoas/server/TypedEntityLinks.java index 954324c3..b3713d9f 100644 --- a/src/main/java/org/springframework/hateoas/server/TypedEntityLinks.java +++ b/src/main/java/org/springframework/hateoas/server/TypedEntityLinks.java @@ -17,7 +17,6 @@ package org.springframework.hateoas.server; import java.util.function.Function; -import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; import org.springframework.util.Assert; diff --git a/src/main/java/org/springframework/hateoas/server/core/AnnotationAttribute.java b/src/main/java/org/springframework/hateoas/server/core/AnnotationAttribute.java index 50d5f8ef..31782124 100644 --- a/src/main/java/org/springframework/hateoas/server/core/AnnotationAttribute.java +++ b/src/main/java/org/springframework/hateoas/server/core/AnnotationAttribute.java @@ -17,9 +17,9 @@ package org.springframework.hateoas.server.core; import java.lang.annotation.Annotation; +import org.jspecify.annotations.Nullable; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -30,7 +30,7 @@ import org.springframework.util.Assert; public class AnnotationAttribute { private final Class annotationType; - private final String attributeName; + private final @Nullable String attributeName; /** * Creates a new {@link AnnotationAttribute} to the {@code value} attribute of the given {@link Annotation} type. diff --git a/src/main/java/org/springframework/hateoas/server/core/AnnotationLinkRelationProvider.java b/src/main/java/org/springframework/hateoas/server/core/AnnotationLinkRelationProvider.java index e501be17..d2a11edb 100644 --- a/src/main/java/org/springframework/hateoas/server/core/AnnotationLinkRelationProvider.java +++ b/src/main/java/org/springframework/hateoas/server/core/AnnotationLinkRelationProvider.java @@ -17,11 +17,11 @@ package org.springframework.hateoas.server.core; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.server.LinkRelationProvider; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ConcurrentReferenceHashMap; diff --git a/src/main/java/org/springframework/hateoas/server/core/AnnotationMappingDiscoverer.java b/src/main/java/org/springframework/hateoas/server/core/AnnotationMappingDiscoverer.java index 1475b9a1..fb5c3d9e 100644 --- a/src/main/java/org/springframework/hateoas/server/core/AnnotationMappingDiscoverer.java +++ b/src/main/java/org/springframework/hateoas/server/core/AnnotationMappingDiscoverer.java @@ -27,9 +27,9 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMethod; @@ -45,7 +45,7 @@ import org.springframework.web.bind.annotation.RequestMethod; public class AnnotationMappingDiscoverer implements MappingDiscoverer { private final Class annotationType; - private final String mappingAttributeName; + private final @Nullable String mappingAttributeName; /** * Creates an {@link AnnotationMappingDiscoverer} for the given annotation type. Will lookup the {@code value} diff --git a/src/main/java/org/springframework/hateoas/server/core/CachingMappingDiscoverer.java b/src/main/java/org/springframework/hateoas/server/core/CachingMappingDiscoverer.java index ecf5243f..34e4b38b 100644 --- a/src/main/java/org/springframework/hateoas/server/core/CachingMappingDiscoverer.java +++ b/src/main/java/org/springframework/hateoas/server/core/CachingMappingDiscoverer.java @@ -20,9 +20,9 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.StringUtils; diff --git a/src/main/java/org/springframework/hateoas/server/core/ControllerEntityLinks.java b/src/main/java/org/springframework/hateoas/server/core/ControllerEntityLinks.java index 3f112452..f217474f 100644 --- a/src/main/java/org/springframework/hateoas/server/core/ControllerEntityLinks.java +++ b/src/main/java/org/springframework/hateoas/server/core/ControllerEntityLinks.java @@ -20,12 +20,10 @@ import java.util.Map; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.hateoas.Link; -import org.springframework.hateoas.server.EntityLinks; import org.springframework.hateoas.server.ExposesResourceFor; import org.springframework.hateoas.server.LinkBuilder; import org.springframework.hateoas.server.LinkBuilderFactory; import org.springframework.util.Assert; -import org.springframework.web.bind.annotation.RequestMapping; /** * {@link EntityLinks} implementation which assumes a certain URI mapping structure: diff --git a/src/main/java/org/springframework/hateoas/server/core/ControllerEntityLinksFactoryBean.java b/src/main/java/org/springframework/hateoas/server/core/ControllerEntityLinksFactoryBean.java index 0bc7ed1c..be5adc76 100644 --- a/src/main/java/org/springframework/hateoas/server/core/ControllerEntityLinksFactoryBean.java +++ b/src/main/java/org/springframework/hateoas/server/core/ControllerEntityLinksFactoryBean.java @@ -18,9 +18,11 @@ package org.springframework.hateoas.server.core; import java.lang.annotation.Annotation; import java.util.Collection; import java.util.HashSet; +import java.util.Objects; import java.util.Set; -import org.springframework.beans.factory.FactoryBean; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -28,7 +30,6 @@ import org.springframework.core.annotation.AnnotationUtils; import org.springframework.hateoas.server.ExposesResourceFor; import org.springframework.hateoas.server.LinkBuilder; import org.springframework.hateoas.server.LinkBuilderFactory; -import org.springframework.lang.NonNull; import org.springframework.util.Assert; /** @@ -40,9 +41,9 @@ import org.springframework.util.Assert; public class ControllerEntityLinksFactoryBean extends AbstractFactoryBean implements ApplicationContextAware { - private Class annotation; - private LinkBuilderFactory linkBuilderFactory; - private ApplicationContext context; + private @Nullable Class annotation; + private @Nullable LinkBuilderFactory linkBuilderFactory; + private @Nullable ApplicationContext context; /** * Configures the annotation type to inspect the {@link ApplicationContext} for beans that carry the given annotation. @@ -89,6 +90,10 @@ public class ControllerEntityLinksFactoryBean extends AbstractFactoryBean> controllerTypes = new HashSet<>(); for (Class controllerType : getBeanTypesWithAnnotation(annotation)) { @@ -116,9 +121,10 @@ public class ControllerEntityLinksFactoryBean extends AbstractFactoryBean> annotatedTypes = new HashSet<>(); - for (String beanName : context.getBeanDefinitionNames()) { + for (String beanName : Objects.requireNonNull(context).getBeanDefinitionNames()) { Annotation annotation = context.findAnnotationOnBean(beanName, type); + if (annotation != null) { annotatedTypes.add(context.getType(beanName)); } diff --git a/src/main/java/org/springframework/hateoas/server/core/DefaultMethodInvocation.java b/src/main/java/org/springframework/hateoas/server/core/DefaultMethodInvocation.java index 81e23f26..8d503945 100644 --- a/src/main/java/org/springframework/hateoas/server/core/DefaultMethodInvocation.java +++ b/src/main/java/org/springframework/hateoas/server/core/DefaultMethodInvocation.java @@ -21,7 +21,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.Objects; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/hateoas/server/core/DummyInvocationUtils.java b/src/main/java/org/springframework/hateoas/server/core/DummyInvocationUtils.java index b59f5fff..ea689594 100644 --- a/src/main/java/org/springframework/hateoas/server/core/DummyInvocationUtils.java +++ b/src/main/java/org/springframework/hateoas/server/core/DummyInvocationUtils.java @@ -21,10 +21,9 @@ import java.util.Iterator; import java.util.Objects; import org.aopalliance.intercept.MethodInterceptor; +import org.jspecify.annotations.Nullable; import org.springframework.aop.framework.Advised; import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.target.EmptyTargetSource; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ConcurrentLruCache; import org.springframework.util.ReflectionUtils; @@ -55,7 +54,7 @@ public class DummyInvocationUtils { private final Class targetType; private final Object[] objectParameters; - private MethodInvocation invocation; + private @Nullable MethodInvocation invocation; /** * Creates a new {@link InvocationRecordingMethodInterceptor} carrying the given parameters forward that might be @@ -101,7 +100,7 @@ public class DummyInvocationUtils { * @see org.springframework.hateoas.core.DummyInvocationUtils.LastInvocationAware#getLastInvocation() */ @Override - public MethodInvocation getLastInvocation() { + public @Nullable MethodInvocation getLastInvocation() { return invocation; } diff --git a/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrapper.java b/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrapper.java index 602962e7..11877976 100644 --- a/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrapper.java +++ b/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrapper.java @@ -17,9 +17,8 @@ package org.springframework.hateoas.server.core; import java.util.Optional; -import org.springframework.hateoas.EntityModel; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.LinkRelation; -import org.springframework.lang.Nullable; /** * A wrapper to handle values to be embedded into a {@link EntityModel}. diff --git a/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrappers.java b/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrappers.java index 8b65f344..dfb16eaa 100644 --- a/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrappers.java +++ b/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrappers.java @@ -23,12 +23,12 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.aop.support.AopUtils; import org.springframework.core.ResolvableType; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.LinkRelation; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/hateoas/server/core/EvoInflectorLinkRelationProvider.java b/src/main/java/org/springframework/hateoas/server/core/EvoInflectorLinkRelationProvider.java index 9477be19..4ee421f1 100644 --- a/src/main/java/org/springframework/hateoas/server/core/EvoInflectorLinkRelationProvider.java +++ b/src/main/java/org/springframework/hateoas/server/core/EvoInflectorLinkRelationProvider.java @@ -17,7 +17,6 @@ package org.springframework.hateoas.server.core; import org.atteo.evo.inflector.English; import org.springframework.hateoas.LinkRelation; -import org.springframework.hateoas.server.LinkRelationProvider; /** * {@link LinkRelationProvider} implementation using the Evo Inflector implementation of an algorithmic approach to diff --git a/src/main/java/org/springframework/hateoas/server/core/HeaderLinksResponseEntity.java b/src/main/java/org/springframework/hateoas/server/core/HeaderLinksResponseEntity.java index 9cb6331d..93d13de8 100644 --- a/src/main/java/org/springframework/hateoas/server/core/HeaderLinksResponseEntity.java +++ b/src/main/java/org/springframework/hateoas/server/core/HeaderLinksResponseEntity.java @@ -15,13 +15,10 @@ */ package org.springframework.hateoas.server.core; -import org.springframework.hateoas.Link; import org.springframework.hateoas.Links; import org.springframework.hateoas.RepresentationModel; -import org.springframework.hateoas.server.RepresentationModelProcessor; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; diff --git a/src/main/java/org/springframework/hateoas/server/core/LastInvocationAware.java b/src/main/java/org/springframework/hateoas/server/core/LastInvocationAware.java index 14c3a976..2169a87b 100644 --- a/src/main/java/org/springframework/hateoas/server/core/LastInvocationAware.java +++ b/src/main/java/org/springframework/hateoas/server/core/LastInvocationAware.java @@ -17,6 +17,8 @@ package org.springframework.hateoas.server.core; import java.util.Iterator; +import org.jspecify.annotations.Nullable; + /** * @author Oliver Drotbohm * @author Greg Turnquist @@ -25,5 +27,6 @@ public interface LastInvocationAware { Iterator getObjectParameters(); + @Nullable MethodInvocation getLastInvocation(); } diff --git a/src/main/java/org/springframework/hateoas/server/core/LinkBuilderSupport.java b/src/main/java/org/springframework/hateoas/server/core/LinkBuilderSupport.java index dfe9ee70..6f8ccb46 100644 --- a/src/main/java/org/springframework/hateoas/server/core/LinkBuilderSupport.java +++ b/src/main/java/org/springframework/hateoas/server/core/LinkBuilderSupport.java @@ -24,12 +24,12 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.Affordance; import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.server.LinkBuilder; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.util.UriComponents; diff --git a/src/main/java/org/springframework/hateoas/server/core/MappingDiscoverer.java b/src/main/java/org/springframework/hateoas/server/core/MappingDiscoverer.java index a7f86d69..935cd0e9 100644 --- a/src/main/java/org/springframework/hateoas/server/core/MappingDiscoverer.java +++ b/src/main/java/org/springframework/hateoas/server/core/MappingDiscoverer.java @@ -19,9 +19,9 @@ import java.lang.reflect.Method; import java.util.Collection; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; /** * Strategy interface to discover a URI mapping and related {@link org.springframework.hateoas.Affordance}s for either a diff --git a/src/main/java/org/springframework/hateoas/server/core/MethodParameters.java b/src/main/java/org/springframework/hateoas/server/core/MethodParameters.java index 5d03f714..bd69e245 100644 --- a/src/main/java/org/springframework/hateoas/server/core/MethodParameters.java +++ b/src/main/java/org/springframework/hateoas/server/core/MethodParameters.java @@ -26,11 +26,11 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.jspecify.annotations.Nullable; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodParameter; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.annotation.SynthesizingMethodParameter; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ConcurrentReferenceHashMap; @@ -155,10 +155,10 @@ public class MethodParameters { */ private static class AnnotationNamingMethodParameter extends SynthesizingMethodParameter { - private final AnnotationAttribute attribute; + private final @Nullable AnnotationAttribute attribute; - private String name; - private @Nullable Annotation[] combinedAnnotations; + private @Nullable String name; + private Annotation @Nullable [] combinedAnnotations; /** * Creates a new {@link AnnotationNamingMethodParameter} for the given {@link Method}'s parameter with the given diff --git a/src/main/java/org/springframework/hateoas/server/core/PropertyResolvingMappingDiscoverer.java b/src/main/java/org/springframework/hateoas/server/core/PropertyResolvingMappingDiscoverer.java index 9ca06195..20ae87ba 100644 --- a/src/main/java/org/springframework/hateoas/server/core/PropertyResolvingMappingDiscoverer.java +++ b/src/main/java/org/springframework/hateoas/server/core/PropertyResolvingMappingDiscoverer.java @@ -19,9 +19,9 @@ import java.lang.reflect.Method; import java.util.Collection; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.web.context.ContextLoader; import org.springframework.web.context.WebApplicationContext; diff --git a/src/main/java/org/springframework/hateoas/server/core/Relation.java b/src/main/java/org/springframework/hateoas/server/core/Relation.java index cfb96de6..ed5f5157 100644 --- a/src/main/java/org/springframework/hateoas/server/core/Relation.java +++ b/src/main/java/org/springframework/hateoas/server/core/Relation.java @@ -21,8 +21,6 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.annotation.AliasFor; -import org.springframework.hateoas.CollectionModel; -import org.springframework.hateoas.EntityModel; /** * Annotation to configure the relation to be used when embedding objects in HAL representations of {@link EntityModel}s diff --git a/src/main/java/org/springframework/hateoas/server/core/SpringAffordanceBuilder.java b/src/main/java/org/springframework/hateoas/server/core/SpringAffordanceBuilder.java index 2a824774..28aac5c6 100644 --- a/src/main/java/org/springframework/hateoas/server/core/SpringAffordanceBuilder.java +++ b/src/main/java/org/springframework/hateoas/server/core/SpringAffordanceBuilder.java @@ -23,6 +23,7 @@ import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.core.ResolvableType; import org.springframework.hateoas.Affordance; import org.springframework.hateoas.Link; @@ -31,7 +32,6 @@ import org.springframework.hateoas.QueryParameter; import org.springframework.hateoas.mediatype.Affordances; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ConcurrentLruCache; import org.springframework.web.bind.annotation.RequestBody; diff --git a/src/main/java/org/springframework/hateoas/server/core/TypeReferences.java b/src/main/java/org/springframework/hateoas/server/core/TypeReferences.java index 1d68a30f..175f3186 100644 --- a/src/main/java/org/springframework/hateoas/server/core/TypeReferences.java +++ b/src/main/java/org/springframework/hateoas/server/core/TypeReferences.java @@ -20,9 +20,9 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; +import org.jspecify.annotations.Nullable; import org.springframework.core.GenericTypeResolver; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/hateoas/server/core/UriMapping.java b/src/main/java/org/springframework/hateoas/server/core/UriMapping.java index c4e4f5e8..f1dc6009 100644 --- a/src/main/java/org/springframework/hateoas/server/core/UriMapping.java +++ b/src/main/java/org/springframework/hateoas/server/core/UriMapping.java @@ -24,8 +24,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.TemplateVariable; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.web.util.UriTemplate; diff --git a/src/main/java/org/springframework/hateoas/server/core/UriTemplateFactory.java b/src/main/java/org/springframework/hateoas/server/core/UriTemplateFactory.java index 9b49c2ea..44509965 100644 --- a/src/main/java/org/springframework/hateoas/server/core/UriTemplateFactory.java +++ b/src/main/java/org/springframework/hateoas/server/core/UriTemplateFactory.java @@ -17,7 +17,7 @@ package org.springframework.hateoas.server.core; import java.util.Map; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.web.util.UriTemplate; diff --git a/src/main/java/org/springframework/hateoas/server/core/WebHandler.java b/src/main/java/org/springframework/hateoas/server/core/WebHandler.java index 0925123f..e11491d4 100644 --- a/src/main/java/org/springframework/hateoas/server/core/WebHandler.java +++ b/src/main/java/org/springframework/hateoas/server/core/WebHandler.java @@ -29,6 +29,7 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.core.MethodParameter; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; @@ -39,7 +40,6 @@ import org.springframework.hateoas.TemplateVariables; import org.springframework.hateoas.server.LinkBuilder; import org.springframework.hateoas.server.core.UriMapping.MappingVariable; import org.springframework.hateoas.server.core.UriMapping.MappingVariables; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -98,7 +98,7 @@ public class WebHandler { throw new IllegalStateException(String.format("Could not obtain previous invocation from %s!", invocationValue)); } - MethodInvocation invocation = invocations.getLastInvocation(); + MethodInvocation invocation = Objects.requireNonNull(invocations.getLastInvocation()); UriMapping mapping = SpringAffordanceBuilder.getUriMapping(invocation.getTargetType(), invocation.getMethod()); return (finisher, conversionService) -> { @@ -139,7 +139,8 @@ public class WebHandler { if (mappingVariable.isCapturing()) { - List segments = Arrays.asList(((String) preparedValue).split("/")); + List segments = preparedValue == null ? Collections.emptyList() + : Arrays.asList(((String) preparedValue).split("/")); Object value = segments.size() != 0 ? "/" + segment.composite().prepareAndEncode(segments) : ""; values.put(key, value); @@ -348,7 +349,7 @@ public class WebHandler { private final TypeDescriptor typeDescriptor; private final boolean isNonComposite; - private String variableName; + private @Nullable String variableName; /** * Creates a new {@link HandlerMethodParameter} for the given {@link MethodParameter} and @@ -364,7 +365,7 @@ public class WebHandler { int nestingIndex = Optional.class.isAssignableFrom(parameter.getParameterType()) ? 1 : 0; - this.typeDescriptor = TypeDescriptor.nested(parameter, nestingIndex); + this.typeDescriptor = Objects.requireNonNull(TypeDescriptor.nested(parameter, nestingIndex)); this.isNonComposite = parameter.hasParameterAnnotation(NonComposite.class); if (isNonComposite) { @@ -479,7 +480,9 @@ public class WebHandler { this.variableName = parameter.getParameterName(); - return variableName; + if (variableName != null) { + return variableName; + } } Annotation annotation = parameter.getParameterAnnotation(attribute.getAnnotationType()); @@ -601,7 +604,7 @@ public class WebHandler { /* * (non-Javadoc) - * @see org.springframework.hateoas.server.core.WebHandler.HandlerMethodParameter#verifyValue(java.lang.Object[]) + * @see org.springframework.hateoas.server.core.WebHandler.HandlerMethodParameter#getVerifiedValue(java.lang.Object[]) */ @Override @Nullable @@ -619,7 +622,7 @@ public class WebHandler { RequestParam annotation = parameter.getParameterAnnotation(RequestParam.class); - return annotation.defaultValue().equals(ValueConstants.DEFAULT_NONE) ? SKIP_VALUE : null; + return annotation != null && annotation.defaultValue().equals(ValueConstants.DEFAULT_NONE) ? SKIP_VALUE : null; } } diff --git a/src/main/java/org/springframework/hateoas/server/core/package-info.java b/src/main/java/org/springframework/hateoas/server/core/package-info.java index 3fc81f2d..adf7d341 100644 --- a/src/main/java/org/springframework/hateoas/server/core/package-info.java +++ b/src/main/java/org/springframework/hateoas/server/core/package-info.java @@ -1,7 +1,5 @@ /** * Implementations of core API interfaces. */ -@NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.server.core; - -import org.springframework.lang.NonNullApi; diff --git a/src/main/java/org/springframework/hateoas/server/mvc/BasicLinkBuilder.java b/src/main/java/org/springframework/hateoas/server/mvc/BasicLinkBuilder.java index 1c3e76d8..5e2eeaaa 100644 --- a/src/main/java/org/springframework/hateoas/server/mvc/BasicLinkBuilder.java +++ b/src/main/java/org/springframework/hateoas/server/mvc/BasicLinkBuilder.java @@ -18,11 +18,9 @@ package org.springframework.hateoas.server.mvc; import java.util.List; import org.springframework.hateoas.Affordance; -import org.springframework.hateoas.server.LinkBuilder; import org.springframework.hateoas.server.core.LinkBuilderSupport; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; /** * Simples {@link LinkBuilder} implementation possible. Exposes a link to the current servlet mapping only. diff --git a/src/main/java/org/springframework/hateoas/server/mvc/JacksonSerializers.java b/src/main/java/org/springframework/hateoas/server/mvc/JacksonSerializers.java index 8d65c0f4..54149837 100644 --- a/src/main/java/org/springframework/hateoas/server/mvc/JacksonSerializers.java +++ b/src/main/java/org/springframework/hateoas/server/mvc/JacksonSerializers.java @@ -21,7 +21,6 @@ import org.springframework.http.MediaType; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; /** diff --git a/src/main/java/org/springframework/hateoas/server/mvc/RepresentationModelProcessorHandlerMethodReturnValueHandler.java b/src/main/java/org/springframework/hateoas/server/mvc/RepresentationModelProcessorHandlerMethodReturnValueHandler.java index 2bb91522..8862e9e7 100644 --- a/src/main/java/org/springframework/hateoas/server/mvc/RepresentationModelProcessorHandlerMethodReturnValueHandler.java +++ b/src/main/java/org/springframework/hateoas/server/mvc/RepresentationModelProcessorHandlerMethodReturnValueHandler.java @@ -17,18 +17,18 @@ package org.springframework.hateoas.server.mvc; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.Objects; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.RepresentationModel; -import org.springframework.hateoas.server.RepresentationModelProcessor; import org.springframework.hateoas.server.core.HeaderLinksResponseEntity; import org.springframework.http.HttpEntity; import org.springframework.http.ResponseEntity; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; import org.springframework.web.context.request.NativeWebRequest; @@ -49,7 +49,8 @@ public class RepresentationModelProcessorHandlerMethodReturnValueHandler impleme static final ResolvableType COLLECTION_MODEL_TYPE = ResolvableType.forRawClass(CollectionModel.class); private static final ResolvableType HTTP_ENTITY_TYPE = ResolvableType.forRawClass(HttpEntity.class); - static final Field CONTENT_FIELD = ReflectionUtils.findField(CollectionModel.class, "content"); + static final Field CONTENT_FIELD = Objects + .requireNonNull(ReflectionUtils.findField(CollectionModel.class, "content")); static { if (CONTENT_FIELD != null) { diff --git a/src/main/java/org/springframework/hateoas/server/mvc/RepresentationModelProcessorInvoker.java b/src/main/java/org/springframework/hateoas/server/mvc/RepresentationModelProcessorInvoker.java index 221548d3..0898c84d 100644 --- a/src/main/java/org/springframework/hateoas/server/mvc/RepresentationModelProcessorInvoker.java +++ b/src/main/java/org/springframework/hateoas/server/mvc/RepresentationModelProcessorInvoker.java @@ -20,6 +20,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.core.Ordered; import org.springframework.core.ResolvableType; import org.springframework.core.annotation.AnnotationAwareOrderComparator; @@ -28,7 +29,6 @@ import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.server.RepresentationModelProcessor; import org.springframework.hateoas.server.core.EmbeddedWrapper; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; diff --git a/src/main/java/org/springframework/hateoas/server/mvc/TypeConstrainedMappingJackson2HttpMessageConverter.java b/src/main/java/org/springframework/hateoas/server/mvc/TypeConstrainedMappingJackson2HttpMessageConverter.java index b6768177..156a9d65 100644 --- a/src/main/java/org/springframework/hateoas/server/mvc/TypeConstrainedMappingJackson2HttpMessageConverter.java +++ b/src/main/java/org/springframework/hateoas/server/mvc/TypeConstrainedMappingJackson2HttpMessageConverter.java @@ -18,9 +18,9 @@ package org.springframework.hateoas.server.mvc; import java.lang.reflect.Type; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/org/springframework/hateoas/server/mvc/UriComponentsBuilderFactory.java b/src/main/java/org/springframework/hateoas/server/mvc/UriComponentsBuilderFactory.java index efbd7fde..3f18e3d8 100644 --- a/src/main/java/org/springframework/hateoas/server/mvc/UriComponentsBuilderFactory.java +++ b/src/main/java/org/springframework/hateoas/server/mvc/UriComponentsBuilderFactory.java @@ -17,8 +17,8 @@ package org.springframework.hateoas.server.mvc; import java.net.URI; +import org.jspecify.annotations.Nullable; import org.springframework.hateoas.server.core.UriMapping; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; diff --git a/src/main/java/org/springframework/hateoas/server/mvc/UriComponentsContributor.java b/src/main/java/org/springframework/hateoas/server/mvc/UriComponentsContributor.java index 548b6a3f..5ffc54e6 100644 --- a/src/main/java/org/springframework/hateoas/server/mvc/UriComponentsContributor.java +++ b/src/main/java/org/springframework/hateoas/server/mvc/UriComponentsContributor.java @@ -15,10 +15,8 @@ */ package org.springframework.hateoas.server.mvc; +import org.jspecify.annotations.Nullable; import org.springframework.core.MethodParameter; -import org.springframework.hateoas.server.MethodLinkBuilderFactory; -import org.springframework.lang.Nullable; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.util.UriComponentsBuilder; /** diff --git a/src/main/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilder.java b/src/main/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilder.java index e78007d0..43cfbdde 100644 --- a/src/main/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilder.java +++ b/src/main/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilder.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; import org.springframework.hateoas.Affordance; -import org.springframework.hateoas.Link; import org.springframework.hateoas.TemplateVariables; import org.springframework.hateoas.server.core.DummyInvocationUtils; import org.springframework.hateoas.server.core.SpringAffordanceBuilder; diff --git a/src/main/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderFactory.java b/src/main/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderFactory.java index 78f9a25e..039f7b79 100644 --- a/src/main/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderFactory.java +++ b/src/main/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderFactory.java @@ -30,9 +30,7 @@ import java.util.function.Supplier; import org.springframework.core.MethodParameter; import org.springframework.core.convert.ConversionService; import org.springframework.format.support.DefaultFormattingConversionService; -import org.springframework.hateoas.Link; import org.springframework.hateoas.server.MethodLinkBuilderFactory; -import org.springframework.hateoas.server.core.LinkBuilderSupport; import org.springframework.hateoas.server.core.MethodParameters; import org.springframework.hateoas.server.core.SpringAffordanceBuilder; import org.springframework.hateoas.server.core.UriMapping; diff --git a/src/main/java/org/springframework/hateoas/server/mvc/package-info.java b/src/main/java/org/springframework/hateoas/server/mvc/package-info.java index 9cd4fc7f..d0be10b7 100644 --- a/src/main/java/org/springframework/hateoas/server/mvc/package-info.java +++ b/src/main/java/org/springframework/hateoas/server/mvc/package-info.java @@ -2,7 +2,5 @@ * Spring MVC helper classes to build {@link org.springframework.hateoas.Link}s and assemble * {@link org.springframework.hateoas.RepresentationModel} types. */ -@NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.server.mvc; - -import org.springframework.lang.NonNullApi; diff --git a/src/main/java/org/springframework/hateoas/server/package-info.java b/src/main/java/org/springframework/hateoas/server/package-info.java index 033eff99..e8de647d 100644 --- a/src/main/java/org/springframework/hateoas/server/package-info.java +++ b/src/main/java/org/springframework/hateoas/server/package-info.java @@ -1,7 +1,5 @@ /** * Server-side components for hypermedia handling. */ -@NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.server; - -import org.springframework.lang.NonNullApi; diff --git a/src/main/java/org/springframework/hateoas/server/reactive/ReactiveRepresentationModelAssembler.java b/src/main/java/org/springframework/hateoas/server/reactive/ReactiveRepresentationModelAssembler.java index ef5487fb..55b1ce44 100644 --- a/src/main/java/org/springframework/hateoas/server/reactive/ReactiveRepresentationModelAssembler.java +++ b/src/main/java/org/springframework/hateoas/server/reactive/ReactiveRepresentationModelAssembler.java @@ -20,8 +20,6 @@ import reactor.core.publisher.Mono; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.RepresentationModel; -import org.springframework.hateoas.server.RepresentationModelAssembler; -import org.springframework.hateoas.server.SimpleRepresentationModelAssembler; import org.springframework.web.server.ServerWebExchange; /** diff --git a/src/main/java/org/springframework/hateoas/server/reactive/SimpleReactiveRepresentationModelAssembler.java b/src/main/java/org/springframework/hateoas/server/reactive/SimpleReactiveRepresentationModelAssembler.java index 40c1d82e..7e687652 100644 --- a/src/main/java/org/springframework/hateoas/server/reactive/SimpleReactiveRepresentationModelAssembler.java +++ b/src/main/java/org/springframework/hateoas/server/reactive/SimpleReactiveRepresentationModelAssembler.java @@ -20,8 +20,6 @@ import reactor.core.publisher.Mono; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; -import org.springframework.hateoas.server.RepresentationModelAssembler; -import org.springframework.hateoas.server.SimpleRepresentationModelAssembler; import org.springframework.web.server.ServerWebExchange; /** diff --git a/src/main/java/org/springframework/hateoas/server/reactive/WebFluxLinkBuilder.java b/src/main/java/org/springframework/hateoas/server/reactive/WebFluxLinkBuilder.java index 9fc0591b..9bf2865d 100644 --- a/src/main/java/org/springframework/hateoas/server/reactive/WebFluxLinkBuilder.java +++ b/src/main/java/org/springframework/hateoas/server/reactive/WebFluxLinkBuilder.java @@ -22,11 +22,11 @@ import reactor.core.publisher.Mono; import java.util.List; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.springframework.context.ApplicationContext; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.hateoas.Affordance; -import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.TemplateVariables; @@ -37,7 +37,6 @@ import org.springframework.hateoas.server.core.WebHandler; import org.springframework.hateoas.server.core.WebHandler.PreparedWebHandler; import org.springframework.http.server.PathContainer; import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.util.UriComponents; @@ -274,32 +273,32 @@ public class WebFluxLinkBuilder extends TemplateVariableAwareLinkBuilderSupport< private UriComponentsBuilder builder; private ConversionService conversionService; + private CurrentRequest(UriComponentsBuilder builder, ConversionService conversionService) { + + this.builder = builder; + this.conversionService = conversionService; + } + public static Mono of(@Nullable ServerWebExchange exchange) { - CurrentRequest result = new CurrentRequest(); - if (exchange == null) { - - result.builder = UriComponentsBuilder.fromPath("/"); - result.conversionService = FALLBACK_CONVERSION_SERVICE; - - return Mono.just(result); + return Mono.just(new CurrentRequest(UriComponentsBuilder.fromPath("/"), FALLBACK_CONVERSION_SERVICE)); } ServerHttpRequest request = exchange.getRequest(); PathContainer contextPath = request.getPath().contextPath(); - result.builder = UriComponentsBuilder.fromUri(request.getURI()) // + var builder = UriComponentsBuilder.fromUri(request.getURI()) // .replacePath(contextPath.toString()) // .replaceQuery(""); ApplicationContext context = exchange.getApplicationContext(); - result.conversionService = context != null && context.containsBean("webFluxConversionService") + var conversionService = context != null && context.containsBean("webFluxConversionService") ? context.getBean("webFluxConversionService", ConversionService.class) : FALLBACK_CONVERSION_SERVICE; - return Mono.just(result); + return Mono.just(new CurrentRequest(builder, conversionService)); } UriComponentsBuilder toBuilder(UriMapping mapping) { diff --git a/src/main/java/org/springframework/hateoas/server/reactive/package-info.java b/src/main/java/org/springframework/hateoas/server/reactive/package-info.java index 00efe337..ee701960 100644 --- a/src/main/java/org/springframework/hateoas/server/reactive/package-info.java +++ b/src/main/java/org/springframework/hateoas/server/reactive/package-info.java @@ -2,7 +2,5 @@ * Spring WebFlux components to build {@link org.springframework.hateoas.Link}s and assemble * {@link org.springframework.hateoas.RepresentationModel} types. */ -@NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.server.reactive; - -import org.springframework.lang.NonNullApi; diff --git a/src/main/java/org/springframework/hateoas/support/ClassUtils.java b/src/main/java/org/springframework/hateoas/support/ClassUtils.java index c42bec53..82da8044 100644 --- a/src/main/java/org/springframework/hateoas/support/ClassUtils.java +++ b/src/main/java/org/springframework/hateoas/support/ClassUtils.java @@ -15,7 +15,7 @@ */ package org.springframework.hateoas.support; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * @author Oliver Drotbohm diff --git a/src/main/java/org/springframework/hateoas/support/package-info.java b/src/main/java/org/springframework/hateoas/support/package-info.java index b05be7ae..56142317 100644 --- a/src/main/java/org/springframework/hateoas/support/package-info.java +++ b/src/main/java/org/springframework/hateoas/support/package-info.java @@ -1,7 +1,5 @@ /** * Support utilities for hypermedia handling. */ -@NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.hateoas.support; - -import org.springframework.lang.NonNullApi; diff --git a/src/main/kotlin/org/springframework/hateoas/server/mvc/WebMvcAffordanceBuilderDsl.kt b/src/main/kotlin/org/springframework/hateoas/server/mvc/WebMvcAffordanceBuilderDsl.kt index 1fefae06..11cca081 100644 --- a/src/main/kotlin/org/springframework/hateoas/server/mvc/WebMvcAffordanceBuilderDsl.kt +++ b/src/main/kotlin/org/springframework/hateoas/server/mvc/WebMvcAffordanceBuilderDsl.kt @@ -43,7 +43,7 @@ inline infix fun Link.andAffordances(setup: WebMvcAffordanceBuilderDsl.() -> Uni * @author Roland Kulcsár * @since 1.0 */ -inline fun afford(func: C.() -> Unit): Affordance = afford(methodOn(C::class.java).apply(func)) +inline fun afford(func: C.() -> Any): Affordance = afford(methodOn(C::class.java as Class).run(func)) /** * Provide an [Affordance]s DSL to help write idiomatic Kotlin code. @@ -55,7 +55,7 @@ open class WebMvcAffordanceBuilderDsl(val affordances: MutableList = inline fun afford(func: C.() -> Any) { - val affordance = afford(methodOn(C::class.java).func()) + val affordance = afford(methodOn(C::class.java as Class).func()) affordances.add(affordance) } } diff --git a/src/main/kotlin/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderDsl.kt b/src/main/kotlin/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderDsl.kt index ae4b402e..837aa56b 100644 --- a/src/main/kotlin/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderDsl.kt +++ b/src/main/kotlin/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderDsl.kt @@ -32,7 +32,7 @@ import kotlin.reflect.KClass * @author Greg Turnquist * @since 1.0 */ -inline fun linkTo(func: C.() -> Unit): WebMvcLinkBuilder = linkTo(methodOn(C::class.java).apply(func)) +inline fun linkTo(func: C.() -> Any): WebMvcLinkBuilder = linkTo(methodOn(C::class.java as Class).run(func)) /** * Create a [Link] with the given [rel]. @@ -49,7 +49,7 @@ infix fun WebMvcLinkBuilder.withRel(rel: String): Link = withRel(rel) * @author Roland Kulcsár * @since 1.0 */ -fun > R.add(controller: Class, links: WebMvcLinkBuilderDsl.(R) -> Unit): R { +fun > R.add(controller: Class, links: WebMvcLinkBuilderDsl.(R) -> Unit): R { val builder = WebMvcLinkBuilderDsl(controller, this) builder.links(this) @@ -68,17 +68,17 @@ fun > R.add(controller: KClass, links: We } /** - * Provide a [LinkBuilder] DSL to help write idiomatic Kotlin code. + * Provide a [WebMvcLinkBuilder] DSL to help write idiomatic Kotlin code. * * @author Roland Kulcsár * @since 1.0 */ -open class WebMvcLinkBuilderDsl>(val controller: Class, val resource: R) { +open class WebMvcLinkBuilderDsl>(val controller: Class, val resource: R) { /** * Create a [WebMvcLinkBuilder] pointing to [func] method. */ - fun linkTo(func: C.() -> R): WebMvcLinkBuilder = linkTo(methodOn(controller).run(func)) + fun linkTo(func: C.() -> R & Any): WebMvcLinkBuilder = linkTo(methodOn(controller).run(func)) /** * Add a link with the given [rel] to the [resource]. diff --git a/src/test/java/org/springframework/hateoas/ArchitectureTest.java b/src/test/java/org/springframework/hateoas/ArchitectureTest.java index 30b56adb..786b9b33 100644 --- a/src/test/java/org/springframework/hateoas/ArchitectureTest.java +++ b/src/test/java/org/springframework/hateoas/ArchitectureTest.java @@ -24,7 +24,6 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; -import org.springframework.lang.Nullable; import com.tngtech.archunit.base.DescribedPredicate; import com.tngtech.archunit.core.domain.Dependency; @@ -35,6 +34,7 @@ import com.tngtech.archunit.core.importer.ImportOption; import com.tngtech.archunit.lang.syntax.ArchRuleDefinition; import com.tngtech.archunit.library.dependencies.SliceRule; import com.tngtech.archunit.library.dependencies.SlicesRuleDefinition; +import org.jspecify.annotations.Nullable; /** * Tests to verify certain architectural assumptions. diff --git a/src/test/java/org/springframework/hateoas/CollectionModelUnitTest.java b/src/test/java/org/springframework/hateoas/CollectionModelUnitTest.java index 27aadc0d..9445abca 100755 --- a/src/test/java/org/springframework/hateoas/CollectionModelUnitTest.java +++ b/src/test/java/org/springframework/hateoas/CollectionModelUnitTest.java @@ -18,6 +18,7 @@ package org.springframework.hateoas; import static org.assertj.core.api.Assertions.*; import lombok.Value; +import org.jspecify.annotations.Nullable; import java.util.Arrays; import java.util.Collections; @@ -28,7 +29,6 @@ import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.NamedExecutable; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; -import org.springframework.lang.Nullable; /** * Unit tests for {@link CollectionModel}. diff --git a/src/test/java/org/springframework/hateoas/config/EnableHypermediaSupportIntegrationTest.java b/src/test/java/org/springframework/hateoas/config/EnableHypermediaSupportIntegrationTest.java index b443964d..690d7d4e 100755 --- a/src/test/java/org/springframework/hateoas/config/EnableHypermediaSupportIntegrationTest.java +++ b/src/test/java/org/springframework/hateoas/config/EnableHypermediaSupportIntegrationTest.java @@ -57,7 +57,6 @@ import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.lang.Nullable; import org.springframework.mock.http.MockHttpOutputMessage; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.util.ReflectionUtils; @@ -70,6 +69,7 @@ import org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConv import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import com.fasterxml.jackson.core.JsonProcessingException; +import org.jspecify.annotations.Nullable; /** * Integration tests for {@link EnableHypermediaSupport}. diff --git a/src/test/java/org/springframework/hateoas/mediatype/hal/Jackson2HalIntegrationTest.java b/src/test/java/org/springframework/hateoas/mediatype/hal/Jackson2HalIntegrationTest.java index 8cf9edfd..f4a4f801 100755 --- a/src/test/java/org/springframework/hateoas/mediatype/hal/Jackson2HalIntegrationTest.java +++ b/src/test/java/org/springframework/hateoas/mediatype/hal/Jackson2HalIntegrationTest.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; +import org.jspecify.annotations.Nullable; import java.io.IOException; import java.util.ArrayList; @@ -53,7 +54,6 @@ import org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalHandlerIns import org.springframework.hateoas.server.core.AnnotationLinkRelationProvider; import org.springframework.hateoas.server.core.EmbeddedWrappers; import org.springframework.hateoas.server.core.Relation; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/src/test/java/org/springframework/hateoas/mediatype/hal/forms/Jackson2HalFormsIntegrationTest.java b/src/test/java/org/springframework/hateoas/mediatype/hal/forms/Jackson2HalFormsIntegrationTest.java index d8f7f6bb..ef8555f6 100644 --- a/src/test/java/org/springframework/hateoas/mediatype/hal/forms/Jackson2HalFormsIntegrationTest.java +++ b/src/test/java/org/springframework/hateoas/mediatype/hal/forms/Jackson2HalFormsIntegrationTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.*; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; import lombok.Getter; +import org.jspecify.annotations.Nullable; import java.io.IOException; import java.util.ArrayList; @@ -70,7 +71,6 @@ import org.springframework.hateoas.server.core.EmbeddedWrappers; import org.springframework.hateoas.support.EmployeeResource; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; diff --git a/src/test/java/org/springframework/hateoas/mediatype/uber/Jackson2UberIntegrationTest.java b/src/test/java/org/springframework/hateoas/mediatype/uber/Jackson2UberIntegrationTest.java index 8a3be15c..4d6cdeb0 100644 --- a/src/test/java/org/springframework/hateoas/mediatype/uber/Jackson2UberIntegrationTest.java +++ b/src/test/java/org/springframework/hateoas/mediatype/uber/Jackson2UberIntegrationTest.java @@ -27,6 +27,8 @@ import java.util.ArrayList; import java.util.List; import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.core.io.ClassPathResource; @@ -39,7 +41,6 @@ import org.springframework.hateoas.Links; import org.springframework.hateoas.PagedModel; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.support.MappingUtils; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.SerializationFeature; diff --git a/src/test/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderUnitTest.java b/src/test/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderUnitTest.java index d1da77c1..0b5df1a3 100644 --- a/src/test/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderUnitTest.java +++ b/src/test/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderUnitTest.java @@ -33,6 +33,8 @@ import java.util.Optional; import java.util.stream.Stream; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; +import org.jspecify.annotations.NonNull; + import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Named; import org.junit.jupiter.api.Test; @@ -51,7 +53,6 @@ import org.springframework.hateoas.server.core.MethodParameters; import org.springframework.hateoas.server.mvc.WebMvcLinkBuilderUnitTest.Sample.SampleConverter; import org.springframework.http.HttpEntity; import org.springframework.http.ResponseEntity; -import org.springframework.lang.NonNull; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.GetMapping; diff --git a/src/test/java/org/springframework/hateoas/server/reactive/WebFluxLinkBuilderTest.java b/src/test/java/org/springframework/hateoas/server/reactive/WebFluxLinkBuilderTest.java index b6814e63..f1d759b9 100644 --- a/src/test/java/org/springframework/hateoas/server/reactive/WebFluxLinkBuilderTest.java +++ b/src/test/java/org/springframework/hateoas/server/reactive/WebFluxLinkBuilderTest.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.*; import static org.springframework.hateoas.server.reactive.WebFluxLinkBuilder.*; import static org.springframework.web.filter.reactive.ServerWebExchangeContextFilter.*; +import org.jspecify.annotations.Nullable; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import reactor.util.context.Context; @@ -34,7 +35,6 @@ import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; import org.springframework.hateoas.server.reactive.WebFluxLinkBuilder.WebFluxLink; import org.springframework.http.HttpEntity; -import org.springframework.lang.Nullable; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/src/test/java/org/springframework/hateoas/support/ContextTester.java b/src/test/java/org/springframework/hateoas/support/ContextTester.java index 938e02e2..07311e11 100644 --- a/src/test/java/org/springframework/hateoas/support/ContextTester.java +++ b/src/test/java/org/springframework/hateoas/support/ContextTester.java @@ -15,9 +15,10 @@ */ package org.springframework.hateoas.support; +import org.jspecify.annotations.Nullable; + import java.util.function.Function; -import org.springframework.lang.Nullable; import org.springframework.mock.web.MockServletContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; diff --git a/src/test/java/org/springframework/hateoas/support/JsonPathUtils.java b/src/test/java/org/springframework/hateoas/support/JsonPathUtils.java index 70950b8d..004b2b13 100644 --- a/src/test/java/org/springframework/hateoas/support/JsonPathUtils.java +++ b/src/test/java/org/springframework/hateoas/support/JsonPathUtils.java @@ -19,7 +19,8 @@ import lombok.RequiredArgsConstructor; import org.assertj.core.matcher.AssertionMatcher; import org.hamcrest.Matcher; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; + import org.springframework.test.util.JsonPathExpectationsHelper; /** diff --git a/src/test/kotlin/org/springframework/hateoas/server/mvc/WebMvcAffordanceBuilderDslUnitTest.kt b/src/test/kotlin/org/springframework/hateoas/server/mvc/WebMvcAffordanceBuilderDslUnitTest.kt index c9c485bb..ed875041 100644 --- a/src/test/kotlin/org/springframework/hateoas/server/mvc/WebMvcAffordanceBuilderDslUnitTest.kt +++ b/src/test/kotlin/org/springframework/hateoas/server/mvc/WebMvcAffordanceBuilderDslUnitTest.kt @@ -39,7 +39,7 @@ class WebMvcAffordanceBuilderDslUnitTest : TestUtils() { val delete = afford { delete("15") } - val affordanceModel = delete.getAffordanceModel(MediaTypes.HAL_FORMS_JSON) + val affordanceModel = delete.getRequiredAffordanceModel(MediaTypes.HAL_FORMS_JSON) assertThat(affordanceModel.httpMethod).isEqualTo(HttpMethod.DELETE) assertThat(affordanceModel.name).isEqualTo("delete") @@ -62,14 +62,14 @@ class WebMvcAffordanceBuilderDslUnitTest : TestUtils() { assertThat(selfWithAffordances.href).isEqualTo("http://localhost/customers/15") assertThat(selfWithAffordances.affordances).hasSize(3) - assertThat(selfWithAffordances.affordances[0].getAffordanceModel(MediaTypes.HAL_FORMS_JSON).httpMethod).isEqualTo(HttpMethod.GET) - assertThat(selfWithAffordances.affordances[0].getAffordanceModel(MediaTypes.HAL_FORMS_JSON).name).isEqualTo("findById") + assertThat(selfWithAffordances.affordances[0].getRequiredAffordanceModel(MediaTypes.HAL_FORMS_JSON).httpMethod).isEqualTo(HttpMethod.GET) + assertThat(selfWithAffordances.affordances[0].getRequiredAffordanceModel(MediaTypes.HAL_FORMS_JSON).name).isEqualTo("findById") - assertThat(selfWithAffordances.affordances[1].getAffordanceModel(MediaTypes.HAL_FORMS_JSON).httpMethod).isEqualTo(HttpMethod.PUT) - assertThat(selfWithAffordances.affordances[1].getAffordanceModel(MediaTypes.HAL_FORMS_JSON).name).isEqualTo("update") + assertThat(selfWithAffordances.affordances[1].getRequiredAffordanceModel(MediaTypes.HAL_FORMS_JSON).httpMethod).isEqualTo(HttpMethod.PUT) + assertThat(selfWithAffordances.affordances[1].getRequiredAffordanceModel(MediaTypes.HAL_FORMS_JSON).name).isEqualTo("update") - assertThat(selfWithAffordances.affordances[2].getAffordanceModel(MediaTypes.HAL_FORMS_JSON).httpMethod).isEqualTo(HttpMethod.DELETE) - assertThat(selfWithAffordances.affordances[2].getAffordanceModel(MediaTypes.HAL_FORMS_JSON).name).isEqualTo("delete") + assertThat(selfWithAffordances.affordances[2].getRequiredAffordanceModel(MediaTypes.HAL_FORMS_JSON).httpMethod).isEqualTo(HttpMethod.DELETE) + assertThat(selfWithAffordances.affordances[2].getRequiredAffordanceModel(MediaTypes.HAL_FORMS_JSON).name).isEqualTo("delete") assertThat(selfWithAffordances.hashCode()).isNotEqualTo(self.hashCode()) assertThat(selfWithAffordances).isNotEqualTo(self)