From c5aaebd0e4adf6f4aae11e18cb4605a8d30f8bee Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Mon, 18 May 2015 16:19:14 +0200 Subject: [PATCH] DATACMNS-699 - PagedResourcesAssembler now allows to create empty Page with type information. --- .../data/web/PagedResourcesAssembler.java | 40 ++++++++++++++-- .../web/PagedResourcesAssemblerUnitTests.java | 46 +++++++++++++++---- 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java b/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java index 8beda1b78..fb7ac652f 100644 --- a/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java +++ b/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java @@ -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 implements ResourceAssembler, 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 implements ResourceAssembler, 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 embedded = Collections.singletonList(wrapper); + + return new PagedResources(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 implements ResourceAssembler, 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 pagedResources = new PagedResources(resources, asPageMetadata(page), selfLink); @@ -161,8 +189,12 @@ public class PagedResourcesAssembler implements ResourceAssembler, 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); } /** diff --git a/src/test/java/org/springframework/data/web/PagedResourcesAssemblerUnitTests.java b/src/test/java/org/springframework/data/web/PagedResourcesAssemblerUnitTests.java index 758d1a40a..4154633a2 100644 --- a/src/test/java/org/springframework/data/web/PagedResourcesAssemblerUnitTests.java +++ b/src/test/java/org/springframework/data/web/PagedResourcesAssemblerUnitTests.java @@ -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 EMPTY_PAGE = new PageImpl(Collections.emptyList()); + HateoasPageableHandlerMethodArgumentResolver resolver = new HateoasPageableHandlerMethodArgumentResolver(); + PagedResourcesAssembler assembler = new PagedResourcesAssembler(resolver, null); @Before public void setUp() { @@ -56,7 +60,6 @@ public class PagedResourcesAssemblerUnitTests { @Test public void addsNextLinkForFirstPage() { - PagedResourcesAssembler assembler = new PagedResourcesAssembler(resolver, null); PagedResources> 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 assembler = new PagedResourcesAssembler(resolver, null); PagedResources> 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 assembler = new PagedResourcesAssembler(resolver, null); PagedResources> 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 assembler = new PagedResourcesAssembler(resolver, null); PagedResources> 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 assembler = new PagedResourcesAssembler(resolver, null); AbstractPageRequest request = new PageRequest(0, 1); Page page = new PageImpl(Collections. emptyList(), request, 0); @@ -134,7 +133,6 @@ public class PagedResourcesAssemblerUnitTests { @Test public void createsACanonicalLinkWithoutTemplateParameters() { - PagedResourcesAssembler assembler = new PagedResourcesAssembler(resolver, null); PagedResources> resources = assembler.toResource(createPage(1)); Link selfLink = resources.getLink(Link.REL_SELF); @@ -147,7 +145,6 @@ public class PagedResourcesAssemblerUnitTests { @Test public void invokesCustomElementResourceAssembler() { - PagedResourcesAssembler assembler = new PagedResourcesAssembler(resolver, null); PersonResourceAssembler personAssembler = new PersonResourceAssembler(); PagedResources resources = assembler.toResource(createPage(0), personAssembler); @@ -184,7 +181,6 @@ public class PagedResourcesAssemblerUnitTests { @Test public void generatedLinksShouldNotBeTemplated() { - PagedResourcesAssembler assembler = new PagedResourcesAssembler(resolver, null); PagedResources> 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 createPage(int index) { AbstractPageRequest request = new PageRequest(index, 1);