DATAREST-37: Display entities inline when accessing relationship links.

This commit is contained in:
Jon Brisbin
2012-08-13 09:31:55 -05:00
committed by Jon Brisbin
parent 17c97eb423
commit 3393780e65
21 changed files with 420 additions and 250 deletions

View File

@@ -2,11 +2,14 @@ package org.springframework.data.rest.core;
import java.net.URI;
import org.codehaus.jackson.annotate.JsonTypeInfo;
/**
* A simple bean representing a URI link.
*
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, defaultImpl = ResourceLink.class)
public interface Link {
/**

View File

@@ -1,39 +0,0 @@
package org.springframework.data.rest.core;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.codehaus.jackson.annotate.JsonProperty;
import org.springframework.util.Assert;
/**
* @author Jon Brisbin
*/
public abstract class LinkAware<T extends LinkAware<? super T>> {
@JsonProperty("links")
protected List<Link> links = new ArrayList<Link>();
public List<Link> getLinks() {
return links;
}
@SuppressWarnings({"unchecked"})
public T setLinks(List<Link> links) {
if(null == links) {
this.links = Collections.emptyList();
} else {
this.links = links;
}
return (T)this;
}
@SuppressWarnings({"unchecked"})
public T addLink(Link link) {
Assert.notNull(link, "Link cannot be null!");
links.add(link);
return (T)this;
}
}

View File

@@ -0,0 +1,36 @@
package org.springframework.data.rest.core;
import java.util.ArrayList;
import java.util.List;
/**
* Simple abstraction for representing a list of {@link Link}s.
*
* @author Jon Brisbin
*/
public class LinkList {
private List<Link> links = new ArrayList<Link>();
/**
* Add a {@link Link} to this list.
*
* @param link
*
* @return
*/
public LinkList add(Link link) {
links.add(link);
return this;
}
/**
* Get the {@link Link}s in this list.
*
* @return
*/
public List<Link> getLinks() {
return this.links;
}
}

View File

@@ -1,22 +0,0 @@
package org.springframework.data.rest.core;
import java.util.ArrayList;
import java.util.List;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
public class Links {
private List<Link> links = new ArrayList<Link>();
public Links add(Link link) {
links.add(link);
return this;
}
public List<Link> getLinks() {
return this.links;
}
}

View File

