DATAREST-302 - Rendering projections includes/keeps links.

We now treat embedded projections as Resource instances and equip them with a self link. This should also allow to register ResourceProcessor instances for projection types to even add projection specific links if necessary.

Also removed the explicit removal of the association link in case a projection is rendered for an association.
This commit is contained in:
Oliver Gierke
2015-04-02 16:03:32 +02:00
parent 3b55dceef7
commit 2697c6a2fa
5 changed files with 17 additions and 64 deletions

View File

@@ -95,29 +95,6 @@ public class PersistentEntityResource extends Resource<Object> {
return embeddeds;
}
/**
* Returns whether the given {@link Link} shall be rendered for the resource.
*
* @param link must not be {@literal null}.
* @return
*/
public boolean shouldRenderLink(Link link) {
Assert.notNull(link, "Link must not be null!");
if (enforceAssociationLinks) {
return true;
}
for (EmbeddedWrapper wrapper : embeddeds) {
if (wrapper.hasRel(link.getRel())) {
return false;
}
}
return true;
}
/**
* Creates a new {@link Builder} to create {@link PersistentEntityResource}s eventually.
*

View File

@@ -32,6 +32,7 @@ import org.springframework.data.rest.webmvc.mapping.AssociationLinks;
import org.springframework.data.rest.webmvc.support.Projector;
import org.springframework.hateoas.EntityLinks;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.ResourceAssembler;
import org.springframework.hateoas.core.EmbeddedWrapper;
import org.springframework.hateoas.core.EmbeddedWrappers;
@@ -164,14 +165,14 @@ public class PersistentEntityResourceAssembler implements ResourceAssembler<Obje
for (Object element : collection) {
if (element != null) {
nestedCollection.add(projector.projectExcerpt(element));
nestedCollection.add(getExcerptResource(element));
}
}
associationProjections.add(wrappers.wrap(nestedCollection, rel));
} else {
associationProjections.add(wrappers.wrap(projector.projectExcerpt(value), rel));
associationProjections.add(wrappers.wrap(getExcerptResource(value), rel));
}
}
});
@@ -202,4 +203,14 @@ public class PersistentEntityResourceAssembler implements ResourceAssembler<Obje
Link resourceLink = entityLinks.linkToSingleResource(entity.getType(), id);
return new Link(resourceLink.getHref(), Link.REL_SELF);
}
/**
* Returns a {@link Resource} instance for the excerpt of the given source entity.
*
* @param entity must not be {@literal null}.
* @return
*/
private Resource<Object> getExcerptResource(Object entity) {
return new Resource<Object>(projector.projectExcerpt(entity), getSelfLinkFor(entity));
}
}

View File

@@ -165,9 +165,7 @@ public class PersistentEntityJackson2Module extends SimpleModule {
resource.getPersistentEntity().doWithAssociations(associationHandler);
for (Link link : associationHandler.getLinks()) {
if (resource.shouldRenderLink(link)) {
links.add(link);
}
links.add(link);
}
Resource<Object> resourceToRender = new Resource<Object>(resource.getContent(), links) {

View File

@@ -80,38 +80,4 @@ public class PersistentEntityResourceUnitTests {
assertThat(resource.getEmbeddeds(), is(notNullValue()));
assertThat(resource.getEmbeddeds(), is(emptyIterable()));
}
/**
* @see DATAREST-317
*/
@Test
public void doesNotRenderAssociationLinksIfEmbeddedWithRelPresent() {
PersistentEntityResource resource = PersistentEntityResource.build(payload, entity).//
withEmbedded(resources).build();
assertThat(resource.shouldRenderLink(link), is(false));
}
/**
* @see DATAREST-317
*/
@Test
public void rendersAssociationLinksIfEvenIfEmbeddedWithRelPresentButLinksEnforced() {
PersistentEntityResource resource = PersistentEntityResource.build(payload, entity).//
withEmbedded(resources).renderAllAssociationLinks().build();
assertThat(resource.shouldRenderLink(link), is(true));
}
/**
* @see DATAREST-317
*/
@Test
public void rendersAssociationIfNoEmbeddedPresent() {
PersistentEntityResource resource = PersistentEntityResource.build(payload, entity).build();
assertThat(resource.shouldRenderLink(link), is(true));
}
}

View File

@@ -535,9 +535,10 @@ public class JpaWebTests extends CommonWebTests {
// Has main content
assertHasJsonPathValue(firstAuthorPath.concat(".name"), response);
// Embeddes content of related entity but no link to it
// Embeddes content of related entity, self link and keeps relation link
assertHasJsonPathValue(firstAuthorPath.concat("._embedded.books[0].title"), response);
assertJsonPathDoesntExist(firstAuthorPath.concat("._links.books"), response);
assertHasJsonPathValue(firstAuthorPath.concat("._embedded.books[0]._links.self"), response);
assertHasJsonPathValue(firstAuthorPath.concat("._links.books"), response);
// Access item resource and expect link to related resource present
String content = response.getContentAsString();