Fix for DATAREST-69. Tweaked how RepositoryEntityLinks gets its default baseUri if none is set in the configuration.

This commit is contained in:
Jon Brisbin
2013-03-05 10:54:13 -06:00
parent 9e47346314
commit afbf92bdad
4 changed files with 198 additions and 181 deletions

View File

@@ -6,7 +6,9 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
@@ -23,84 +25,86 @@ import org.springframework.data.rest.repository.annotation.Description;
@Entity
public class Person {
private Long id;
@Description("A person's first name")
private String firstName;
@Description("A person's last name")
private String lastName;
@Description("A person's siblings")
private List<Person> siblings = Collections.emptyList();
private Person father;
@Description("Timestamp this person object was created")
private Date created;
private Long id;
@Description("A person's first name")
private String firstName;
@Description("A person's last name")
private String lastName;
@Description("A person's siblings")
private List<Person> siblings = Collections.emptyList();
private Person father;
@Description("Timestamp this person object was created")
private Date created;
public Person() {
}
public Person() {
}
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Id @GeneratedValue public Long getId() {
return id;
}
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public String getLastName() {
return lastName;
}
@NotNull
public void setLastName(String lastName) {
this.lastName = lastName;
}
@NotNull
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Person addSibling(Person p) {
if(siblings == Collections.EMPTY_LIST) {
siblings = new ArrayList<Person>();
}
siblings.add(p);
return this;
}
public Person addSibling(Person p) {
if(siblings == Collections.EMPTY_LIST) {
siblings = new ArrayList<Person>();
}
siblings.add(p);
return this;
}
@ManyToMany public List<Person> getSiblings() {
return siblings;
}
@ManyToMany(fetch = FetchType.LAZY)
public List<Person> getSiblings() {
return siblings;
}
public void setSiblings(List<Person> siblings) {
this.siblings = siblings;
}
public void setSiblings(List<Person> siblings) {
this.siblings = siblings;
}
@ManyToOne public Person getFather() {
return father;
}
@ManyToOne public Person getFather() {
return father;
}
public void setFather(Person father) {
this.father = father;
}
public void setFather(Person father) {
this.father = father;
}
public Date getCreated() {
return created;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
}
public void setCreated(Date created) {
}
@PrePersist
private void prePersist() {
this.created = Calendar.getInstance().getTime();
}
@PrePersist
private void prePersist() {
this.created = Calendar.getInstance().getTime();
}
}

View File