@@ -1,17 +1,24 @@
package org.springframework.data.rest.core;
import org.codehaus.jackson.annotate.JsonPropertyOrder;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.annotate.JsonUnwrapped;
import org.springframework.util.Assert;
/**
* Wraps a simple object or a bean plus a set of links.
*
* @author Jon Brisbin
*/
public class Resource<T> extends LinkAware<Resource<T>> {
public class Resource<T> {
@JsonUnwrapped
protected T resource;
@JsonProperty("links")
protected Set<Link> links = new HashSet<Link>();
public Resource() {
}
@@ -20,12 +27,64 @@ public class Resource<T> extends LinkAware<Resource<T>> {
this.resource = resource;
}
/**
* Get the resource. May be {@literal null}.
*
* @return The resource or {@literal null}.
*/
public T getResource() {
return resource;
}
public void setResource(T resource) {
/**
* Set the resource.
*
* @param resource
*
* @return {@literal this}
*/
public Resource<T> setResource(T resource) {
this.resource = resource;
return this;
}
/**
* Get the set of {@link Link}s for this resource.
*
* @return
*/
public Set<Link> getLinks() {
return links;
}
/**
* Set the entire set of {@link Link}s.
*
* @param links
*
* @return {@literal this}
*/
@SuppressWarnings({"unchecked"})
public Resource<T> setLinks(Set<Link> links) {
if(null == links) {
this.links = Collections.emptySet();
} else {
this.links = links;
}
return this;
}
/**
* Add a {@link Link} to this resource's set.
*
* @param link
*
* @return {@literal this}
*/
public Resource<T> addLink(Link link) {
Assert.notNull(link, "Link cannot be null.");
links.add(link);
return this;
}
}

View File

@@ -0,0 +1,60 @@
package org.springframework.data.rest.core;
import java.net.URI;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
/**
* Implementation of {@link Link}.
*
* @author Jon Brisbin
*/
public class ResourceLink implements Link, Comparable<Link> {
@JsonProperty("rel")
private String rel;
@JsonProperty("href")
private URI href;
public ResourceLink() {
}
public ResourceLink(String rel, URI href) {
this.rel = rel;
this.href = href;
}
@Override public String rel() {
return rel;
}
@Override public URI href() {
return href;
}
@Override public int compareTo(Link link) {
if(null == rel || null == link.rel()) {
return -1;
}
int i = rel.compareTo(link.rel());
if(i != 0) {
return i;
}
if(null == href || null == link.href()) {
return -1;
}
return (href.compareTo(link.href()));
}
@Override public String toString() {
return "ResourceLink{" +
"rel='" + rel + '\'' +
", href=" + href +
'}';
}
}

View File

@@ -0,0 +1,101 @@
package org.springframework.data.rest.core;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.codehaus.jackson.annotate.JsonProperty;
import org.springframework.util.Assert;
/**
* Abstraction for representing resources to the user agent.
*
* @author Jon Brisbin
*/
@SuppressWarnings({"unchecked"})
public class ResourceSet {
@JsonProperty("content")
protected List<Resource<?>> resources = new ArrayList<Resource<?>>();
@JsonProperty("links")
protected Set<Link> links = new HashSet<Link>();
/**
* Get the {@link Resource}s this {@literal ResourceSet} manages.
*
* @return
*/
public List<Resource<?>> getResources() {
return resources;
}
/**
* Set the {@link Resource}s this {@literal ResourceSet} manages.
*
* @param resources
*
* @return
*/
public ResourceSet setResources(List<Resource<?>> resources) {
if(null == resources) {
this.resources = Collections.emptyList();
} else {
this.resources = resources;
}
return this;
}
/**
* Add a {@link Resource} to this set.
*
* @param resource
*
* @return {@literal this}
*/
public ResourceSet addResource(Resource<?> resource) {
resources.add((null == resource ? new Resource<Object>() : resource));
return this;
}
/**
* Get the set of {@link Link}s.
*
* @return
*/
public Set<Link> getLinks() {
return links;
}
/**
* Set the {@link Link}s this {@literal ResourceSet} manages.
*
* @param links
*
* @return {@literal this}
*/
@SuppressWarnings({"unchecked"})
public ResourceSet setLinks(Set<Link> links) {
if(null == links) {
this.links = Collections.emptySet();
} else {
this.links = links;
}
return this;
}
/**
* Add a {@link Link} to this resource's set.
*
* @param link
*
* @return {@literal this}
*/
public ResourceSet addLink(Link link) {
Assert.notNull(link, "Link cannot be null.");
links.add(link);
return this;
}
}

View File

@@ -1,38 +0,0 @@
package org.springframework.data.rest.core;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.codehaus.jackson.annotate.JsonProperty;
/**
* Abstraction for representing resources to the user agent.
*
* @author Jon Brisbin
*/
@SuppressWarnings({"unchecked"})
public class Resources extends LinkAware<Resources> {
@JsonProperty("content")
protected List<Resource<?>> resources = new ArrayList<Resource<?>>();
public List getResources() {
return resources;
}
public Resources setResources(List resources) {
if(null == resources) {
this.resources = Collections.emptyList();
} else {
this.resources = resources;
}
return this;
}
public Resources addResource(Resource<?> resource) {
resources.add((null == resource ? new Resource<Object>() : resource));
return this;
}
}

View File

@@ -1,39 +0,0 @@
package org.springframework.data.rest.core;
import java.net.URI;
/**
* Implementation of {@link Link}.
*
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
public class SimpleLink
implements Link {
private String rel;
private URI href;
public SimpleLink() {
}
public SimpleLink(String rel, URI href) {
this.rel = rel;
this.href = href;
}
@Override public String rel() {
return rel;
}
@Override public URI href() {
return href;
}
@Override public String toString() {
return "SimpleLink{" +
"rel='" + rel + '\'' +
", href=" + href +
'}';
}
}

View File

@@ -5,7 +5,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.deser.std.StdDeserializer;
@@ -18,8 +17,7 @@ import org.springframework.util.ClassUtils;
*
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
public class FluentBeanDeserializer
extends StdDeserializer {
public class FluentBeanDeserializer extends StdDeserializer {
private ConversionService conversionService;
private FluentBeanUtils.Metadata beanMeta;
@@ -37,9 +35,7 @@ public class FluentBeanDeserializer
@Override
public Object deserialize(JsonParser jp,
DeserializationContext ctxt)
throws IOException,
JsonProcessingException {
DeserializationContext ctxt) throws IOException {
if(jp.getCurrentToken() != JsonToken.START_OBJECT) {
throw ctxt.mappingException(_valueClass);
}