Fix for DATAREST-69. Tweaked how RepositoryEntityLinks gets its default baseUri if none is set in the configuration.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user