@@ -1,117 +0,0 @@
package org.springframework.data.rest.repository.support;
import static org.springframework.data.rest.core.util.UriUtils.*;
import static org.springframework.data.rest.repository.support.ResourceMappingUtils.*;
import java.net.URI;
import org.springframework.data.mapping.PersistentEntity;
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.config.RepositoryRestConfiguration;
import org.springframework.data.rest.config.ResourceMapping;
import org.springframework.hateoas.Identifiable;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkBuilder;
import org.springframework.hateoas.core.AbstractEntityLinks;
import org.springframework.web.util.UriComponentsBuilder;
/**
* @author Jon Brisbin
*/
public class RepositoryEntityLinks extends AbstractEntityLinks {
private final Repositories repositories;
private final RepositoryRestConfiguration config;
public RepositoryEntityLinks(Repositories repositories,
RepositoryRestConfiguration config) {
this.repositories = repositories;
this.config = config;
}
@Override public boolean supports(Class<?> delimiter) {
PersistentEntity persistentEntity = repositories.getPersistentEntity(delimiter);
return (null != persistentEntity);
}
@Override public LinkBuilder linkFor(Class<?> type) {
RepositoryInformation repoInfo = repositories.getRepositoryInformationFor(type);
if(null == repoInfo) {
throw new IllegalArgumentException(type + " is not managed by any repository.");
}
PersistentEntity persistentEntity = repositories.getPersistentEntity(type);
if(null == persistentEntity) {
throw new IllegalArgumentException(type + " is not managed by any repository.");
}
return new PersistentEntityLinkBuilder(config.getBaseUri(), repoInfo, persistentEntity);
}
@Override public LinkBuilder linkFor(Class<?> type, Object... parameters) {
return linkFor(type);
}
@Override public Link linkToCollectionResource(Class<?> type) {
RepositoryInformation repoInfo = repositories.getRepositoryInformationFor(type);
if(null == repoInfo) {
throw new IllegalArgumentException(type + " is not managed by any repository.");
}
ResourceMapping mapping = getResourceMapping(config, repoInfo);
return linkFor(type).withRel(mapping.getRel());
}
@Override public Link linkToSingleResource(Class<?> type, Object id) {
RepositoryInformation repoInfo = repositories.getRepositoryInformationFor(type);
if(null == repoInfo) {
throw new IllegalArgumentException(type + " is not managed by any repository.");
}
ResourceMapping repoMapping = getResourceMapping(config, repoInfo);
PersistentEntity persistentEntity = repositories.getPersistentEntity(type);
ResourceMapping entityMapping = getResourceMapping(config, persistentEntity);
return linkFor(type).slash(id).withRel(repoMapping.getRel() + "." + entityMapping.getRel());
}
private class PersistentEntityLinkBuilder implements LinkBuilder {
private final UriComponentsBuilder builder;
private final ResourceMapping repoMapping;
private final ResourceMapping entityMapping;
private PersistentEntityLinkBuilder(URI baseUri,
RepositoryInformation repoInfo,
PersistentEntity persistentEntity) {
this.repoMapping = getResourceMapping(config, repoInfo);
this.entityMapping = getResourceMapping(config, persistentEntity);
this.builder = UriComponentsBuilder.fromUri(buildUri(baseUri, repoMapping.getPath()));
}
@Override public LinkBuilder slash(Object object) {
String path = String.format("%s", object);
if(object instanceof PersistentProperty) {
String propName = ((PersistentProperty)object).getName();
if(entityMapping.hasResourceMappingFor(propName)) {
path = entityMapping.getResourceMappingFor(propName).getPath();
}
}
builder.pathSegment(path);
return this;
}
@Override public LinkBuilder slash(Identifiable<?> identifiable) {
return slash(identifiable.getId());
}
@Override public URI toUri() {
return builder.build().toUri();
}
@Override public Link withRel(String rel) {
return new Link(builder.build().toUriString(), rel);
}
@Override public Link withSelfRel() {
return withRel("self");
}
}
}

View File

@@ -23,7 +23,7 @@ import org.springframework.data.rest.repository.json.Jackson2DatatypeHelper;
import org.springframework.data.rest.repository.json.PersistentEntityJackson2Module;
import org.springframework.data.rest.repository.json.PersistentEntityToJsonSchemaConverter;
import org.springframework.data.rest.repository.support.DomainObjectMerger;
import org.springframework.data.rest.repository.support.RepositoryEntityLinks;
import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks;
import org.springframework.data.rest.webmvc.BaseUriMethodArgumentResolver;
import org.springframework.data.rest.webmvc.PagingAndSortingMethodArgumentResolver;
import org.springframework.data.rest.webmvc.PersistentEntityResourceHandlerMethodArgumentResolver;

View File

