DATAREST-112 - Moved property mapping into PropertyResourceMapping.
PersistentEntityJackson2Module now entirely relies on the property mapping to do the right thing for link creation. The PropertyResourceMapping now returns the property name for both rel and path.
This commit is contained in:
@@ -25,6 +25,7 @@ import java.util.Map;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.repository.core.RepositoryInformation;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.data.rest.core.Path;
|
||||
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
|
||||
import org.springframework.data.rest.core.support.RepositoriesUtils;
|
||||
import org.springframework.hateoas.RelProvider;
|
||||
@@ -44,6 +45,7 @@ public class ResourceMappings implements Iterable<ResourceMetadata> {
|
||||
|
||||
private final Map<Class<?>, ResourceMetadata> cache = new HashMap<Class<?>, ResourceMetadata>();
|
||||
private final Map<Class<?>, SearchResourceMappings> searchCache = new HashMap<Class<?>, SearchResourceMappings>();
|
||||
private final Map<PersistentProperty<?>, ResourceMapping> propertyCache = new HashMap<PersistentProperty<?>, ResourceMapping>();
|
||||
|
||||
/**
|
||||
* Creates a new {@link ResourceMappings} using the given {@link RepositoryRestConfiguration} and {@link Repositories}
|
||||
@@ -187,7 +189,19 @@ public class ResourceMappings implements Iterable<ResourceMetadata> {
|
||||
* @see org.springframework.data.rest.core.mapping.ResourceMetadataProvider#getMappingFor(org.springframework.data.mapping.PersistentProperty)
|
||||
*/
|
||||
ResourceMapping getMappingFor(PersistentProperty<?> property) {
|
||||
return getMappingFor(property.getActualType());
|
||||
|
||||
ResourceMapping propertyMapping = propertyCache.get(property);
|
||||
|
||||
if (propertyMapping != null) {
|
||||
return propertyMapping;
|
||||
}
|
||||
|
||||
ResourceMetadata propertyTypeMapping = getMappingFor(property.getActualType());
|
||||
propertyMapping = new PersistentPropertyResourceMapping(property, propertyTypeMapping == null ? false
|
||||
: propertyTypeMapping.isExported());
|
||||
propertyCache.put(property, propertyMapping);
|
||||
|
||||
return propertyMapping;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -208,4 +222,55 @@ public class ResourceMappings implements Iterable<ResourceMetadata> {
|
||||
public Iterator<ResourceMetadata> iterator() {
|
||||
return cache.values().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Special resource mapping for {@link PersistentProperty} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class PersistentPropertyResourceMapping implements ResourceMapping {
|
||||
|
||||
private final PersistentProperty<?> property;
|
||||
private final boolean exported;
|
||||
|
||||
/**
|
||||
* Creates a new {@link PersistentPropertyResourceMapping}.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @param exported whether the property is exported or not.
|
||||
*/
|
||||
public PersistentPropertyResourceMapping(PersistentProperty<?> property, boolean exported) {
|
||||
|
||||
Assert.notNull(property, "PersistentProperty must not be null!");
|
||||
this.property = property;
|
||||
this.exported = exported;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.mapping.ResourceMapping#getPath()
|
||||
*/
|
||||
@Override
|
||||
public Path getPath() {
|
||||
return new Path(property.getName());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.mapping.ResourceMapping#getRel()
|
||||
*/
|
||||
@Override
|
||||
public String getRel() {
|
||||
return property.getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.mapping.ResourceMapping#isExported()
|
||||
*/
|
||||
@Override
|
||||
public Boolean isExported() {
|
||||
return exported;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,13 +24,14 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.data.rest.core.Path;
|
||||
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
|
||||
import org.springframework.data.rest.core.domain.jpa.CreditCard;
|
||||
import org.springframework.data.rest.core.domain.jpa.JpaRepositoryConfig;
|
||||
import org.springframework.data.rest.core.domain.jpa.Person;
|
||||
import org.springframework.data.rest.core.mapping.ResourceMappings;
|
||||
import org.springframework.data.rest.core.mapping.ResourceMetadata;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -78,4 +79,22 @@ public class ResourceMappingsIntegrationTest {
|
||||
assertThat(creditCardMapping.isExported(), is(false));
|
||||
assertThat(creditCardMapping.getSearchResourceMappings().isExported(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-112
|
||||
*/
|
||||
@Test
|
||||
public void usesPropertyNameAsRelForPropertyResourceMapping() {
|
||||
|
||||
Repositories repositories = new Repositories(factory);
|
||||
PersistentEntity<?, ?> entity = repositories.getPersistentEntity(Person.class);
|
||||
PersistentProperty<?> property = entity.getPersistentProperty("siblings");
|
||||
|
||||
ResourceMetadata metadata = mappings.getMappingFor(Person.class);
|
||||
ResourceMapping mapping = metadata.getMappingFor(property);
|
||||
|
||||
assertThat(mapping.getRel(), is("siblings"));
|
||||
assertThat(mapping.getPath(), is(new Path("siblings")));
|
||||
assertThat(mapping.isExported(), is(true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.data.rest.core.UriDomainClassConverter;
|
||||
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
|
||||
import org.springframework.data.rest.core.mapping.ResourceMapping;
|
||||
import org.springframework.data.rest.core.mapping.ResourceMappings;
|
||||
import org.springframework.data.rest.core.mapping.ResourceMetadata;
|
||||
import org.springframework.data.rest.webmvc.PersistentEntityResource;
|
||||
@@ -72,19 +73,16 @@ public class PersistentEntityJackson2Module extends SimpleModule implements Init
|
||||
PersistentProperty<?> persistentProperty, List<Link> links) {
|
||||
|
||||
Assert.isTrue(persistentProperty.isAssociation(), "PersistentProperty must be an association!");
|
||||
ResourceMetadata metadata = mappings.getMappingFor(persistentProperty.getOwner().getType());
|
||||
ResourceMetadata ownerMetadata = mappings.getMappingFor(persistentProperty.getOwner().getType());
|
||||
|
||||
if (!metadata.isManagedResource(persistentProperty)) {
|
||||
if (!ownerMetadata.isManagedResource(persistentProperty)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
metadata = mappings.getMappingFor(persistentProperty.getActualType());
|
||||
|
||||
if (metadata.isExported()) {
|
||||
|
||||
String propertyRel = String.format("%s.%s", metadata.getSingleResourceRel(), persistentProperty.getName());
|
||||
links.add(builder.slash(persistentProperty.getName()).withRel(propertyRel));
|
||||
ResourceMapping propertyMapping = ownerMetadata.getMappingFor(persistentProperty);
|
||||
|
||||
if (propertyMapping.isExported()) {
|
||||
links.add(builder.slash(propertyMapping.getPath()).withRel(propertyMapping.getRel()));
|
||||
// This is an association. We added a Link.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -68,10 +68,10 @@ public class PersistentEntitySerializationTests {
|
||||
|
||||
String s = writer.toString();
|
||||
|
||||
Link fatherLink = linkDiscoverer.findLinkWithRel("person.father", s);
|
||||
Link fatherLink = linkDiscoverer.findLinkWithRel("father", s);
|
||||
assertThat(fatherLink.getHref(), endsWith(new UriTemplate("/{id}/father").expand(person.getId()).toString()));
|
||||
|
||||
Link siblingLink = linkDiscoverer.findLinkWithRel("person.siblings", s);
|
||||
Link siblingLink = linkDiscoverer.findLinkWithRel("siblings", s);
|
||||
assertThat(siblingLink.getHref(), endsWith(new UriTemplate("/{id}/siblings").expand(person.getId()).toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user