DATACMNS-699 - PagedResourcesAssembler now allows to create empty Page with type information.

This commit is contained in:
Oliver Gierke
2015-05-18 16:19:14 +02:00
parent 65104a4a3a
commit c5aaebd0e4
2 changed files with 73 additions and 13 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2015 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.
@@ -18,6 +18,7 @@ package org.springframework.data.web;
import static org.springframework.web.util.UriComponentsBuilder.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.core.MethodParameter;
@@ -30,6 +31,8 @@ import org.springframework.hateoas.Resource;
import org.springframework.hateoas.ResourceAssembler;
import org.springframework.hateoas.ResourceSupport;
import org.springframework.hateoas.UriTemplate;
import org.springframework.hateoas.core.EmbeddedWrapper;
import org.springframework.hateoas.core.EmbeddedWrappers;
import org.springframework.util.Assert;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.UriComponents;
@@ -46,6 +49,7 @@ public class PagedResourcesAssembler<T> implements ResourceAssembler<Page<T>, Pa
private final HateoasPageableHandlerMethodArgumentResolver pageableResolver;
private final UriComponents baseUri;
private final EmbeddedWrappers wrappers = new EmbeddedWrappers(false);
/**
* Creates a new {@link PagedResourcesAssembler} using the given {@link PageableHandlerMethodArgumentResolver} and
@@ -112,6 +116,30 @@ public class PagedResourcesAssembler<T> implements ResourceAssembler<Page<T>, Pa
return createResource(page, assembler, link);
}
/**
* Creates a {@link PagedResources} with an empt collection {@link EmbeddedWrapper} for the given domain type.
*
* @param page must not be {@literal null}, content must be empty.
* @param type must not be {@literal null}.
* @param link can be {@literal null}.
* @return
* @since 1.11
*/
public PagedResources<?> toEmptyResource(Page<?> page, Class<?> type, Link link) {
Assert.notNull(page, "Page must must not be null!");
Assert.isTrue(!page.hasContent(), "Page must not have any content!");
Assert.notNull(type, "Type must not be null!");
PageMetadata metadata = asPageMetadata(page);
EmbeddedWrapper wrapper = wrappers.emptyCollectionOf(type);
List<EmbeddedWrapper> embedded = Collections.singletonList(wrapper);
return new PagedResources<EmbeddedWrapper>(embedded, metadata,
createLink(getUriTemplate(link), null, Link.REL_SELF));
}
/**
* Adds the pagination parameters for all parameters not already present in the given {@link Link}.
*
@@ -139,7 +167,7 @@ public class PagedResourcesAssembler<T> implements ResourceAssembler<Page<T>, Pa
resources.add(assembler.toResource(element));
}
UriTemplate base = new UriTemplate(link == null ? getDefaultUriString() : link.getHref());
UriTemplate base = getUriTemplate(link);
Link selfLink = createLink(base, null, Link.REL_SELF);
PagedResources<R> pagedResources = new PagedResources<R>(resources, asPageMetadata(page), selfLink);
@@ -161,8 +189,12 @@ public class PagedResourcesAssembler<T> implements ResourceAssembler<Page<T>, Pa
*
* @return
*/
private String getDefaultUriString() {
return baseUri == null ? ServletUriComponentsBuilder.fromCurrentRequest().build().toString() : baseUri.toString();
private UriTemplate getUriTemplate(Link baseLink) {
String href = baseLink != null ? baseLink.getHref() : baseUri == null ? ServletUriComponentsBuilder
.fromCurrentRequest().build().toString() : baseUri.toString();
return new UriTemplate(href);
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2015 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.
@@ -35,6 +35,7 @@ import org.springframework.hateoas.PagedResources;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.ResourceAssembler;
import org.springframework.hateoas.ResourceSupport;
import org.springframework.hateoas.core.EmbeddedWrapper;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
@@ -46,7 +47,10 @@ import org.springframework.web.util.UriComponentsBuilder;
*/
public class PagedResourcesAssemblerUnitTests {
static final Page<Object> EMPTY_PAGE = new PageImpl<Object>(Collections.emptyList());
HateoasPageableHandlerMethodArgumentResolver resolver = new HateoasPageableHandlerMethodArgumentResolver();
PagedResourcesAssembler<Person> assembler = new PagedResourcesAssembler<Person>(resolver, null);
@Before
public void setUp() {
@@ -56,7 +60,6 @@ public class PagedResourcesAssemblerUnitTests {
@Test
public void addsNextLinkForFirstPage() {
PagedResourcesAssembler<Person> assembler = new PagedResourcesAssembler<Person>(resolver, null);
PagedResources<Resource<Person>> resources = assembler.toResource(createPage(0));
assertThat(resources.getLink(Link.REL_PREVIOUS), is(nullValue()));
@@ -67,7 +70,6 @@ public class PagedResourcesAssemblerUnitTests {
@Test
public void addsPreviousAndNextLinksForMiddlePage() {
PagedResourcesAssembler<Person> assembler = new PagedResourcesAssembler<Person>(resolver, null);
PagedResources<Resource<Person>> resources = assembler.toResource(createPage(1));
assertThat(resources.getLink(Link.REL_PREVIOUS), is(notNullValue()));
@@ -78,7 +80,6 @@ public class PagedResourcesAssemblerUnitTests {
@Test
public void addsPreviousLinkForLastPage() {
PagedResourcesAssembler<Person> assembler = new PagedResourcesAssembler<Person>(resolver, null);
PagedResources<Resource<Person>> resources = assembler.toResource(createPage(2));
assertThat(resources.getLink(Link.REL_PREVIOUS), is(notNullValue()));
@@ -104,7 +105,6 @@ public class PagedResourcesAssemblerUnitTests {
Link link = new Link("http://foo:9090", "rel");
PagedResourcesAssembler<Person> assembler = new PagedResourcesAssembler<Person>(resolver, null);
PagedResources<Resource<Person>> resources = assembler.toResource(createPage(1), link);
assertThat(resources.getLink(Link.REL_PREVIOUS).getHref(), startsWith(link.getHref()));
@@ -119,7 +119,6 @@ public class PagedResourcesAssemblerUnitTests {
public void createsPagedResourcesForOneIndexedArgumentResolver() {
resolver.setOneIndexedParameters(true);
PagedResourcesAssembler<Person> assembler = new PagedResourcesAssembler<Person>(resolver, null);
AbstractPageRequest request = new PageRequest(0, 1);
Page<Person> page = new PageImpl<Person>(Collections.<Person> emptyList(), request, 0);
@@ -134,7 +133,6 @@ public class PagedResourcesAssemblerUnitTests {
@Test
public void createsACanonicalLinkWithoutTemplateParameters() {
PagedResourcesAssembler<Person> assembler = new PagedResourcesAssembler<Person>(resolver, null);
PagedResources<Resource<Person>> resources = assembler.toResource(createPage(1));
Link selfLink = resources.getLink(Link.REL_SELF);
@@ -147,7 +145,6 @@ public class PagedResourcesAssemblerUnitTests {
@Test
public void invokesCustomElementResourceAssembler() {
PagedResourcesAssembler<Person> assembler = new PagedResourcesAssembler<Person>(resolver, null);
PersonResourceAssembler personAssembler = new PersonResourceAssembler();
PagedResources<PersonResource> resources = assembler.toResource(createPage(0), personAssembler);
@@ -184,7 +181,6 @@ public class PagedResourcesAssemblerUnitTests {
@Test
public void generatedLinksShouldNotBeTemplated() {
PagedResourcesAssembler<Person> assembler = new PagedResourcesAssembler<Person>(resolver, null);
PagedResources<Resource<Person>> resources = assembler.toResource(createPage(1));
assertThat(resources.getLink(Link.REL_SELF).getHref(), endsWith("localhost"));
@@ -192,6 +188,38 @@ public class PagedResourcesAssemblerUnitTests {
assertThat(resources.getLink(Link.REL_PREVIOUS).getHref(), endsWith("?page=0&size=1"));
}
/**
* @see DATACMNS-699
*/
@Test
public void generatesEmptyPagedResourceWithEmbeddedWrapper() {
PagedResources<?> result = assembler.toEmptyResource(EMPTY_PAGE, Person.class, null);
Collection<?> content = result.getContent();
assertThat(content, hasSize(1));
Object element = content.iterator().next();
assertThat(element, is(instanceOf(EmbeddedWrapper.class)));
assertThat(((EmbeddedWrapper) element).getRelTargetType(), is(typeCompatibleWith(Person.class)));
}
/**
* @see DATACMNS-699
*/
@Test(expected = IllegalArgumentException.class)
public void emptyPageCreatorRejectsPageWithContent() {
assembler.toEmptyResource(createPage(1), Person.class, null);
}
/**
* @see DATACMNS-699
*/
@Test(expected = IllegalArgumentException.class)
public void emptyPageCreatorRejectsNullType() {
assembler.toEmptyResource(EMPTY_PAGE, null, null);
}
private static Page<Person> createPage(int index) {
AbstractPageRequest request = new PageRequest(index, 1);