DATACMNS-58 - Added support for repository populators.

Added RepositoryPopulator abstraction and implementations based on Spring OXM Unmarshallers as well as Jackson. This allows arbitrary repositories being populated with data pulled from XML / JSON, no matter what store they are actually backed. The populator will eventually populate the repositories held in a Repositories instance. It can be used like this:

Repositories repositories = new Repositories(applicationContext);
ResourceReader reader = new JacksonResourceReader();

ResourceReaderRepositoryPopulator populator = new ResourceReaderRepositoryPopulator(reader);
populator.setResourceLocation("classpath*:data.json");
populator.populate(repositories);

The ResourceReader defines what technology shall be used to read the data from the file into objects. The ResourceReaderRepositoryPopulator uses the reader and can either get a set of Resource instances configured or is able to lookup resources using a location string. The actual Repositories instance captures all CrudRepository instances contained inside an ApplicationContext.

The populators can also be used from within XML configuration though the repository namespace elements shown below:

<repository:jackson-populator location="classpath:org/springframework/data/repository/init/data.json" />
		
<repository:unmarshaller-populator location="classpath:org/springframework/data/repository/init/data.xml" unmarshaller-ref="unmarshaller" />

Updated reference documentation accordingly.
This commit is contained in:
Oliver Gierke
2012-06-21 19:32:07 +02:00
parent 149cfa068c
commit d441d95197
24 changed files with 1248 additions and 2 deletions

View File

@@ -0,0 +1,78 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.repository.config;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.repository.init.JacksonResourceReader;
import org.springframework.data.repository.init.ResourceReaderRepositoryPopulator;
import org.springframework.data.repository.init.UnmarshallingResourceReader;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.test.util.ReflectionTestUtils;
/**
* Integratin tests for the initializer namespace elements.
*
* @author Oliver Gierke
*/
public class ResourceReaderRepositoryPopulatorBeanDefinitionParserIntegrationTests {
/**
* @see DATACMNS-58
*/
@Test
public void registersJacksonInitializerCorrectly() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(new ClassPathResource("populators.xml", getClass()));
BeanDefinition definition = beanFactory.getBeanDefinition("jackson-populator");
assertThat(definition, is(notNullValue()));
Object bean = beanFactory.getBean("jackson-populator");
assertThat(bean, is(instanceOf(ResourceReaderRepositoryPopulator.class)));
Object resourceReader = ReflectionTestUtils.getField(bean, "reader");
assertThat(resourceReader, is(instanceOf(JacksonResourceReader.class)));
}
/**
* @see DATACMNS-58
*/
@Test
public void registersXmlInitializerCorrectly() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(new ClassPathResource("populators.xml", getClass()));
BeanDefinition definition = beanFactory.getBeanDefinition("xml-populator");
assertThat(definition, is(notNullValue()));
Object bean = beanFactory.getBean("xml-populator");
assertThat(bean, is(instanceOf(ResourceReaderRepositoryPopulator.class)));
Object resourceReader = ReflectionTestUtils.getField(bean, "reader");
assertThat(resourceReader, is(instanceOf(UnmarshallingResourceReader.class)));
Object unmarshaller = ReflectionTestUtils.getField(resourceReader, "unmarshaller");
assertThat(unmarshaller, is(instanceOf(Jaxb2Marshaller.class)));
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.repository.init;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.util.Collection;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
/**
* @author Oliver Gierke
*/
public class JacksonResourceReaderIntegrationTests {
@Test
public void readsFileWithMultipleObjects() throws Exception {
ResourceReader reader = new JacksonResourceReader();
Object result = reader.readFrom(new ClassPathResource("data.json", getClass()), null);
assertThat(result, is(instanceOf(Collection.class)));
assertThat((Collection<?>) result, hasSize(1));
}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.repository.init;
/**
* @author Oliver Gierke
*/
public class Person {
String firstname;
String lastname;
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.repository.init;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.core.io.Resource;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.support.Repositories;
/**
* Unit tests for {@link UnmarshallingRepositoryInitializer}.
*
* @author Oliver Gierke
*/
@RunWith(MockitoJUnitRunner.class)
public class ResourceReaderRepositoryInitializerUnitTests {
@Mock
ResourceReader reader;
@Mock
Repositories repositories;
@Mock
Resource resource;
@Mock
CrudRepository<Object, Serializable> repo;
@Test
public void storesSingleObjectCorrectly() throws Exception {
Object reference = new Object();
setUpReferenceAndInititalize(reference);
verify(repo, times(1)).save(reference);
}
@Test
public void storesCollectionOfObjectsCorrectly() throws Exception {
Object object = new Object();
Collection<Object> reference = Collections.singletonList(object);
setUpReferenceAndInititalize(reference);
verify(repo, times(1)).save(object);
}
private void setUpReferenceAndInititalize(Object reference) throws Exception {
when(reader.readFrom(any(Resource.class), any(ClassLoader.class))).thenReturn(reference);
when(repositories.getRepositoryFor(Object.class)).thenReturn(repo);
ResourceReaderRepositoryPopulator initializer = new ResourceReaderRepositoryPopulator(reader);
initializer.setResources(resource);
initializer.populate(repositories);
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:repository="http://www.springframework.org/schema/data/repository"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd
http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<repository:jackson-populator id="jackson-populator"
location="classpath:org/springframework/data/repository/init/data.json" />
<repository:unmarshaller-populator
id="xml-populator" location="classpath:org/springframework/data/repository/init/data.xml"
unmarshaller-ref="unmarshaller" />
<oxm:jaxb2-marshaller id="unmarshaller" contextPath="org.springframework.data.repository.config" />
</beans>

View File

@@ -0,0 +1,3 @@
[ { "_class" : "org.springframework.data.repository.init.Person",
"firstname" : "Dave",
"lastname" : "Matthews" } ]