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:
@@ -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)));
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -0,0 +1,3 @@
|
||||
[ { "_class" : "org.springframework.data.repository.init.Person",
|
||||
"firstname" : "Dave",
|
||||
"lastname" : "Matthews" } ]
|
||||
Reference in New Issue
Block a user