DATAREST-521 - Re-added accidentally dropped existing links.

The LinkCollector introduced in previous commits accidentally dropped links already existing on the Resource.
This commit is contained in:
Oliver Gierke
2015-04-19 12:21:45 +02:00
parent 9bba615d79
commit cd82411169
3 changed files with 72 additions and 18 deletions

View File

@@ -594,27 +594,53 @@ public class PersistentEntityJackson2Module extends SimpleModule {
PersistentEntity<?, ?> entity = entities.getPersistentEntity(object.getClass());
Link selfLink = getSelfLink(object, entity, new Links(existingLinks));
Links links = new Links(existingLinks);
Link selfLink = createSelfLink(object, entity, links);
if (selfLink == null) {
return links;
}
Path path = new Path(selfLink.expand().getHref());
LinkCollectingAssociationHandler handler = new LinkCollectingAssociationHandler(entities, path, associationLinks);
entity.doWithAssociations(handler);
List<Link> result = new ArrayList<Link>();
result.add(getSelfLink(object, entity, new Links(existingLinks)));
List<Link> result = new ArrayList<Link>(existingLinks);
result.addAll(handler.getLinks());
return new Links(result);
return addSelfLinkIfNecessary(object, entity, result);
}
private Link getSelfLink(Object object, PersistentEntity<?, ?> entity, Links existing) {
private Links addSelfLinkIfNecessary(Object object, PersistentEntity<?, ?> entity, List<Link> existing) {
Links result = new Links(existing);
if (result.hasLink(Link.REL_SELF)) {
return result;
}
List<Link> list = new ArrayList<Link>();
list.add(createSelfLink(object, entity, result));
list.addAll(existing);
return new Links(list);
}
private Link createSelfLink(Object object, PersistentEntity<?, ?> entity, Links existing) {
if (existing.hasLink(Link.REL_SELF)) {
return existing.getLink(Link.REL_SELF);
}
IdentifierAccessor accessor = entity.getIdentifierAccessor(object);
return links.linkToSingleResource(entity.getType(), accessor.getIdentifier()).withSelfRel();
Object identifier = accessor.getIdentifier();
if (identifier == null) {
return null;
}
return links.linkToSingleResource(entity.getType(), identifier).withSelfRel();
}
}

View File

@@ -48,13 +48,15 @@ import org.springframework.hateoas.PagedResources.PageMetadata;
import org.springframework.hateoas.core.EmbeddedWrapper;
import org.springframework.hateoas.core.EmbeddedWrappers;
import org.springframework.hateoas.hal.HalLinkDiscoverer;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.util.UriTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.jayway.jsonpath.JsonPath;
/**
@@ -82,6 +84,8 @@ public class PersistentEntitySerializationTests {
@Before
public void setUp() {
RequestContextHolder.setRequestAttributes(new ServletWebRequest(new MockHttpServletRequest()));
this.linkDiscoverer = new HalLinkDiscoverer();
this.projectionFactory = new SpelAwareProxyProjectionFactory();
}
@@ -234,9 +238,11 @@ public class PersistentEntitySerializationTests {
@Test
public void serializesLinksForExcerpts() throws Exception {
Person oliver = new Person("Oliver August", "Matthews");
Person dave = new Person("Dave", "Matthews");
dave.setId(1L);
Person oliver = new Person("Oliver August", "Matthews");
oliver.setId(2L);
oliver.setFather(dave);
UserExcerpt daveExcerpt = projectionFactory.createProjection(UserExcerpt.class, dave);
@@ -248,9 +254,27 @@ public class PersistentEntitySerializationTests {
withEmbedded(Arrays.asList(wrapper)).//
build();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
String result = mapper.writeValueAsString(resource);
assertThat(JsonPath.read(result, "$_embedded.father[*]._links.self"), is(notNullValue()));
}
/**
* @see DATAREST-521
*/
@Test
public void rendersAdditionalLinksRegisteredWithResource() throws Exception {
Person dave = new Person("Dave", "Matthews");
PersistentEntityResource resource = PersistentEntityResource.//
build(dave, repositories.getPersistentEntity(Person.class)).//
withLink(new Link("/people/1")).//
withLink(new Link("/aditional", "processed")).//
build();
String result = mapper.writeValueAsString(resource);
assertThat(JsonPath.read(result, "$_links.processed"), is(notNullValue()));
}
}

View File

@@ -15,13 +15,12 @@
*/
package org.springframework.data.rest.webmvc.json;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.mockito.Matchers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -38,13 +37,17 @@ import org.springframework.data.rest.webmvc.jpa.JpaRepositoryConfig;
import org.springframework.data.rest.webmvc.jpa.Person;
import org.springframework.data.rest.webmvc.jpa.PersonRepository;
import org.springframework.data.rest.webmvc.mongodb.MongoDbRepositoryConfig;
import org.springframework.data.rest.webmvc.spi.BackendIdConverter;
import org.springframework.data.rest.webmvc.spi.BackendIdConverter.DefaultIdConverter;
import org.springframework.data.rest.webmvc.support.PagingAndSortingTemplateVariables;
import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.hateoas.EntityLinks;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.RelProvider;
import org.springframework.hateoas.core.EvoInflectorRelProvider;
import org.springframework.hateoas.hal.Jackson2HalModule;
import org.springframework.plugin.core.OrderAwarePluginRegistry;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
@@ -101,12 +104,13 @@ public class RepositoryTestsConfig {
@Bean
public Module persistentEntityModule() {
EntityLinks entityLinks = mock(EntityLinks.class);
when(entityLinks.linkToSingleResource(Matchers.<Class<?>> any(), anyObject())).thenReturn(new Link("/mock/1"));
RepositoryResourceMappings mappings = new RepositoryResourceMappings(repositories(), persistentEntities());
EntityLinks entityLinks = new RepositoryEntityLinks(repositories(), mappings, config(),
mock(PagingAndSortingTemplateVariables.class),
OrderAwarePluginRegistry.<Class<?>, BackendIdConverter> create(Arrays.asList(DefaultIdConverter.INSTANCE)));
return new PersistentEntityJackson2Module(new RepositoryResourceMappings(repositories(), persistentEntities()),
persistentEntities(), config(), new UriToEntityConverter(persistentEntities(), defaultConversionService()),
entityLinks);
return new PersistentEntityJackson2Module(mappings, persistentEntities(), config(), new UriToEntityConverter(
persistentEntities(), defaultConversionService()), entityLinks);
}
@Bean