diff --git a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/Person.java b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/Person.java index cb261a4c4..5c1972b4f 100644 --- a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/Person.java +++ b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/Person.java @@ -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 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 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(); - } - siblings.add(p); - return this; - } + public Person addSibling(Person p) { + if(siblings == Collections.EMPTY_LIST) { + siblings = new ArrayList(); + } + siblings.add(p); + return this; + } - @ManyToMany public List getSiblings() { - return siblings; - } + @ManyToMany(fetch = FetchType.LAZY) + public List getSiblings() { + return siblings; + } - public void setSiblings(List siblings) { - this.siblings = siblings; - } + public void setSiblings(List 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(); + } } \ No newline at end of file diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/RepositoryEntityLinks.java b/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/RepositoryEntityLinks.java deleted file mode 100644 index cd6d1a6b6..000000000 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/RepositoryEntityLinks.java +++ /dev/null @@ -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"); - } - } - -} diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java index 01c2f99a9..2e1c2fb6f 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java @@ -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; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java new file mode 100644 index 000000000..0e2c75afc --- /dev/null +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java @@ -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"); + } + } + +}