diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/MethodResourceMapping.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/MethodResourceMapping.java index 5a058a1d9..cb73ed8f4 100644 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/MethodResourceMapping.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/MethodResourceMapping.java @@ -50,7 +50,7 @@ public interface MethodResourceMapping extends ResourceMapping { /** * Returns the domain type that the query method returns. This will inspect wrapper types ({@link Collection}s, - * {@link Map}s, {@link Optional}s etc.) for their elemtn or value types. + * {@link Map}s, {@link Optional}s etc.) for their element or value types. * * @return will never be {@literal null}. * @since 2.3 diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/SearchResourceMappings.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/SearchResourceMappings.java index 046c709f9..d0adfd913 100644 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/SearchResourceMappings.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/SearchResourceMappings.java @@ -111,7 +111,28 @@ public class SearchResourceMappings implements Iterable, for (MethodResourceMapping mapping : this) { - if (mapping.isExported() && mapping.getRel().endsWith(rel)) { + if (mapping.isExported() && mapping.getRel().equals(rel)) { + return mapping; + } + } + + return null; + } + + /** + * Returns the {@link MethodResourceMapping} for the given path. + * + * @param path must not be {@literal null} or empty. + * @return + * @since 2.4 + */ + public MethodResourceMapping getExportedMethodMappingForPath(String path) { + + Assert.hasText(path, "Path must not be null or empty!"); + + for (MethodResourceMapping mapping : this) { + + if (mapping.isExported() && mapping.getPath().matches(path)) { return mapping; } } 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 4f919cda9..09ae30e4d 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 @@ -18,6 +18,7 @@ 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.Calendar; import java.util.List; @@ -32,9 +33,11 @@ import org.springframework.hateoas.Link; import org.springframework.hateoas.Resource; import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.Resources; +import org.springframework.hateoas.core.EmbeddedWrappers; import org.springframework.http.HttpHeaders; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; /** * @author Jon Brisbin @@ -44,6 +47,8 @@ import org.springframework.util.ClassUtils; @SuppressWarnings({ "rawtypes" }) class AbstractRepositoryRestController { + private static final EmbeddedWrappers WRAPPERS = new EmbeddedWrappers(false); + private final PagedResourcesAssembler pagedResourcesAssembler; private final AuditableBeanWrapperFactory auditableBeanWrapperFactory; @@ -75,13 +80,14 @@ class AbstractRepositoryRestController { } @SuppressWarnings({ "unchecked" }) - protected Resources toResources(Iterable source, PersistentEntityResourceAssembler assembler, Link baseLink) { + protected Resources toResources(Iterable source, PersistentEntityResourceAssembler assembler, + Class domainType, Link baseLink) { if (source instanceof Page) { Page page = (Page) source; - return entitiesToResources(page, assembler, baseLink); + return entitiesToResources(page, assembler, domainType, baseLink); } else if (source instanceof Iterable) { - return entitiesToResources((Iterable) source, assembler); + return entitiesToResources((Iterable) source, assembler, domainType); } else { return new Resources(EMPTY_RESOURCE_LIST); } @@ -93,13 +99,15 @@ class AbstractRepositoryRestController { * * @param source can be must not be {@literal null}. * @param assembler must not be {@literal null}. + * @param domainType the domain type in case the source is an empty iterable, must not be {@literal null}. * @param baseLink can be {@literal null}. * @return */ - protected Object toResource(Object source, PersistentEntityResourceAssembler assembler, Link baseLink) { + protected Object toResource(Object source, PersistentEntityResourceAssembler assembler, Class domainType, + Link baseLink) { if (source instanceof Iterable) { - return toResources((Iterable) source, assembler, baseLink); + return toResources((Iterable) source, assembler, domainType, baseLink); } else if (source == null) { throw new ResourceNotFoundException(); } else if (ClassUtils.isPrimitiveOrWrapper(source.getClass())) { @@ -109,14 +117,25 @@ class AbstractRepositoryRestController { return assembler.toFullResource(source); } - protected Resources> entitiesToResources(Page page, - PersistentEntityResourceAssembler assembler, Link baseLink) { + protected Resources entitiesToResources(Page page, PersistentEntityResourceAssembler assembler, + Class domainType, Link baseLink) { + + if (page.getContent().isEmpty()) { + return pagedResourcesAssembler.toEmptyResource(page, domainType, baseLink); + } + return baseLink == null ? pagedResourcesAssembler.toResource(page, assembler) : pagedResourcesAssembler.toResource( page, assembler, baseLink); } - protected Resources> entitiesToResources(Iterable entities, - PersistentEntityResourceAssembler assembler) { + protected Resources entitiesToResources(Iterable entities, PersistentEntityResourceAssembler assembler, + Class domainType) { + + if (!entities.iterator().hasNext()) { + + List content = Arrays. asList(WRAPPERS.emptyCollectionOf(domainType)); + return new Resources(content, getDefaultSelfLink()); + } List> resources = new ArrayList>(); @@ -124,7 +143,7 @@ class AbstractRepositoryRestController { resources.add(obj == null ? null : assembler.toResource(obj)); } - return new Resources>(resources); + return new Resources>(resources, getDefaultSelfLink()); } /** @@ -176,4 +195,8 @@ class AbstractRepositoryRestController { protected AuditableBeanWrapper getAuditableBeanWrapper(Object source) { return auditableBeanWrapperFactory.getBeanWrapperFor(source); } + + protected Link getDefaultSelfLink() { + return new Link(ServletUriComponentsBuilder.fromCurrentRequest().build().toUriString()); + } } 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 f526e23b8..f7522d186 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 @@ -170,9 +170,9 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem */ @ResponseBody @RequestMapping(value = BASE_MAPPING, method = RequestMethod.GET) - public Resources getCollectionResource(final RootResourceInformation resourceInformation, - DefaultedPageable pageable, Sort sort, PersistentEntityResourceAssembler assembler) - throws ResourceNotFoundException, HttpRequestMethodNotSupportedException { + public Resources getCollectionResource(RootResourceInformation resourceInformation, DefaultedPageable pageable, + Sort sort, PersistentEntityResourceAssembler assembler) throws ResourceNotFoundException, + HttpRequestMethodNotSupportedException { resourceInformation.verifySupportedMethod(HttpMethod.GET, ResourceType.COLLECTION); @@ -202,7 +202,7 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem Link baseLink = entityLinks.linkToPagedResource(resourceInformation.getDomainType(), pageable.isDefault() ? null : pageable.getPageable()); - Resources result = toResources(results, assembler, baseLink); + Resources result = toResources(results, assembler, metadata.getDomainType(), baseLink); result.add(links); return result; } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryLinksResource.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryLinksResource.java index 97c881943..b0b4f085c 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryLinksResource.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryLinksResource.java @@ -1,15 +1,26 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://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; -import java.util.Collections; - -import org.springframework.hateoas.Resources; +import org.springframework.hateoas.ResourceSupport; /** + * Dedicated resource type to represent the links pointing to collection resources exposed for repositories. + * * @author Jon Brisbin + * @author Oliver Gierke */ -public class RepositoryLinksResource extends Resources { - - public RepositoryLinksResource() { - super(Collections.emptyList()); - } -} +public class RepositoryLinksResource extends ResourceSupport {} 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 da85404e9..a06d37956 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 @@ -107,7 +107,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro @RequestMapping(value = BASE_MAPPING, method = RequestMethod.GET) public ResponseEntity followPropertyReference(final RootResourceInformation repoRequest, - @BackendId Serializable id, @PathVariable String property, final PersistentEntityResourceAssembler assembler) + @BackendId Serializable id, final @PathVariable String property, final PersistentEntityResourceAssembler assembler) throws Exception { final HttpHeaders headers = new HttpHeaders(); @@ -123,13 +123,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro if (prop.property.isCollectionLike()) { - List> resources = new ArrayList>(); - - for (Object obj : (Iterable) prop.propertyValue) { - resources.add(assembler.toResource(obj)); - } - - return new Resources>(resources); + return toResources((Iterable) prop.propertyValue, assembler, prop.propertyType, null); } else if (prop.property.isMap()) { 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 f2b0c5bb5..9c60e3681 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 @@ -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. @@ -31,12 +31,12 @@ import org.springframework.data.auditing.AuditableBeanWrapperFactory; import org.springframework.data.domain.Sort; import org.springframework.data.repository.query.Param; import org.springframework.data.repository.support.RepositoryInvoker; +import org.springframework.data.rest.core.mapping.MethodResourceMapping; import org.springframework.data.rest.core.mapping.ResourceMappings; import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.data.rest.core.mapping.SearchResourceMappings; import org.springframework.data.rest.webmvc.support.DefaultedPageable; import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks; -import org.springframework.data.web.HateoasSortHandlerMethodArgumentResolver; import org.springframework.data.web.PagedResourcesAssembler; import org.springframework.hateoas.EntityLinks; import org.springframework.hateoas.Link; @@ -74,8 +74,6 @@ class RepositorySearchController extends AbstractRepositoryRestController { private final RepositoryEntityLinks entityLinks; private final ResourceMappings mappings; - private final PagedResourcesAssembler assembler; - private final HateoasSortHandlerMethodArgumentResolver sortResolver; /** * Creates a new {@link RepositorySearchController} using the given {@link PagedResourcesAssembler}, @@ -84,22 +82,19 @@ class RepositorySearchController extends AbstractRepositoryRestController { * @param assembler must not be {@literal null}. * @param entityLinks must not be {@literal null}. * @param mappings must not be {@literal null}. + * @param auditableBeanWrapperFactory must not be {@literal null}. */ @Autowired public RepositorySearchController(PagedResourcesAssembler assembler, RepositoryEntityLinks entityLinks, - ResourceMappings mappings, HateoasSortHandlerMethodArgumentResolver sortResolver, - AuditableBeanWrapperFactory auditableBeanWrapperFactory) { + ResourceMappings mappings, AuditableBeanWrapperFactory auditableBeanWrapperFactory) { super(assembler, auditableBeanWrapperFactory); Assert.notNull(entityLinks, "EntityLinks must not be null!"); Assert.notNull(mappings, "ResourceMappings must not be null!"); - Assert.notNull(sortResolver, "HateoasSortHandlerMethodArgumentResolver must not be null!"); this.entityLinks = entityLinks; this.mappings = mappings; - this.assembler = assembler; - this.sortResolver = sortResolver; } /** @@ -155,6 +150,7 @@ class RepositorySearchController extends AbstractRepositoryRestController { RepositorySearchesResource result = new RepositorySearchesResource(resourceInformation.getDomainType()); result.add(queryMethodLinks); + result.add(getDefaultSelfLink()); return result; } @@ -180,7 +176,11 @@ class RepositorySearchController extends AbstractRepositoryRestController { Method method = checkExecutability(resourceInformation, search); Object result = executeQueryMethod(resourceInformation.getInvoker(), parameters, method, pageable, sort, assembler); - return new ResponseEntity(toResource(result, assembler, null), HttpStatus.OK); + SearchResourceMappings searchMappings = resourceInformation.getSearchMappings(); + MethodResourceMapping methodMapping = searchMappings.getExportedMethodMappingForPath(search); + Class domainType = methodMapping.getReturnedDomainType(); + + return new ResponseEntity(toResource(result, assembler, domainType, null), HttpStatus.OK); } /** @@ -189,7 +189,7 @@ class RepositorySearchController extends AbstractRepositoryRestController { * @param resourceInformation * @param parameters * @param repository - * @param searcg + * @param search * @param pageable * @param sort * @param assembler @@ -204,7 +204,8 @@ class RepositorySearchController extends AbstractRepositoryRestController { Method method = checkExecutability(resourceInformation, search); Object result = executeQueryMethod(resourceInformation.getInvoker(), parameters, method, pageable, sort, assembler); - Object resource = toResource(result, assembler, null); + ResourceMetadata metadata = resourceInformation.getResourceMetadata(); + Object resource = toResource(result, assembler, metadata.getDomainType(), null); List links = new ArrayList(); if (resource instanceof Resources && ((Resources) resource).getContent() != null) { diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandler.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandler.java index 210d4912e..c21cebfa6 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandler.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandler.java @@ -19,6 +19,7 @@ import static org.springframework.data.util.ClassTypeInformation.*; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -32,6 +33,7 @@ import org.springframework.hateoas.Resource; import org.springframework.hateoas.ResourceProcessor; import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.Resources; +import org.springframework.hateoas.core.EmbeddedWrapper; import org.springframework.hateoas.mvc.HeaderLinksResponseEntity; import org.springframework.http.HttpEntity; import org.springframework.http.ResponseEntity; @@ -292,7 +294,7 @@ public class ResourceProcessorHandlerMethodReturnValueHandler implements Handler */ @Override public boolean supports(TypeInformation typeInformation, Object value) { - return targetType.isAssignableFrom(typeInformation); + return targetType.getType().isAssignableFrom(typeInformation.getType()); } /* @@ -352,7 +354,7 @@ public class ResourceProcessorHandlerMethodReturnValueHandler implements Handler return false; } - return super.supports(typeInformation, value) || isValueTypeMatch((Resource) value, getTargetType()); + return super.supports(typeInformation, value) && isValueTypeMatch((Resource) value, getTargetType()); } /** @@ -408,7 +410,7 @@ public class ResourceProcessorHandlerMethodReturnValueHandler implements Handler return false; } - return super.supports(typeInformation, value) || isValueTypeMatch((Resources) value, getTargetType()); + return super.supports(typeInformation, value) && isValueTypeMatch((Resources) value, getTargetType()); } /** @@ -431,22 +433,31 @@ public class ResourceProcessorHandlerMethodReturnValueHandler implements Handler return false; } - Object element = content.iterator().next(); + TypeInformation superTypeInformation = null; - if (!(element instanceof Resource)) { - return false; + for (Class resourcesType : Arrays.> asList(resources.getClass(), Resources.class)) { + + superTypeInformation = target.getSuperTypeInformation(resourcesType); + + if (superTypeInformation != null) { + break; + } } - Class resourcesType = resources.getClass(); - - TypeInformation superTypeInformation = target.getSuperTypeInformation(resourcesType); - if (superTypeInformation == null) { return false; } + Object element = content.iterator().next(); TypeInformation resourceTypeInformation = superTypeInformation.getComponentType(); - return ResourceProcessorWrapper.isValueTypeMatch((Resource) element, resourceTypeInformation); + + if (element instanceof Resource) { + return ResourceProcessorWrapper.isValueTypeMatch((Resource) element, resourceTypeInformation); + } else if (element instanceof EmbeddedWrapper) { + return resourceTypeInformation.getType().isAssignableFrom(((EmbeddedWrapper) element).getRelTargetType()); + } + + return false; } } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/CommonWebTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/CommonWebTests.java index 0fbc6049f..7ecf83a29 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/CommonWebTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/CommonWebTests.java @@ -119,7 +119,7 @@ public abstract class CommonWebTests extends AbstractWebIntegrationTests { Link searchLink = client.getDiscoverer(response).findLinkWithRel("search", rootResourceRepresentation); if (searchLink != null) { - client.request(searchLink); + client.follow(searchLink).andExpect(client.hasLinkWithRel("self")); } } } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositorySearchControllerIntegrationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositorySearchControllerIntegrationTests.java index 436951aea..9e271cf06 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositorySearchControllerIntegrationTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositorySearchControllerIntegrationTests.java @@ -71,7 +71,7 @@ public class RepositorySearchControllerIntegrationTests extends AbstractControll ResourceSupport resource = controller.listSearches(request); ResourceTester tester = ResourceTester.of(resource); - tester.assertNumberOfLinks(5); + tester.assertNumberOfLinks(6); // Self link included tester.assertHasLinkEndingWith("findFirstPersonByFirstName", "findFirstPersonByFirstName{?firstname,projection}"); tester.assertHasLinkEndingWith("firstname", "firstname{?firstname,page,size,sort,projection}"); tester.assertHasLinkEndingWith("lastname", "lastname{?lastname,sort,projection}"); diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandlerUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandlerUnitTests.java index dfa83d96c..27148e87d 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandlerUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandlerUnitTests.java @@ -48,6 +48,7 @@ import org.springframework.hateoas.PagedResources.PageMetadata; import org.springframework.hateoas.Resource; import org.springframework.hateoas.ResourceProcessor; import org.springframework.hateoas.Resources; +import org.springframework.hateoas.core.EmbeddedWrappers; import org.springframework.hateoas.mvc.HeaderLinksResponseEntity; import org.springframework.http.HttpEntity; import org.springframework.http.HttpStatus; @@ -255,6 +256,23 @@ public class ResourceProcessorHandlerMethodReturnValueHandlerUnitTests { assertThat(ResourcesProcessorWrapper.isValueTypeMatch(pagedResources, type), is(false)); } + /** + * @see DATAREST-479 + */ + @Test + public void doesNotInvokeAProcessorForASpecializedType() throws Exception { + + EmbeddedWrappers wrappers = new EmbeddedWrappers(false); + Resources value = new Resources(Collections. singleton(wrappers + .emptyCollectionOf(Object.class))); + ResourcesProcessorWrapper wrapper = new ResourcesProcessorWrapper(new SpecialResourcesProcessor()); + + TypeInformation typeInformation = ClassTypeInformation.fromReturnTypeOf(Controller.class + .getMethod("resourcesOfObject")); + + assertThat(wrapper.supports(typeInformation, value), is(false)); + } + // Helpers ---------------------------------------------------------// private void invokeReturnValueHandler(String method, final Matcher matcher, Object returnValue) throws Exception { final MethodParameter methodParam = METHOD_PARAMS.get(method); @@ -353,6 +371,8 @@ public class ResourceProcessorHandlerMethodReturnValueHandlerUnitTests { ResponseEntity> resourceResponseEntity(); ResponseEntity> resourcesResponseEntity(); + + Resources resourcesOfObject(); } static class StringResource extends Resource { @@ -383,7 +403,23 @@ public class ResourceProcessorHandlerMethodReturnValueHandlerUnitTests { @Override public Resource process(Resource resource) { + this.invoked = true; + return resource; + } + } + static class SpecialResources extends Resources { + public SpecialResources() { + super(Collections.emptyList()); + } + } + + static class SpecialResourcesProcessor implements ResourceProcessor { + + boolean invoked = false; + + @Override + public SpecialResources process(SpecialResources resource) { this.invoked = true; return resource; } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/LegacyRepresentationConfigIntegrationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/LegacyRepresentationConfigIntegrationTests.java index 754ca0922..df4199314 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/LegacyRepresentationConfigIntegrationTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/LegacyRepresentationConfigIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 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. @@ -50,7 +50,7 @@ public class LegacyRepresentationConfigIntegrationTests extends AbstractReposito public void returnsJsonIfConfiguredAndRequested() throws Exception { mvc.perform(get("/").accept(MediaType.APPLICATION_JSON)). // - andExpect(jsonPath("content", is(notNullValue()))); + andExpect(jsonPath("links", is(notNullValue()))); } /** @@ -60,6 +60,6 @@ public class LegacyRepresentationConfigIntegrationTests extends AbstractReposito public void returnsJsonIfConfigured() throws Exception { mvc.perform(get("/").accept(MediaType.ALL)). // - andExpect(jsonPath("content", is(notNullValue()))); + andExpect(jsonPath("links", is(notNullValue()))); } } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java index 93e0e1cd3..eb78fdc00 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java @@ -576,11 +576,13 @@ public class JpaWebTests extends CommonWebTests { // Assert results returned as specified client.follow(findBySortedLink.expand("title,desc")).// andExpect(jsonPath("$._embedded.books[0].title").value("Spring Data (Second Edition)")).// - andExpect(jsonPath("$._embedded.books[1].title").value("Spring Data")); + andExpect(jsonPath("$._embedded.books[1].title").value("Spring Data")).// + andExpect(client.hasLinkWithRel("self")); client.follow(findBySortedLink.expand("title,asc")).// andExpect(jsonPath("$._embedded.books[0].title").value("Spring Data")).// - andExpect(jsonPath("$._embedded.books[1].title").value("Spring Data (Second Edition)")); + andExpect(jsonPath("$._embedded.books[1].title").value("Spring Data (Second Edition)")).// + andExpect(client.hasLinkWithRel("self")); } /**