Browse Source
Created Mongo specific implementation of basic namespace functionality from Spring Data Commons. Allows classpath scanning for MongoRepository based repository interfaces.pull/1/head
13 changed files with 438 additions and 81 deletions
@ -0,0 +1,51 @@ |
|||||||
|
package org.springframework.data.document.mongodb.repository.config; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder; |
||||||
|
import org.springframework.data.document.mongodb.repository.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration; |
||||||
|
import org.springframework.data.repository.config.AbstractRepositoryConfigDefinitionParser; |
||||||
|
import org.w3c.dom.Element; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} to create |
||||||
|
* Mongo DB repositories from classpath scanning or manual definition. |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
public class MongoRepositoryConfigDefinitionParser |
||||||
|
extends |
||||||
|
AbstractRepositoryConfigDefinitionParser<SimpleMongoRepositoryConfiguration, MongoRepositoryConfiguration> { |
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* |
||||||
|
* @see org.springframework.data.repository.config. |
||||||
|
* AbstractRepositoryConfigDefinitionParser |
||||||
|
* #getGlobalRepositoryConfigInformation(org.w3c.dom.Element) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
protected SimpleMongoRepositoryConfiguration getGlobalRepositoryConfigInformation( |
||||||
|
Element element) { |
||||||
|
|
||||||
|
return new SimpleMongoRepositoryConfiguration(element); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* |
||||||
|
* @see org.springframework.data.repository.config. |
||||||
|
* AbstractRepositoryConfigDefinitionParser |
||||||
|
* #postProcessBeanDefinition(org.springframework |
||||||
|
* .data.repository.config.SingleRepositoryConfigInformation, |
||||||
|
* org.springframework.beans.factory.support.BeanDefinitionBuilder, |
||||||
|
* java.lang.Object) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
protected void postProcessBeanDefinition( |
||||||
|
MongoRepositoryConfiguration context, |
||||||
|
BeanDefinitionBuilder builder, Object beanSource) { |
||||||
|
|
||||||
|
builder.addPropertyReference("template", context.getMongoTemplateRef()); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,24 @@ |
|||||||
|
package org.springframework.data.document.mongodb.repository.config; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.xml.NamespaceHandlerSupport; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB |
||||||
|
* based repositories. |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
public class MongoRepositoryNamespaceHandler extends NamespaceHandlerSupport { |
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* |
||||||
|
* @see org.springframework.beans.factory.xml.NamespaceHandler#init() |
||||||
|
*/ |
||||||
|
public void init() { |
||||||
|
|
||||||
|
registerBeanDefinitionParser("repositories", |
||||||
|
new MongoRepositoryConfigDefinitionParser()); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,181 @@ |
|||||||
|
package org.springframework.data.document.mongodb.repository.config; |
||||||
|
|
||||||
|
import org.springframework.data.document.mongodb.MongoTemplate; |
||||||
|
import org.springframework.data.document.mongodb.repository.MongoRepository; |
||||||
|
import org.springframework.data.document.mongodb.repository.MongoRepositoryFactoryBean; |
||||||
|
import org.springframework.data.repository.config.AutomaticRepositoryConfigInformation; |
||||||
|
import org.springframework.data.repository.config.ManualRepositoryConfigInformation; |
||||||
|
import org.springframework.data.repository.config.RepositoryConfig; |
||||||
|
import org.springframework.data.repository.config.SingleRepositoryConfigInformation; |
||||||
|
import org.springframework.util.StringUtils; |
||||||
|
import org.w3c.dom.Element; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* {@link RepositoryConfig} implementation to create |
||||||
|
* {@link MongoRepositoryConfiguration} instances for both automatic and manual |
||||||
|
* configuration. |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
public class SimpleMongoRepositoryConfiguration |
||||||
|
extends |
||||||
|
RepositoryConfig<SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration, SimpleMongoRepositoryConfiguration> { |
||||||
|
|
||||||
|
private static final String MONGO_TEMPLATE_REF = "mongo-template-ref"; |
||||||
|
private static final String DEFAULT_MONGO_TEMPLATE_REF = "mongoTemplate"; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new {@link SimpleMongoRepositoryConfiguration} for the given |
||||||
|
* {@link Element}. |
||||||
|
* |
||||||
|
* @param repositoriesElement |
||||||
|
* @param defaultRepositoryFactoryBeanClassName |
||||||
|
*/ |
||||||
|
protected SimpleMongoRepositoryConfiguration(Element repositoriesElement) { |
||||||
|
|
||||||
|
super(repositoriesElement, MongoRepositoryFactoryBean.class.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the bean name of the {@link MongoTemplate} to be referenced. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public String getMongoTemplateRef() { |
||||||
|
|
||||||
|
String templateRef = getSource().getAttribute(MONGO_TEMPLATE_REF); |
||||||
|
return StringUtils.hasText(templateRef) ? templateRef |
||||||
|
: DEFAULT_MONGO_TEMPLATE_REF; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* |
||||||
|
* @see |
||||||
|
* org.springframework.data.repository.config.GlobalRepositoryConfigInformation |
||||||
|
* #getAutoconfigRepositoryInformation(java.lang.String) |
||||||
|
*/ |
||||||
|
public MongoRepositoryConfiguration getAutoconfigRepositoryInformation( |
||||||
|
String interfaceName) { |
||||||
|
|
||||||
|
return new AutomaticMongoRepositoryConfiguration(interfaceName, this); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* |
||||||
|
* @see |
||||||
|
* org.springframework.data.repository.config.GlobalRepositoryConfigInformation |
||||||
|
* #getRepositoryBaseInterface() |
||||||
|
*/ |
||||||
|
public Class<?> getRepositoryBaseInterface() { |
||||||
|
|
||||||
|
return MongoRepository.class; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* |
||||||
|
* @see org.springframework.data.repository.config.RepositoryConfig# |
||||||
|
* createSingleRepositoryConfigInformationFor(org.w3c.dom.Element) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
protected MongoRepositoryConfiguration createSingleRepositoryConfigInformationFor( |
||||||
|
Element element) { |
||||||
|
|
||||||
|
return new ManualMongoRepositoryConfiguration(element, this); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Simple interface for configuration values specific to Mongo repositories. |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
public static interface MongoRepositoryConfiguration |
||||||
|
extends |
||||||
|
SingleRepositoryConfigInformation<SimpleMongoRepositoryConfiguration> { |
||||||
|
|
||||||
|
String getMongoTemplateRef(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements manual lookup of the additional attributes. |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
private static class ManualMongoRepositoryConfiguration |
||||||
|
extends |
||||||
|
ManualRepositoryConfigInformation<SimpleMongoRepositoryConfiguration> |
||||||
|
implements MongoRepositoryConfiguration { |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new {@link ManualMongoRepositoryConfiguration} for the |
||||||
|
* given {@link Element} and parent. |
||||||
|
* |
||||||
|
* @param element |
||||||
|
* @param parent |
||||||
|
*/ |
||||||
|
public ManualMongoRepositoryConfiguration(Element element, |
||||||
|
SimpleMongoRepositoryConfiguration parent) { |
||||||
|
|
||||||
|
super(element, parent); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* |
||||||
|
* @see org.springframework.data.document.mongodb.repository.config. |
||||||
|
* SimpleMongoRepositoryConfiguration |
||||||
|
* .MongoRepositoryConfiguration#getMongoTemplateRef() |
||||||
|
*/ |
||||||
|
public String getMongoTemplateRef() { |
||||||
|
|
||||||
|
return getAttribute(MONGO_TEMPLATE_REF); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements the lookup of the additional attributes during automatic |
||||||
|
* configuration. |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
private static class AutomaticMongoRepositoryConfiguration |
||||||
|
extends |
||||||
|
AutomaticRepositoryConfigInformation<SimpleMongoRepositoryConfiguration> |
||||||
|
implements MongoRepositoryConfiguration { |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new {@link AutomaticMongoRepositoryConfiguration} for the |
||||||
|
* given interface and parent. |
||||||
|
* |
||||||
|
* @param interfaceName |
||||||
|
* @param parent |
||||||
|
*/ |
||||||
|
public AutomaticMongoRepositoryConfiguration(String interfaceName, |
||||||
|
SimpleMongoRepositoryConfiguration parent) { |
||||||
|
|
||||||
|
super(interfaceName, parent); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* |
||||||
|
* @see org.springframework.data.document.mongodb.repository.config. |
||||||
|
* SimpleMongoRepositoryConfiguration |
||||||
|
* .MongoRepositoryConfiguration#getMongoTemplateRef() |
||||||
|
*/ |
||||||
|
public String getMongoTemplateRef() { |
||||||
|
|
||||||
|
return getParent().getMongoTemplateRef(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1 @@ |
|||||||
|
http\://www.springframework.org/schema/data/mongo=org.springframework.data.document.mongodb.repository.config.MongoRepositoryNamespaceHandler |
||||||
@ -0,0 +1,2 @@ |
|||||||
|
http\://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd=org/springframework/data/document/mongodb/repository/config/spring-mongo-1.0.xsd |
||||||
|
http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/document/mongodb/repository/config/spring-mongo-1.0.xsd |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
# Tooling related information for the Mongo DB namespace |
||||||
|
http\://www.springframework.org/schema/data/mongo@name=Mongo Namespace |
||||||
|
http\://www.springframework.org/schema/data/mongo@prefix=mongo |
||||||
|
http\://www.springframework.org/schema/data/mongo@icon=org/springframework/jdbc/config/spring-jdbc.gif |
||||||
@ -0,0 +1,55 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||||
|
<xsd:schema xmlns="http://www.springframework.org/schema/data/mongo" |
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema" |
||||||
|
xmlns:tool="http://www.springframework.org/schema/tool" |
||||||
|
xmlns:context="http://www.springframework.org/schema/context" |
||||||
|
xmlns:repository="http://www.springframework.org/schema/data/repository" |
||||||
|
targetNamespace="http://www.springframework.org/schema/data/mongo" |
||||||
|
elementFormDefault="qualified" attributeFormDefault="unqualified"> |
||||||
|
|
||||||
|
<xsd:import namespace="http://www.springframework.org/schema/tool" /> |
||||||
|
<xsd:import namespace="http://www.springframework.org/schema/context" |
||||||
|
schemaLocation="http://www.springframework.org/schema/context/spring-context.xsd" /> |
||||||
|
<xsd:import namespace="http://www.springframework.org/schema/data/repository" |
||||||
|
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd" /> |
||||||
|
|
||||||
|
<xsd:complexType name="mongo-repository"> |
||||||
|
<xsd:complexContent> |
||||||
|
<xsd:extension base="repository:repository"> |
||||||
|
<xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" default="mongoTemplate"> |
||||||
|
<xsd:annotation> |
||||||
|
<xsd:documentation> |
||||||
|
The reference to a MongoTemplate. Will default to 'mongoTemplate'. |
||||||
|
</xsd:documentation> |
||||||
|
</xsd:annotation> |
||||||
|
</xsd:attribute> |
||||||
|
</xsd:extension> |
||||||
|
</xsd:complexContent> |
||||||
|
</xsd:complexType> |
||||||
|
|
||||||
|
<xsd:element name="repositories"> |
||||||
|
<xsd:complexType> |
||||||
|
<xsd:complexContent> |
||||||
|
<xsd:extension base="repository:repositories"> |
||||||
|
<xsd:sequence> |
||||||
|
<xsd:element name="repository" minOccurs="0" maxOccurs="unbounded" type="mongo-repository" /> |
||||||
|
</xsd:sequence> |
||||||
|
<xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" /> |
||||||
|
</xsd:extension> |
||||||
|
</xsd:complexContent> |
||||||
|
</xsd:complexType> |
||||||
|
</xsd:element> |
||||||
|
|
||||||
|
<xsd:simpleType name="mongoTemplateRef"> |
||||||
|
<xsd:annotation> |
||||||
|
<xsd:appinfo> |
||||||
|
<tool:annotation kind="ref"> |
||||||
|
<tool:assignable-to type="org.springframework.data.document.mongodb.MongoTemplate" /> |
||||||
|
</tool:annotation> |
||||||
|
</xsd:appinfo> |
||||||
|
</xsd:annotation> |
||||||
|
<xsd:union memberTypes="xsd:string" /> |
||||||
|
</xsd:simpleType> |
||||||
|
|
||||||
|
|
||||||
|
</xsd:schema> |
||||||
@ -0,0 +1,83 @@ |
|||||||
|
package org.springframework.data.document.mongodb.repository; |
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*; |
||||||
|
import static org.junit.Assert.*; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.data.domain.Page; |
||||||
|
import org.springframework.data.domain.PageRequest; |
||||||
|
import org.springframework.data.domain.Sort.Direction; |
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
||||||
|
|
||||||
|
/** |
||||||
|
* Base class for tests for {@link PersonRepository}. |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
@RunWith(SpringJUnit4ClassRunner.class) |
||||||
|
public abstract class AbstractPersonRepositoryIntegrationTests { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
protected PersonRepository repository; |
||||||
|
Person dave, carter, boyd,stefan,leroi; |
||||||
|
|
||||||
|
@Before |
||||||
|
public void setUp() { |
||||||
|
|
||||||
|
repository.deleteAll(); |
||||||
|
|
||||||
|
dave = new Person("Dave", "Matthews"); |
||||||
|
carter = new Person("Carter", "Beauford"); |
||||||
|
boyd = new Person("Boyd", "Tinsley"); |
||||||
|
stefan = new Person("Stefan", "Lessard"); |
||||||
|
leroi = new Person("Leroi", "Moore"); |
||||||
|
|
||||||
|
repository.save(Arrays.asList(dave, carter, boyd, stefan, leroi)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void findsPersonsByLastname() throws Exception { |
||||||
|
|
||||||
|
List<Person> result = repository.findByLastname("Beauford"); |
||||||
|
assertThat(result.size(), is(1)); |
||||||
|
assertThat(result, hasItem(carter)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void findsPersonsByFirstnameLike() throws Exception { |
||||||
|
|
||||||
|
List<Person> result = repository.findByFirstnameLike("Bo*"); |
||||||
|
assertThat(result.size(), is(1)); |
||||||
|
assertThat(result, hasItem(boyd)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void findsPagedPersons() throws Exception { |
||||||
|
|
||||||
|
Page<Person> result = |
||||||
|
repository.findAll(new PageRequest(1, 2, Direction.ASC, |
||||||
|
"lastname")); |
||||||
|
assertThat(result.isFirstPage(), is(false)); |
||||||
|
assertThat(result.isLastPage(), is(false)); |
||||||
|
assertThat(result, hasItems(dave, leroi)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void executesPagedFinderCorrectly() throws Exception { |
||||||
|
|
||||||
|
Page<Person> page = |
||||||
|
repository.findByLastnameLike("*a*", new PageRequest(0, 2, |
||||||
|
Direction.ASC, "lastname")); |
||||||
|
assertThat(page.isFirstPage(), is(true)); |
||||||
|
assertThat(page.isLastPage(), is(false)); |
||||||
|
assertThat(page.getNumberOfElements(), is(2)); |
||||||
|
assertThat(page, hasItems(carter, stefan)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,17 @@ |
|||||||
|
package org.springframework.data.document.mongodb.repository.config; |
||||||
|
|
||||||
|
import org.springframework.data.document.mongodb.repository.AbstractPersonRepositoryIntegrationTests; |
||||||
|
import org.springframework.test.context.ContextConfiguration; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Test class using the namespace configuration to set up the repository |
||||||
|
* instance. |
||||||
|
* |
||||||
|
* @author Oliver Gierke |
||||||
|
*/ |
||||||
|
@ContextConfiguration |
||||||
|
public class MongoNamespaceIntegrationTests extends |
||||||
|
AbstractPersonRepositoryIntegrationTests { |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:mongo="http://www.springframework.org/schema/data/mongo" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns:repository="http://www.springframework.org/schema/data/repository" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd |
||||||
|
http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository-1.0.xsd"> |
||||||
|
|
||||||
|
<import resource="../infrastructure.xml" /> |
||||||
|
|
||||||
|
<mongo:repositories base-package="org.springframework.data.**.repository"> |
||||||
|
<repository:exclude-filter type="regex" expression=".*MongoRepository" /> |
||||||
|
</mongo:repositories> |
||||||
|
|
||||||
|
</beans> |
||||||
Loading…
Reference in new issue