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:
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user