From 4c17d54e9a8df4a55a4f482e71e2a4e1ac4fb411 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Fri, 27 Mar 2020 14:10:41 +0100 Subject: [PATCH] DATAREST-1499, DATAREST-1500 - Cleanups. Moved off Spring Framework deprecations for HttpMessageNotReadableException. This required some rearrangements of method signatures for types (hopefully) exclusively used by internal abstractions (some public, but not very friendly for user extension in the first place). Switched to consistent use of Pageable.unpaged() instead of null. Switched to the use of new factory methods in Spring HATEOAS. Some Java 8 based improvements in request handling to simplify the implementation code. Deprecation of code that got obsolete due to the use of the factory methods. Moved off some deprecations in Jackson APIs. Removed a couple of unused imports. General avoidance of common warnings. Suppression where needed. Removed dead code in configuration. --- .../PersistentEntitiesResourceMappings.java | 1 - .../rest/core/domain/OrderRepository.java | 3 +- ...ositoryMethodResourceMappingUnitTests.java | 1 - ...itoryEntityControllerIntegrationTests.java | 7 +-- .../AbstractRepositoryRestController.java | 8 ++-- .../data/rest/webmvc/ControllerUtils.java | 8 +++- .../rest/webmvc/PersistentEntityResource.java | 6 ++- .../webmvc/RepositoryEntityController.java | 29 ++++++------ ...RepositoryPropertyReferenceController.java | 3 +- .../webmvc/RepositorySearchController.java | 4 +- .../rest/webmvc/config/JsonPatchHandler.java | 6 ++- .../RepositoryRestMvcConfiguration.java | 19 -------- .../convert/UriListHttpMessageConverter.java | 45 +++++++------------ .../rest/webmvc/json/DomainObjectReader.java | 30 +++++++------ .../rest/webmvc/json/JacksonMetadata.java | 2 +- .../json/PersistentEntityJackson2Module.java | 4 +- ...estedLinkCollectingAssociationHandler.java | 6 +-- .../webmvc/support/DefaultedPageable.java | 38 ++++++++-------- .../data/rest/webmvc/support/ETag.java | 2 +- .../util/InputStreamHttpInputMessage.java | 44 ++++++++++++++++++ .../BasePathAwareHandlerMappingUnitTests.java | 4 +- .../PersistentEntityResourceUnitTests.java | 4 +- ...yPropertyReferenceControllerUnitTests.java | 4 +- ...positoryRestExceptionHandlerUnitTests.java | 3 +- ...RepositoryRestHandlerMappingUnitTests.java | 4 +- .../json/DomainObjectReaderUnitTests.java | 14 +++--- .../ProjectionJacksonIntegrationTests.java | 2 +- .../webmvc/mapping/AssociationsUnitTests.java | 1 + 28 files changed, 163 insertions(+), 139 deletions(-) create mode 100644 spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/util/InputStreamHttpInputMessage.java diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/PersistentEntitiesResourceMappings.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/PersistentEntitiesResourceMappings.java index a6ef045ea..5e5b262ae 100644 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/PersistentEntitiesResourceMappings.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/PersistentEntitiesResourceMappings.java @@ -16,7 +16,6 @@ package org.springframework.data.rest.core.mapping; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/OrderRepository.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/OrderRepository.java index 9c3d9a467..be170a77b 100644 --- a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/OrderRepository.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/OrderRepository.java @@ -30,7 +30,8 @@ public interface OrderRepository extends CrudRepository { * @see org.springframework.data.repository.CrudRepository#save(java.lang.Object) */ @Override - S save(S entity); + @SuppressWarnings("unchecked") + Order save(Order entity); /* * (non-Javadoc) diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/RepositoryMethodResourceMappingUnitTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/RepositoryMethodResourceMappingUnitTests.java index ba4268557..9ff0f16e2 100755 --- a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/RepositoryMethodResourceMappingUnitTests.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/RepositoryMethodResourceMappingUnitTests.java @@ -113,7 +113,6 @@ public class RepositoryMethodResourceMappingUnitTests { } @Test // DATAREST-467 - @SuppressWarnings("rawtypes") public void returnsDomainTypeAsProjectionSourceType() throws Exception { Method method = PersonRepository.class.getMethod("findByLastname", String.class); diff --git a/spring-data-rest-tests/spring-data-rest-tests-jpa/src/test/java/org/springframework/data/rest/webmvc/RepositoryEntityControllerIntegrationTests.java b/spring-data-rest-tests/spring-data-rest-tests-jpa/src/test/java/org/springframework/data/rest/webmvc/RepositoryEntityControllerIntegrationTests.java index 613eb5728..4286464db 100755 --- a/spring-data-rest-tests/spring-data-rest-tests-jpa/src/test/java/org/springframework/data/rest/webmvc/RepositoryEntityControllerIntegrationTests.java +++ b/spring-data-rest-tests/spring-data-rest-tests-jpa/src/test/java/org/springframework/data/rest/webmvc/RepositoryEntityControllerIntegrationTests.java @@ -25,10 +25,10 @@ import java.util.Optional; import org.junit.Test; import org.mockito.Mockito; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.data.domain.Pageable; import org.springframework.data.mapping.context.PersistentEntities; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.repository.support.RepositoryInvoker; @@ -116,13 +116,14 @@ public class RepositoryEntityControllerIntegrationTests extends AbstractControll @Test // DATAREST-330 public void exposesHeadForCollectionResourceIfExported() throws Exception { ResponseEntity entity = controller.headCollectionResource(getResourceInformation(Person.class), - new DefaultedPageable(null, false)); + new DefaultedPageable(Pageable.unpaged(), false)); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); } @Test(expected = ResourceNotFoundException.class) // DATAREST-330 public void doesNotExposeHeadForCollectionResourceIfNotExported() throws Exception { - controller.headCollectionResource(getResourceInformation(CreditCard.class), new DefaultedPageable(null, false)); + controller.headCollectionResource(getResourceInformation(CreditCard.class), + new DefaultedPageable(Pageable.unpaged(), false)); } @Test // DATAREST-330 diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java index 98c25cd35..2a60e951e 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java @@ -15,8 +15,6 @@ */ package org.springframework.data.rest.webmvc; -import static org.springframework.data.rest.webmvc.ControllerUtils.*; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -81,7 +79,7 @@ class AbstractRepositoryRestController { } else if (source instanceof Iterable) { return entitiesToResources((Iterable) source, assembler, domainType); } else { - return new CollectionModel(EMPTY_RESOURCE_LIST); + return CollectionModel.empty(); } } @@ -103,7 +101,7 @@ class AbstractRepositoryRestController { if (!entities.iterator().hasNext()) { List content = Arrays. asList(WRAPPERS.emptyCollectionOf(domainType)); - return new CollectionModel(content, getDefaultSelfLink()); + return CollectionModel.of(content, getDefaultSelfLink()); } List> resources = new ArrayList>(); @@ -112,7 +110,7 @@ class AbstractRepositoryRestController { resources.add(obj == null ? null : assembler.toModel(obj)); } - return new CollectionModel>(resources, getDefaultSelfLink()); + return CollectionModel.of(resources, getDefaultSelfLink()); } protected Link getDefaultSelfLink() { diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ControllerUtils.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ControllerUtils.java index 8433d1f08..bcb77492d 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ControllerUtils.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ControllerUtils.java @@ -18,6 +18,7 @@ package org.springframework.data.rest.webmvc; import java.util.Collections; import java.util.Optional; +import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.RepresentationModel; import org.springframework.http.HttpHeaders; @@ -31,7 +32,12 @@ import org.springframework.util.Assert; */ public class ControllerUtils { - public static final Iterable> EMPTY_RESOURCE_LIST = Collections.emptyList(); + /** + * Use {@link CollectionModel#empty()} instead. + * + * @deprecated since 3.3 + */ + @Deprecated public static final Iterable> EMPTY_RESOURCE_LIST = Collections.emptyList(); public static > ResponseEntity> toResponseEntity( HttpStatus status, HttpHeaders headers, Optional resource) { diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResource.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResource.java index 65b29c0d2..bcf6e144c 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResource.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResource.java @@ -24,10 +24,10 @@ import java.util.List; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentPropertyAccessor; +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; import org.springframework.hateoas.Links; -import org.springframework.hateoas.EntityModel; -import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.server.core.EmbeddedWrapper; import org.springframework.util.Assert; @@ -65,6 +65,7 @@ public class PersistentEntityResource extends EntityModel { * @param links must not be {@literal null}. * @param embeddeds can be {@literal null}. */ + @SuppressWarnings("deprecation") private PersistentEntityResource(PersistentEntity entity, Object content, Iterable links, Iterable embeddeds, boolean isNew, boolean nested) { @@ -205,6 +206,7 @@ public class PersistentEntityResource extends EntityModel { private static class NoLinksResources extends CollectionModel { + @SuppressWarnings("deprecation") public NoLinksResources(Iterable content) { super(content); } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java index 08c59f33a..56e7d1edc 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java @@ -19,7 +19,6 @@ import static org.springframework.http.HttpMethod.*; import java.io.Serializable; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Optional; @@ -199,16 +198,16 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem throw new ResourceNotFoundException(); } - Iterable results = pageable.getPageable() != null ? invoker.invokeFindAll(pageable.getPageable()) + Iterable results = pageable.getPageable() != null // + ? invoker.invokeFindAll(pageable.getPageable()) // : invoker.invokeFindAll(sort); ResourceMetadata metadata = resourceInformation.getResourceMetadata(); Optional baseLink = Optional.of(entityLinks.linkToPagedResource(resourceInformation.getDomainType(), pageable.isDefault() ? null : pageable.getPageable())); - CollectionModel result = toCollectionModel(results, assembler, metadata.getDomainType(), baseLink); - result.add(getCollectionResourceLinks(resourceInformation, pageable)); - return result; + return toCollectionModel(results, assembler, metadata.getDomainType(), baseLink) + .add(getCollectionResourceLinks(resourceInformation, pageable)); } private Links getCollectionResourceLinks(RootResourceInformation resourceInformation, DefaultedPageable pageable) { @@ -226,7 +225,6 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem } @ResponseBody - @SuppressWarnings({ "unchecked" }) @RequestMapping(value = BASE_MAPPING, method = RequestMethod.GET, produces = { "application/x-spring-data-compact+json", "text/uri-list" }) public CollectionModel getCollectionResourceCompact(@QuerydslPredicate RootResourceInformation resourceinformation, @@ -234,18 +232,17 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem throws ResourceNotFoundException, HttpRequestMethodNotSupportedException { CollectionModel resources = getCollectionResource(resourceinformation, pageable, sort, assembler); - Links links = resources.getLinks(); - for (EntityModel resource : ((CollectionModel>) resources).getContent()) { - PersistentEntityResource persistentEntityResource = (PersistentEntityResource) resource; - links = links.and(resourceLink(resourceinformation, persistentEntityResource)); - } + Links links = resources.getContent().stream() // + .map(PersistentEntityResource.class::cast) // + .map(it -> resourceLink(resourceinformation, it)) // + .reduce(resources.getLinks(), Links::and, Links::and); - if (resources instanceof PagedModel) { - return new PagedModel(Collections.emptyList(), ((PagedModel) resources).getMetadata(), links); - } else { - return new CollectionModel(Collections.emptyList(), links); - } + CollectionModel model = resources instanceof PagedModel // + ? PagedModel.empty(((PagedModel) resources).getMetadata()) // + : CollectionModel.empty(); + + return model.add(links); } /** diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java index 04da63309..eed60d59c 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java @@ -25,7 +25,6 @@ import lombok.RequiredArgsConstructor; import java.io.Serializable; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; @@ -252,7 +251,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro @RequestBody(required = false) CollectionModel incoming, @BackendId Serializable id, @PathVariable String property) throws Exception { - CollectionModel source = incoming == null ? new CollectionModel(Collections.emptyList()) : incoming; + CollectionModel source = incoming == null ? CollectionModel.empty() : incoming; RepositoryInvoker invoker = resourceInformation.getInvoker(); Function> handler = prop -> { diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java index 14965fccd..578899308 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java @@ -15,8 +15,6 @@ */ package org.springframework.data.rest.webmvc; -import static org.springframework.data.rest.webmvc.ControllerUtils.*; - import java.lang.reflect.Method; import java.net.URI; import java.net.URISyntaxException; @@ -266,7 +264,7 @@ class RepositorySearchController extends AbstractRepositoryRestController { links.add(resourceLink(resourceInformation, res)); } - return new CollectionModel>(EMPTY_RESOURCE_LIST, links); + return CollectionModel.empty(links); } /** diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/JsonPatchHandler.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/JsonPatchHandler.java index 14c2615c3..37e5b0950 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/JsonPatchHandler.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/JsonPatchHandler.java @@ -22,6 +22,7 @@ import org.springframework.data.rest.webmvc.RestMediaTypes; import org.springframework.data.rest.webmvc.json.DomainObjectReader; import org.springframework.data.rest.webmvc.json.patch.JsonPatchPatchConverter; import org.springframework.data.rest.webmvc.json.patch.Patch; +import org.springframework.data.rest.webmvc.util.InputStreamHttpInputMessage; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.util.Assert; @@ -95,7 +96,7 @@ class JsonPatchHandler { return reader.read(source, existingObject, mapper); } - T applyPut(ObjectNode source, T existingObject) { + T applyPut(ObjectNode source, T existingObject) throws Exception { return reader.readPut(source, existingObject, mapper); } @@ -112,7 +113,8 @@ class JsonPatchHandler { return new JsonPatchPatchConverter(mapper).convert(mapper.readTree(source)); } catch (Exception o_O) { throw new HttpMessageNotReadableException( - String.format("Could not read PATCH operations! Expected %s!", RestMediaTypes.JSON_PATCH_JSON), o_O); + String.format("Could not read PATCH operations! Expected %s!", RestMediaTypes.JSON_PATCH_JSON), o_O, + InputStreamHttpInputMessage.of(source)); } } } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java index 604e9b508..97842b16f 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java @@ -15,7 +15,6 @@ */ package org.springframework.data.rest.webmvc.config; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -23,7 +22,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Properties; import java.util.Set; import org.springframework.beans.factory.BeanClassLoaderAware; @@ -33,7 +31,6 @@ import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -43,7 +40,6 @@ import org.springframework.context.annotation.Import; import org.springframework.context.annotation.ImportResource; import org.springframework.core.Ordered; import org.springframework.core.convert.ConversionService; -import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.data.auditing.AuditableBeanWrapperFactory; import org.springframework.data.auditing.MappingAuditableBeanWrapperFactory; @@ -410,21 +406,6 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon new ValueTypeSchemaPropertyCustomizerFactory(repositoryInvokerFactory(defaultConversionService()))); } - private final Properties lookupDefaultMessages() { - - try { - - PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); - propertiesFactoryBean.setLocation(new ClassPathResource("rest-default-messages.properties")); - propertiesFactoryBean.afterPropertiesSet(); - - return propertiesFactoryBean.getObject(); - - } catch (IOException o_O) { - throw new IllegalStateException("Unable to resolve default rest-default-messages.properties!", o_O); - } - } - /** * The Jackson {@link ObjectMapper} used internally. * diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/convert/UriListHttpMessageConverter.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/convert/UriListHttpMessageConverter.java index 68a255f66..4e4fd8c15 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/convert/UriListHttpMessageConverter.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/convert/UriListHttpMessageConverter.java @@ -15,25 +15,25 @@ */ package org.springframework.data.rest.webmvc.convert; +import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; +import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Scanner; import org.springframework.core.convert.converter.Converter; -import org.springframework.hateoas.Link; -import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.Links; +import org.springframework.hateoas.RepresentationModel; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotWritableException; -import org.springframework.util.StringUtils; /** * {@link Converter} to render all {@link Link}s contained in a {@link ResourceSupport} as {@code text/uri-list} and @@ -43,7 +43,7 @@ import org.springframework.util.StringUtils; * @author Greg Turnquist * @author Oliver Gierke */ -public class UriListHttpMessageConverter implements HttpMessageConverter { +public class UriListHttpMessageConverter implements HttpMessageConverter> { private static final List MEDIA_TYPES = new ArrayList(); @@ -57,10 +57,10 @@ public class UriListHttpMessageConverter implements HttpMessageConverter clazz, MediaType mediaType) { - if (null == mediaType) { - return false; - } - return RepresentationModel.class.isAssignableFrom(clazz) && mediaType.getSubtype().contains("uri-list"); + + return null != mediaType // + && RepresentationModel.class.isAssignableFrom(clazz) // + && mediaType.getSubtype().contains("uri-list"); } /* @@ -86,28 +86,17 @@ public class UriListHttpMessageConverter implements HttpMessageConverter clazz, HttpInputMessage inputMessage) + public RepresentationModel read(Class> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { - List links = new ArrayList(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputMessage.getBody()))) { - Scanner scanner = new Scanner(inputMessage.getBody()); + Links links = reader.lines() // + .map(Link::of) // + .reduce(Links.NONE, Links::and, Links::and); - try { - - while (scanner.hasNextLine()) { - - String line = scanner.nextLine(); - if (StringUtils.hasText(line)) { - links.add(Link.of(line)); - } - } - - } finally { - scanner.close(); + return CollectionModel.empty(links); } - - return new CollectionModel(Collections.emptyList(), links); } /* @@ -115,7 +104,7 @@ public class UriListHttpMessageConverter implements HttpMessageConverter resource, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputMessage.getBody())); diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java index 62c65efd8..e46614e60 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java @@ -42,6 +42,7 @@ import org.springframework.data.mapping.SimplePropertyHandler; import org.springframework.data.mapping.context.PersistentEntities; import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import org.springframework.data.rest.webmvc.mapping.Associations; +import org.springframework.data.rest.webmvc.util.InputStreamHttpInputMessage; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.http.converter.HttpMessageNotReadableException; @@ -88,7 +89,7 @@ public class DomainObjectReader { try { return doMerge((ObjectNode) mapper.readTree(source), target, mapper); } catch (Exception o_O) { - throw new HttpMessageNotReadableException("Could not read payload!", o_O); + throw new HttpMessageNotReadableException("Could not read payload!", o_O, InputStreamHttpInputMessage.of(source)); } } @@ -101,24 +102,14 @@ public class DomainObjectReader { * @return */ @SuppressWarnings("unchecked") - public T readPut(final ObjectNode source, T target, final ObjectMapper mapper) { + public T readPut(final ObjectNode source, T target, final ObjectMapper mapper) throws Exception { Assert.notNull(source, "ObjectNode must not be null!"); Assert.notNull(target, "Existing object instance must not be null!"); Assert.notNull(mapper, "ObjectMapper must not be null!"); - Class type = target.getClass(); - - entities.getRequiredPersistentEntity(type); - - try { - - Object intermediate = mapper.readerFor(target.getClass()).readValue(source); - return (T) mergeForPut(intermediate, target, mapper); - - } catch (Exception o_O) { - throw new HttpMessageNotReadableException("Could not read payload!", o_O); - } + Object intermediate = mapper.readerFor(target.getClass()).readValue(source); + return (T) mergeForPut(intermediate, target, mapper); } /** @@ -186,6 +177,17 @@ public class DomainObjectReader { } } + /** + * Only for internal use. To be removed in 3.4. + * + * @param + * @param source + * @param target + * @param mapper + * @return + * @deprecated + */ + @Deprecated public T merge(ObjectNode source, T target, ObjectMapper mapper) { try { diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/JacksonMetadata.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/JacksonMetadata.java index 67c796b52..dfd1734ba 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/JacksonMetadata.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/JacksonMetadata.java @@ -69,7 +69,7 @@ public class JacksonMetadata implements Iterable { BeanDescription description = serializationConfig.introspect(javaType); this.definitions = description.findProperties(); - this.isValue = description.findJsonValueMethod() != null; + this.isValue = description.findJsonValueAccessor() != null; DeserializationConfig deserializationConfig = mapper.getDeserializationConfig(); JavaType deserializationType = deserializationConfig.constructType(type); diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java index 0c530032e..a02d63439 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java @@ -195,6 +195,7 @@ public class PersistentEntityJackson2Module extends SimpleModule { return; } + @SuppressWarnings("deprecation") EntityModel resourceToRender = new EntityModel(resource.getContent(), links) { @JsonUnwrapped @@ -689,7 +690,7 @@ public class PersistentEntityJackson2Module extends SimpleModule { ResourceMetadata metadata = associations.getMetadataFor(value.getTargetClass()); Links links = metadata.isExported() ? collector.getLinksFor(target) : Links.NONE; - EntityModel resource = invoker.invokeProcessorsFor(new EntityModel(value, links)); + EntityModel resource = invoker.invokeProcessorsFor(EntityModel.of(value, links)); return new ProjectionResource(resource.getContent(), resource.getLinks()); } @@ -697,6 +698,7 @@ public class PersistentEntityJackson2Module extends SimpleModule { static class ProjectionResource extends EntityModel { + @SuppressWarnings("deprecation") ProjectionResource(TargetAware projection, Iterable links) { super(new ProjectionResourceContent(projection, projection.getClass().getInterfaces()[0]), links); } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/mapping/NestedLinkCollectingAssociationHandler.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/mapping/NestedLinkCollectingAssociationHandler.java index ecdbfe69b..df3e9b770 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/mapping/NestedLinkCollectingAssociationHandler.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/mapping/NestedLinkCollectingAssociationHandler.java @@ -32,8 +32,8 @@ import org.springframework.data.mapping.context.PersistentEntities; import org.springframework.data.rest.core.mapping.ResourceMapping; import org.springframework.data.rest.core.mapping.ResourceMappings; import org.springframework.data.rest.core.mapping.ResourceMetadata; -import org.springframework.hateoas.server.EntityLinks; import org.springframework.hateoas.Link; +import org.springframework.hateoas.server.EntityLinks; /** * @author Oliver Gierke @@ -43,7 +43,7 @@ public class NestedLinkCollectingAssociationHandler implements SimpleAssociation private final EntityLinks entityLinks; private final PersistentEntities entities; - private final PersistentPropertyAccessor accessor; + private final PersistentPropertyAccessor accessor; private final ResourceMappings mappings; private final @Getter List links = new ArrayList(); @@ -70,10 +70,10 @@ public class NestedLinkCollectingAssociationHandler implements SimpleAssociation links.add(entityLinks.linkForItemResource(element.getClass(), identifierAccessor.getIdentifier()) .withRel(propertyMapping.getRel())); - } } else { + PersistentEntity entity = entities.getRequiredPersistentEntity(propertyValue.getClass()); IdentifierAccessor identifierAccessor = entity.getIdentifierAccessor(propertyValue); diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/DefaultedPageable.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/DefaultedPageable.java index 932118712..7e9ea33fe 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/DefaultedPageable.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/DefaultedPageable.java @@ -15,38 +15,28 @@ */ package org.springframework.data.rest.webmvc.support; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NonNull; +import lombok.Value; + import org.springframework.data.domain.Pageable; /** - * Value object to capture a {@link Pageable} as well it is the default one configured. + * Value object to capture a {@link Pageable} as well whether it is the default one configured. * * @author Oliver Gierke */ +@Value public class DefaultedPageable { - private final Pageable pageable; - private final boolean isDefault; - - /** - * Creates a new {@link DefaultedPageable} with the given {@link Pageable} and default flag. - * - * @param pageable can be {@literal null}. - * @param isDefault - */ - public DefaultedPageable(Pageable pageable, boolean isDefault) { - - this.pageable = pageable; - this.isDefault = isDefault; - } - /** * Returns the delegate {@link Pageable}. * * @return can be {@literal null}. */ - public Pageable getPageable() { - return pageable; - } + private final @NonNull Pageable pageable; + private final @Getter(value = AccessLevel.NONE) boolean isDefault; /** * Returns whether the contained {@link Pageable} is the default one configured. @@ -56,4 +46,14 @@ public class DefaultedPageable { public boolean isDefault() { return isDefault; } + + /** + * Returns {@link Pageable#unpaged()} if the contained {@link Pageable} is the default one. + * + * @return will never be {@literal null}. + * @since 3.3 + */ + public Pageable unpagedIfDefault() { + return isDefault ? Pageable.unpaged() : pageable; + } } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/ETag.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/ETag.java index a3d219e2f..53571b258 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/ETag.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/ETag.java @@ -167,7 +167,7 @@ public final class ETag { Assert.notNull(entity, "PersistentEntity must not be null!"); Assert.notNull(bean, "Target bean must not be null!"); - PersistentPropertyAccessor accessor = entity.getPropertyAccessor(bean); + PersistentPropertyAccessor accessor = entity.getPropertyAccessor(bean); return Optional.ofNullable(entity.getVersionProperty())// .map(it -> accessor.getProperty(it))// diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/util/InputStreamHttpInputMessage.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/util/InputStreamHttpInputMessage.java new file mode 100644 index 000000000..883dd7679 --- /dev/null +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/util/InputStreamHttpInputMessage.java @@ -0,0 +1,44 @@ +/* + * Copyright 2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.webmvc.util; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.io.InputStream; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpInputMessage; + +/** + * {@link HttpInputMessage} based on a plain {@link InputStream}, i.e. exposing no headers. + * + * @author Oliver Drotbohm + */ +@RequiredArgsConstructor(staticName = "of") +public class InputStreamHttpInputMessage implements HttpInputMessage { + + private final @Getter InputStream body; + + /* + * (non-Javadoc) + * @see org.springframework.http.HttpMessage#getHeaders() + */ + @Override + public HttpHeaders getHeaders() { + return HttpHeaders.EMPTY; + } +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMappingUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMappingUnitTests.java index 549653f92..bbca84fda 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMappingUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMappingUnitTests.java @@ -20,8 +20,8 @@ import static org.mockito.Mockito.*; import org.junit.Test; import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.support.AopUtils; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; -import org.springframework.util.ClassUtils; /** * Unit tests for {@link BasePathAwareHandlerMapping}. @@ -54,7 +54,7 @@ public class BasePathAwareHandlerMappingUnitTests { ProxyFactory factory = new ProxyFactory(source); Object proxy = factory.getProxy(); - assertThat(ClassUtils.isCglibProxy(proxy)).isTrue(); + assertThat(AopUtils.isCglibProxy(proxy)).isTrue(); return proxy.getClass(); } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/PersistentEntityResourceUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/PersistentEntityResourceUnitTests.java index 62b4c9fc6..d04e7d9a0 100755 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/PersistentEntityResourceUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/PersistentEntityResourceUnitTests.java @@ -25,9 +25,9 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.data.mapping.PersistentEntity; +import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkRelation; -import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.server.core.EmbeddedWrapper; import org.springframework.hateoas.server.core.EmbeddedWrappers; @@ -50,7 +50,7 @@ public class PersistentEntityResourceUnitTests { EmbeddedWrappers wrappers = new EmbeddedWrappers(false); EmbeddedWrapper wrapper = wrappers.wrap("Embedded", LinkRelation.of("foo")); - this.resources = new CollectionModel(Collections.singleton(wrapper)); + this.resources = CollectionModel.of(Collections.singleton(wrapper)); } @Test(expected = IllegalArgumentException.class) // DATAREST-317 diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceControllerUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceControllerUnitTests.java index 25279dd6d..7303c9e5d 100755 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceControllerUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceControllerUnitTests.java @@ -44,8 +44,8 @@ import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.data.rest.core.mapping.ResourceType; import org.springframework.data.rest.core.mapping.SupportedHttpMethods; import org.springframework.data.web.PagedResourcesAssembler; -import org.springframework.hateoas.Link; import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.Link; import org.springframework.http.HttpMethod; /** @@ -84,7 +84,7 @@ public class RepositoryPropertyReferenceControllerUnitTests { doReturn(new Sample()).when(invoker).invokeSave(any(Object.class)); RootResourceInformation information = new RootResourceInformation(metadata, entity, invoker); - CollectionModel request = new CollectionModel(Collections.emptySet(), Link.of("/reference/some-id")); + CollectionModel request = CollectionModel.empty(Link.of("/reference/some-id")); controller.createPropertyReference(information, HttpMethod.POST, request, 4711, "references"); diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestExceptionHandlerUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestExceptionHandlerUnitTests.java index ae7643981..cf3147036 100755 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestExceptionHandlerUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestExceptionHandlerUnitTests.java @@ -30,6 +30,7 @@ import org.springframework.data.rest.webmvc.support.ExceptionMessage; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.mock.http.MockHttpInputMessage; /** * Unit tests for {@link RepositoryRestExceptionHandler}. @@ -60,7 +61,7 @@ public class RepositoryRestExceptionHandlerUnitTests { public void handlesHttpMessageNotReadableException() { ResponseEntity result = HANDLER - .handleNotReadable(new HttpMessageNotReadableException("Message!")); + .handleNotReadable(new HttpMessageNotReadableException("Message!", new MockHttpInputMessage(new byte[0]))); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingUnitTests.java index b4fdffb6f..27cac021f 100755 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingUnitTests.java @@ -27,6 +27,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.support.AopUtils; import org.springframework.data.domain.Sort; import org.springframework.data.repository.support.Repositories; import org.springframework.data.rest.core.Path; @@ -41,7 +42,6 @@ import org.springframework.data.rest.webmvc.support.DefaultedPageable; import org.springframework.http.HttpHeaders; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockServletContext; -import org.springframework.util.ClassUtils; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.method.HandlerMethod; import org.springframework.web.util.pattern.PathPattern; @@ -308,7 +308,7 @@ public class RepositoryRestHandlerMappingUnitTests { ProxyFactory factory = new ProxyFactory(source); Object proxy = factory.getProxy(); - assertThat(ClassUtils.isCglibProxy(proxy)).isTrue(); + assertThat(AopUtils.isCglibProxy(proxy)).isTrue(); return proxy.getClass(); } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/DomainObjectReaderUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/DomainObjectReaderUnitTests.java index 7d592a46e..1d59b25fa 100755 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/DomainObjectReaderUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/DomainObjectReaderUnitTests.java @@ -36,7 +36,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentMatchers; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; - import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Immutable; @@ -59,6 +58,7 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; @@ -172,7 +172,7 @@ public class DomainObjectReaderUnitTests { assertThat(((Map) object).get("c")).isEqualTo("2"); } - @Test(expected = IllegalArgumentException.class) // DATAREST-701 + @Test(expected = JsonMappingException.class) // DATAREST-701 public void rejectsMergingUnknownDomainObject() throws Exception { ObjectMapper mapper = new ObjectMapper(); @@ -486,6 +486,7 @@ public class DomainObjectReaderUnitTests { ObjectMapper mapper = new ObjectMapper(); JsonNode node = mapper.readTree("{ \"enums\" : [ \"SECOND\", \"FIRST\" ] }"); + @SuppressWarnings("deprecation") CollectionOfEnumWithMethods result = reader.merge((ObjectNode) node, sample, mapper); assertThat(result.enums).containsExactly(SampleEnum.SECOND, SampleEnum.FIRST); @@ -568,18 +569,19 @@ public class DomainObjectReaderUnitTests { ObjectMapper mapper = new ObjectMapper(); ObjectNode source = (ObjectNode) mapper.readTree("{ \"lastLogin\" : null, \"email\" : \"bar@foo.com\"}"); + @SuppressWarnings("deprecation") SampleUser result = reader.merge(source, user, mapper); assertThat(result.lastLogin).isNotNull(); assertThat(result.email).isEqualTo("foo@bar.com"); } - + @Test // DATAREST-1068 public void arraysCanBeResizedDuringMerge() throws Exception { ObjectMapper mapper = new ObjectMapper(); - ArrayHolder target = new ArrayHolder(new String[] { }); + ArrayHolder target = new ArrayHolder(new String[] {}); JsonNode node = mapper.readTree("{ \"array\" : [ \"new\" ] }"); - + ArrayHolder updated = reader.doMerge((ObjectNode) node, target, mapper); assertThat(updated.array).containsExactly("new"); } @@ -807,7 +809,7 @@ public class DomainObjectReaderUnitTests { static class WithNullCollection { List strings; } - + // DATAREST-1068 @Value static class ArrayHolder { diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/ProjectionJacksonIntegrationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/ProjectionJacksonIntegrationTests.java index 7108c8544..a9d201fbe 100755 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/ProjectionJacksonIntegrationTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/ProjectionJacksonIntegrationTests.java @@ -77,7 +77,7 @@ public class ProjectionJacksonIntegrationTests { customer.address = new Address(); CustomerProjection projection = factory.createProjection(CustomerProjection.class, customer); - CollectionModel resources = new CollectionModel(Arrays.asList(projection)); + CollectionModel resources = CollectionModel.of(Arrays.asList(projection)); String result = mapper.writeValueAsString(resources); diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mapping/AssociationsUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mapping/AssociationsUnitTests.java index 0138e93c1..22657f9db 100755 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mapping/AssociationsUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mapping/AssociationsUnitTests.java @@ -147,6 +147,7 @@ public class AssociationsUnitTests { assertThat(links).contains(Link.of("/relatedAndExported{?" + projectionParameterName + "}", "relatedAndExported")); } + @SuppressWarnings({ "rawtypes", "unchecked" }) private Association> getAssociation(Class type, String name) { KeyValuePersistentEntity> rootEntity = mappingContext