Refactored the main controller to use regular Spring MVC conventions.

This commit is contained in:
Jon Brisbin
2012-04-09 09:01:18 -05:00
parent c53d092ee0
commit 53951a928f
11 changed files with 703 additions and 635 deletions

View File

@@ -10,6 +10,9 @@ 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;

View File

@@ -2,6 +2,8 @@ package org.springframework.data.rest.repository;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -13,6 +15,7 @@ import javax.persistence.metamodel.SingularAttribute;
import org.springframework.data.rest.core.Handler;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* @author Jon Brisbin <jon@jbrisbin.com>
@@ -22,6 +25,8 @@ public class JpaEntityMetadata {
private Class<?> targetType;
private Map<String, Attribute> embeddedAttributes = new HashMap<String, Attribute>();
private Map<String, Field> fields = new HashMap<String, Field>();
private Map<String, Method> setters = new HashMap<String, Method>();
private Map<String, Method> getters = new HashMap<String, Method>();
private Map<String, Attribute> linkedAttributes = new HashMap<String, Attribute>();
private final Attribute idAttribute;
private final Attribute versionAttribute;
@@ -37,6 +42,20 @@ public class JpaEntityMetadata {
Field f = ReflectionUtils.findField(targetType, attr.getName());
ReflectionUtils.makeAccessible(f);
fields.put(name, f);
Method setter = null;
try {
setter = targetType.getMethod("set" + StringUtils.capitalize(name), attr.getJavaType());
} catch (NoSuchMethodException e) {}
if (null != setter) {
setters.put(name, setter);
}
Method getter = null;
try {
getter = targetType.getMethod("get" + StringUtils.capitalize(name));
} catch (NoSuchMethodException e) {}
if (null != setter) {
getters.put(name, getter);
}
if (attr instanceof SingularAttribute) {
SingularAttribute sattr = (SingularAttribute) attr;
@@ -127,26 +146,36 @@ public class JpaEntityMetadata {
}
public Object get(String name, Object target) {
if (fields.containsKey(name)) {
try {
return fields.get(name).get(target);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
try {
Method getter = getters.get(name);
if (null != getter) {
return getter.invoke(target);
} else {
Field f = fields.get(name);
return (null != f ? f.get(target) : null);
}
} else {
throw new NoSuchFieldError(name);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
} catch (InvocationTargetException e) {
throw new IllegalStateException(e);
}
}
public void set(String name, Object arg, Object target) {
if (fields.containsKey(name)) {
try {
fields.get(name).set(target, arg);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
try {
Method setter = setters.get(name);
if (null != setter) {
setter.invoke(target, arg);
} else {
Field f = fields.get(name);
if (null != f) {
f.set(target, arg);
}
}
} else {
throw new NoSuchFieldError(name);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
} catch (InvocationTargetException e) {
throw new IllegalStateException(e);
}
}

View File

@@ -0,0 +1,28 @@
package org.springframework.data.rest.webmvc;
import java.util.ArrayList;
import java.util.List;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.springframework.data.rest.core.Link;
import org.springframework.data.rest.core.SimpleLink;
/**
* @author Jon Brisbin <jon@jbrisbin.com>
*/
public class Links {
private List<SimpleLink> links = new ArrayList<SimpleLink>();
public Links add(SimpleLink link) {
links.add(link);
return this;
}
@JsonProperty("_links")
public List<SimpleLink> getLinks() {
return this.links;
}
}

View File

@@ -58,7 +58,6 @@ public class RepositoryRestMvcConfiguration {
@Bean RepositoryRestController repositoryRestController() throws Exception {
if (null == repositoryRestController) {
this.repositoryRestController = new RepositoryRestController()
.baseUri(parentConfig.baseUri())
.repositoryMetadata(parentConfig.jpaRepositoryMetadata())
.conversionService(parentConfig.conversionService())
.httpMessageConverters(parentConfig.httpMessageConverters())

View File

@@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.data.rest.core.Link;
import org.springframework.data.rest.core.SimpleLink;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.view.AbstractView;
@@ -31,18 +32,20 @@ public class UriListView extends AbstractView {
HttpStatus status = (HttpStatus) model.get("status");
HttpHeaders headers = (HttpHeaders) model.get("headers");
List<Link> links = null;
List<SimpleLink> links = null;
if (resource instanceof List) {
links = (List<Link>) resource;
links = (List<SimpleLink>) resource;
} else if (resource instanceof Map) {
Map m = (Map) resource;
Object o = m.get("_links");
if (null != o && o instanceof List) {
links = (List<Link>) o;
links = (List<SimpleLink>) o;
} else {
response.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
return;
}
} else if (resource instanceof Links) {
links = ((Links) resource).getLinks();
}
if (null != status) {

View File

@@ -26,6 +26,10 @@ public class Address {
this.postalCode = postalCode;
}
public Long getId() {
return id;
}
public String[] getLines() {
return lines;
}

View File

@@ -3,6 +3,7 @@ package org.springframework.data.rest.test.webmvc;
import java.util.List;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Version;
@@ -13,7 +14,7 @@ import javax.persistence.Version;
@Entity
public class Person {
@Id private Long id;
@Id @GeneratedValue private Long id;
private String name;
@Version
private Long version;

View File

@@ -48,7 +48,13 @@ public class PersonLoader implements InitializingBean {
pers1profiles.put("twitter", twitter);
pers1profiles.put("facebook", fb);
personRepository.save(new Person(1L, "John Doe", Arrays.asList(pers1addr), pers1profiles));
Person p1 = personRepository.save(
new Person(
"John Doe",
Arrays.asList(addressRepository.findOne(pers1addr.getId())),
pers1profiles
)
);
Address pers2addr = addressRepository.save(new Address(new String[]{"1234 E. 2nd St."}, "Univille", "ST", "12345"));
@@ -57,7 +63,8 @@ public class PersonLoader implements InitializingBean {
Profile fb2 = profileRepository.save(new Profile("facebook", "/janedoe"));
pers2profiles.put("facebook", fb2);
personRepository.save(new Person(2L, "Jane Doe", Arrays.asList(pers2addr), pers2profiles));
Person p2 = personRepository.save(new Person("Jane Doe", Arrays.asList(pers2addr), pers2profiles));
}
}

View File

@@ -9,10 +9,12 @@
<jpa:repositories base-package="org.springframework.data.rest.test.webmvc"/>
<!--
<bean class="org.springframework.data.rest.test.webmvc.PersonLoader">
<property name="personRepository" ref="personRepository"/>
<property name="profileRepository" ref="profileRepository"/>
<property name="addressRepository" ref="addressRepository"/>
</bean>
-->
</beans>

View File

@@ -0,0 +1,11 @@
#!/bin/sh
curl -d '{"name" : "John Doe"}' -H "Content-Type: application/json" http://localhost:8080/person
curl -d '{"name" : "Jane Doe"}' -H "Content-Type: application/json" http://localhost:8080/person
curl -d '{"postalCode":"12345","province":"MO","lines":["1 W 1st St."],"city":"Univille"}' -H "Content-Type: application/json" http://localhost:8080/address
curl -d "http://localhost:8080/address/1" -H "Content-Type: text/uri-list" http://localhost:8080/person/1/addresses
curl -d '{"postalCode":"54321","province":"MO","lines":["2 W 1st St."],"city":"Univille"}' -H "Content-Type: application/json" http://localhost:8080/address
curl -d "http://localhost:8080/address/2" -H "Content-Type: text/uri-list" http://localhost:8080/person/2/addresses
curl -d '{"type" : "twitter", "url": "#!/johndoe"}' -H "Content-Type: application/json" http://localhost:8080/profile
curl -d "http://localhost:8080/profile/1" -H "Content-Type: text/uri-list" http://localhost:8080/person/1/profiles
curl -d '{"type" : "facebook", "url": "/janedoe"}' -H "Content-Type: application/json" http://localhost:8080/profile
curl -d '{"_links": [{"rel":"facebook", "href": "http://localhost:8080/profile/2"}]}' -H "Content-Type: application/json" http://localhost:8080/person/2/profiles