Adding tests.
This commit is contained in:
@@ -127,18 +127,26 @@ public class JpaEntityMetadata {
|
||||
}
|
||||
|
||||
public Object get(String name, Object target) {
|
||||
try {
|
||||
return fields.get(name).get(target);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
if (fields.containsKey(name)) {
|
||||
try {
|
||||
return fields.get(name).get(target);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
} else {
|
||||
throw new NoSuchFieldError(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void set(String name, Object arg, Object target) {
|
||||
try {
|
||||
fields.get(name).set(target, arg);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
if (fields.containsKey(name)) {
|
||||
try {
|
||||
fields.get(name).set(target, arg);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
} else {
|
||||
throw new NoSuchFieldError(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.springframework.data.rest.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
@@ -39,7 +40,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte
|
||||
this.metamodel = entityManager.getMetamodel();
|
||||
}
|
||||
|
||||
public CrudRepository repositoryFor(String name) {
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <T> CrudRepository<T, ? extends Serializable> repositoryFor(String name) {
|
||||
if (null != name) {
|
||||
for (Map.Entry<Class<?>, RepositoryCacheEntry> entry : repositories.entrySet()) {
|
||||
if (name.equals(repositoryNameFor(entry.getValue().repository))) {
|
||||
@@ -50,7 +52,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte
|
||||
return null;
|
||||
}
|
||||
|
||||
public CrudRepository repositoryFor(Class<?> domainClass) {
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <T> CrudRepository<T, ? extends Serializable> repositoryFor(Class<T> domainClass) {
|
||||
RepositoryCacheEntry entry = repositories.get(domainClass);
|
||||
if (null != entry) {
|
||||
return entry.repository;
|
||||
@@ -58,7 +61,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte
|
||||
return null;
|
||||
}
|
||||
|
||||
public EntityInformation entityInfoFor(Class<?> domainClass) {
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <T> EntityInformation<T, ? extends Serializable> entityInfoFor(Class<T> domainClass) {
|
||||
RepositoryCacheEntry entry = repositories.get(domainClass);
|
||||
if (null != entry) {
|
||||
return entry.entityInfo;
|
||||
@@ -70,7 +74,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte
|
||||
return metamodel.entity(domainClass);
|
||||
}
|
||||
|
||||
public EntityInformation entityInfoFor(CrudRepository repository) {
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <T> EntityInformation<T, ? extends Serializable> entityInfoFor(CrudRepository<T, ? extends Serializable> repository) {
|
||||
for (Map.Entry<Class<?>, RepositoryCacheEntry> entry : repositories.entrySet()) {
|
||||
if (entry.getValue().repository == repository) {
|
||||
return entry.getValue().entityInfo;
|
||||
@@ -116,7 +121,7 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte
|
||||
return names;
|
||||
}
|
||||
|
||||
public void setRepositories(Collection<CrudRepository> repositories) {
|
||||
public void setRepositories(Collection<? extends CrudRepository> repositories) {
|
||||
for (CrudRepository repository : repositories) {
|
||||
Class<?> repoClass = AopUtils.getTargetClass(repository);
|
||||
Field infoField = ReflectionUtils.findField(repoClass, "entityInformation");
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package org.springframework.data.rest.repository.spec
|
||||
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.EntityManager
|
||||
import javax.persistence.GeneratedValue
|
||||
import javax.persistence.Id
|
||||
import javax.persistence.PersistenceContext
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.context.ApplicationContext
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
import org.springframework.data.rest.repository.JpaRepositoryMetadata
|
||||
import org.springframework.data.rest.repository.test.Family
|
||||
import org.springframework.data.rest.repository.test.FamilyRepository
|
||||
import org.springframework.data.rest.repository.test.Person
|
||||
import org.springframework.data.rest.repository.test.PersonRepository
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import spock.lang.Specification
|
||||
|
||||
@@ -24,41 +25,50 @@ class JpaMetadataSpec extends Specification {
|
||||
EntityManager entityManager
|
||||
@Autowired
|
||||
Collection<CrudRepository> repositories
|
||||
@Autowired
|
||||
JpaRepositoryMetadata repoMeta
|
||||
|
||||
def setup() {
|
||||
repoMeta = new JpaRepositoryMetadata(
|
||||
repositories: repositories,
|
||||
applicationContext: applicationContext,
|
||||
entityManager: entityManager
|
||||
)
|
||||
repoMeta.afterPropertiesSet()
|
||||
}
|
||||
|
||||
def "finds repositories in ApplicationContext"() {
|
||||
|
||||
when:
|
||||
def repo = repoMeta.repositoryFor("simple")
|
||||
when: "find repo by String identifier"
|
||||
def repo = repoMeta.repositoryFor("person")
|
||||
|
||||
then:
|
||||
null != repo
|
||||
repo instanceof SimpleRepository
|
||||
repo instanceof PersonRepository
|
||||
|
||||
when:
|
||||
repo = repoMeta.repositoryFor(Simple)
|
||||
when: "find repo by domain Class<?>"
|
||||
repo = repoMeta.repositoryFor(Family)
|
||||
|
||||
then:
|
||||
null != repo
|
||||
repo instanceof SimpleRepository
|
||||
repo instanceof FamilyRepository
|
||||
|
||||
}
|
||||
|
||||
def "provides entity metadata"() {
|
||||
|
||||
given:
|
||||
def personRepo = repoMeta.repositoryFor(Person)
|
||||
def familyRepo = repoMeta.repositoryFor(Family)
|
||||
def johnDoe = personRepo.save(new Person("John Doe"))
|
||||
def janeDoe = personRepo.save(new Person("Jane Doe"))
|
||||
def doeFamily = familyRepo.save(new Family(
|
||||
surname: "Doe",
|
||||
members: [johnDoe, janeDoe]
|
||||
))
|
||||
|
||||
when:
|
||||
def personMeta = repoMeta.entityMetadataFor(Person)
|
||||
def familyMeta = repoMeta.entityMetadataFor(Family)
|
||||
|
||||
then:
|
||||
personMeta.get("name", johnDoe) == "John Doe"
|
||||
familyMeta.get("surname", doeFamily) == "Doe"
|
||||
familyMeta.get("members", doeFamily).size() == 2
|
||||
personMeta.embeddedAttributes().size() == 1
|
||||
familyMeta.linkedAttributes().size() == 1
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Entity
|
||||
class Simple {
|
||||
@Id @GeneratedValue Long id
|
||||
String name
|
||||
}
|
||||
|
||||
interface SimpleRepository extends CrudRepository<Simple, Long> {}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.springframework.data.rest.repository.test;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jon@jbrisbin.com>
|
||||
*/
|
||||
@Entity
|
||||
public class Family {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
private String surname;
|
||||
@OneToMany
|
||||
private List<Person> members;
|
||||
|
||||
public Family() {
|
||||
}
|
||||
|
||||
public Family(String surname) {
|
||||
this.surname = surname;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getSurname() {
|
||||
return surname;
|
||||
}
|
||||
|
||||
public void setSurname(String surname) {
|
||||
this.surname = surname;
|
||||
}
|
||||
|
||||
public List<Person> getMembers() {
|
||||
return members;
|
||||
}
|
||||
|
||||
public void setMembers(List<Person> members) {
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "Family{" +
|
||||
"id=" + id +
|
||||
", surname='" + surname + '\'' +
|
||||
", members=" + members +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.springframework.data.rest.repository.test;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jon@jbrisbin.com>
|
||||
*/
|
||||
public interface FamilyRepository extends CrudRepository<Family, Long> {
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.springframework.data.rest.repository.test;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jon@jbrisbin.com>
|
||||
*/
|
||||
@Entity
|
||||
public class Person {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "Person{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.springframework.data.rest.repository.test;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jon@jbrisbin.com>
|
||||
*/
|
||||
public interface PersonRepository extends CrudRepository<Person, Long> {
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
|
||||
<persistence-unit name="jpa.sample">
|
||||
<class>org.springframework.data.rest.repository.spec.Simple</class>
|
||||
<class>org.springframework.data.rest.repository.test.Person</class>
|
||||
<class>org.springframework.data.rest.repository.test.Family</class>
|
||||
<properties>
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
|
||||
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:spring"/>
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
|
||||
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd">
|
||||
|
||||
<jdbc:embedded-database id="dataSource" type="HSQL"/>
|
||||
|
||||
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="jpaVendorAdapter">
|
||||
@@ -18,9 +20,14 @@
|
||||
<property name="persistenceUnitName" value="jpa.sample"/>
|
||||
<property name="persistenceXmlLocation" value="/JpaMetadataSpec-persistence.xml"/>
|
||||
</bean>
|
||||
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
||||
</bean>
|
||||
|
||||
<jdbc:embedded-database id="dataSource" type="HSQL"/>
|
||||
<jpa:repositories base-package="org.springframework.data.rest.repository.test"/>
|
||||
|
||||
<jpa:repositories base-package="org.springframework.data.rest.repository.spec"/>
|
||||
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
|
||||
|
||||
<bean id="jpaRepositoryMetadata" class="org.springframework.data.rest.repository.JpaRepositoryMetadata"/>
|
||||
|
||||
</beans>
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<import resource="classpath:META-INF/spring-data-rest/**/*-export.xml"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.springframework.data.rest.mvc.spec
|
||||
|
||||
import org.codehaus.jackson.map.ObjectMapper
|
||||
import org.codehaus.jackson.map.ser.CustomSerializerFactory
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.data.rest.core.SimpleLink
|
||||
import org.springframework.data.rest.core.util.FluentBeanSerializer
|
||||
import org.springframework.data.rest.mvc.RepositoryRestConfiguration
|
||||
import org.springframework.data.rest.mvc.RepositoryRestController
|
||||
import org.springframework.data.rest.mvc.RepositoryRestMvcConfiguration
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.server.ServletServerHttpRequest
|
||||
import org.springframework.mock.web.MockHttpServletRequest
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import org.springframework.ui.ExtendedModelMap
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Specification
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jon@jbrisbin.com>
|
||||
*/
|
||||
@ContextConfiguration(classes = [RepositoryRestConfiguration, RepositoryRestMvcConfiguration])
|
||||
class RepositoryRestControllerSpec extends Specification {
|
||||
|
||||
@Shared
|
||||
ObjectMapper mapper = new ObjectMapper()
|
||||
@Autowired
|
||||
URI baseUri
|
||||
@Autowired
|
||||
RepositoryRestController controller
|
||||
|
||||
ServletServerHttpRequest createRequest(String method, String path) {
|
||||
return new ServletServerHttpRequest(new MockHttpServletRequest(
|
||||
serverPort: 8080,
|
||||
requestURI: "/data/$path",
|
||||
method: method
|
||||
))
|
||||
}
|
||||
|
||||
Map GET(String path) {
|
||||
def request = createRequest("GET", path)
|
||||
def model = new ExtendedModelMap()
|
||||
controller.get(request, model)
|
||||
return model
|
||||
}
|
||||
|
||||
def setupSpec() {
|
||||
def customSerializerFactory = new CustomSerializerFactory()
|
||||
customSerializerFactory.addSpecificMapping(SimpleLink, new FluentBeanSerializer(SimpleLink))
|
||||
mapper.setSerializerFactory(customSerializerFactory)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
def "responds to GET"() {
|
||||
|
||||
when:
|
||||
def repos = GET("")
|
||||
def reposLinks = repos.resource?._links
|
||||
|
||||
then:
|
||||
repos.status == HttpStatus.OK
|
||||
reposLinks?.size() == 3
|
||||
|
||||
when:
|
||||
def persons = GET("person")
|
||||
def personsLinks = persons.resource?._links
|
||||
|
||||
then:
|
||||
persons.status == HttpStatus.OK
|
||||
personsLinks[0].href().toString() == "http://localhost:8080/data/person/1"
|
||||
|
||||
when:
|
||||
def person = GET("person/1")
|
||||
|
||||
then:
|
||||
person?.resource.name == "John Doe"
|
||||
|
||||
when:
|
||||
def profiles = GET("person/1/profiles")
|
||||
def profilesLinks = profiles?.resource.profiles
|
||||
|
||||
then:
|
||||
profilesLinks.size() == 2
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,8 +9,7 @@
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework.data.rest" level="DEBUG"/>
|
||||
<logger name="org.springframework.data" level="DEBUG"/>
|
||||
<logger name="org.springframework" level="INFO"/>
|
||||
<logger name="org.springframework.data" level="INFO"/>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="stdout"/>
|
||||
|
||||
Reference in New Issue
Block a user