@@ -0,0 +1,130 @@
package org.springframework.data.rest.webmvc.support;
import static org.springframework.data.rest.core.util.UriUtils.*;
import static org.springframework.data.rest.repository.support.ResourceMappingUtils.*;
import java.net.URI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mapping.PersistentEntity;
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.config.RepositoryRestConfiguration;
import org.springframework.data.rest.config.ResourceMapping;
import org.springframework.data.rest.webmvc.RepositoryController;
import org.springframework.hateoas.Identifiable;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkBuilder;
import org.springframework.hateoas.core.AbstractEntityLinks;
import org.springframework.hateoas.mvc.ControllerLinkBuilder;
import org.springframework.web.util.UriComponentsBuilder;
/**
* @author Jon Brisbin
*/
public class RepositoryEntityLinks extends AbstractEntityLinks {
private final Repositories repositories;
private final RepositoryRestConfiguration config;
@Autowired
public RepositoryEntityLinks(Repositories repositories,
RepositoryRestConfiguration config) {
this.repositories = repositories;
this.config = config;
}
@Override public boolean supports(Class<?> delimiter) {
PersistentEntity persistentEntity = repositories.getPersistentEntity(delimiter);
return (null != persistentEntity);
}
@Override public LinkBuilder linkFor(Class<?> type) {
RepositoryInformation repoInfo = repositories.getRepositoryInformationFor(type);
if(null == repoInfo) {
throw new IllegalArgumentException(type + " is not managed by any repository.");
}
PersistentEntity persistentEntity = repositories.getPersistentEntity(type);
if(null == persistentEntity) {
throw new IllegalArgumentException(type + " is not managed by any repository.");
}
return new PersistentEntityLinkBuilder(config.getBaseUri(), repoInfo, persistentEntity);
}
@Override public LinkBuilder linkFor(Class<?> type, Object... parameters) {
return linkFor(type);
}
@Override public Link linkToCollectionResource(Class<?> type) {
RepositoryInformation repoInfo = repositories.getRepositoryInformationFor(type);
if(null == repoInfo) {
throw new IllegalArgumentException(type + " is not managed by any repository.");
}
ResourceMapping mapping = getResourceMapping(config, repoInfo);
return linkFor(type).withRel(mapping.getRel());
}
@Override public Link linkToSingleResource(Class<?> type, Object id) {
RepositoryInformation repoInfo = repositories.getRepositoryInformationFor(type);
if(null == repoInfo) {
throw new IllegalArgumentException(type + " is not managed by any repository.");
}
ResourceMapping repoMapping = getResourceMapping(config, repoInfo);
PersistentEntity persistentEntity = repositories.getPersistentEntity(type);
ResourceMapping entityMapping = getResourceMapping(config, persistentEntity);
return linkFor(type).slash(id).withRel(repoMapping.getRel() + "." + entityMapping.getRel());
}
private class PersistentEntityLinkBuilder implements LinkBuilder {
private final UriComponentsBuilder builder;
private final ResourceMapping repoMapping;
private final ResourceMapping entityMapping;
private PersistentEntityLinkBuilder(URI baseUri,
RepositoryInformation repoInfo,
PersistentEntity persistentEntity) {
this.repoMapping = getResourceMapping(config, repoInfo);
this.entityMapping = getResourceMapping(config, persistentEntity);
if(null == baseUri) {
URI u = ControllerLinkBuilder.linkTo(RepositoryController.class).toUri();
if(u.toString().endsWith("/")) {
String s = u.toString();
baseUri = URI.create(s.substring(0, s.lastIndexOf('/')));
} else {
baseUri = u;
}
}
this.builder = UriComponentsBuilder.fromUri(buildUri(baseUri, repoMapping.getPath()));
}
@Override public LinkBuilder slash(Object object) {
String path = String.format("%s", object);
if(object instanceof PersistentProperty) {
String propName = ((PersistentProperty)object).getName();
if(entityMapping.hasResourceMappingFor(propName)) {
path = entityMapping.getResourceMappingFor(propName).getPath();
}
}
builder.pathSegment(path);
return this;
}
@Override public LinkBuilder slash(Identifiable<?> identifiable) {
return slash(identifiable.getId());
}
@Override public URI toUri() {
return builder.build().toUri();
}
@Override public Link withRel(String rel) {
return new Link(builder.build().toUriString(), rel);
}
@Override public Link withSelfRel() {
return withRel("self");
}
}
}