Compare commits
23 Commits
labs/build
...
1.0.1.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
edd71cac78 | ||
|
|
82bd7a69eb | ||
|
|
b434a0810e | ||
|
|
40236d4099 | ||
|
|
8f6d940036 | ||
|
|
95a92ccf5d | ||
|
|
a6db24554f | ||
|
|
2f6c61ef9c | ||
|
|
d8bf7ebf3f | ||
|
|
ce42783e73 | ||
|
|
69474327c6 | ||
|
|
1bbe2e8247 | ||
|
|
94af898ae3 | ||
|
|
f6298f7005 | ||
|
|
d5b3c651b2 | ||
|
|
33dd00f0b8 | ||
|
|
3207a81555 | ||
|
|
d231519012 | ||
|
|
e052ecc9a4 | ||
|
|
071f2934a1 | ||
|
|
d2a18e9b11 | ||
|
|
d684fa1f8e | ||
|
|
1a0077231d |
65
pom.xml
65
pom.xml
@@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-dist</artifactId>
|
||||
<name>Spring Data MongoDB Distribution</name>
|
||||
<version>1.0.0.RELEASE</version>
|
||||
<description>Spring Data project for MongoDB</description>
|
||||
<url>http://www.springsource.org/spring-data/mongodb</url>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>spring-data-mongodb</module>
|
||||
@@ -14,7 +15,18 @@
|
||||
<module>spring-data-mongodb-parent</module>
|
||||
</modules>
|
||||
|
||||
<developers>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>ogierke</id>
|
||||
<name>Oliver Gierke</name>
|
||||
<email>ogierke at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project lead</role>
|
||||
</roles>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>trisberg</id>
|
||||
<name>Thomas Risberg</name>
|
||||
@@ -39,17 +51,6 @@
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>ogierke</id>
|
||||
<name>Oliver Gierke</name>
|
||||
<email>ogierke at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>jbrisbin</id>
|
||||
<name>Jon Brisbin</name>
|
||||
@@ -145,7 +146,7 @@
|
||||
<htmlCustomization>${project.basedir}/src/docbkx/resources/xsl/html.xsl</htmlCustomization>
|
||||
<useExtensions>1</useExtensions>
|
||||
<highlightSource>1</highlightSource>
|
||||
<highlightDefaultLanguage></highlightDefaultLanguage>
|
||||
<highlightDefaultLanguage />
|
||||
<!-- callouts -->
|
||||
<entities>
|
||||
<entity>
|
||||
@@ -156,26 +157,24 @@
|
||||
<postProcess>
|
||||
<copy todir="${project.basedir}/target/site/reference">
|
||||
<fileset dir="${project.basedir}/target/docbkx">
|
||||
<include name="**/*.html"/>
|
||||
<include name="**/*.pdf"/>
|
||||
<include name="**/*.html" />
|
||||
<include name="**/*.pdf" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="${project.basedir}/target/site/reference/html">
|
||||
<fileset dir="${project.basedir}/src/docbkx/resources">
|
||||
<include name="**/*.css"/>
|
||||
<include name="**/*.png"/>
|
||||
<include name="**/*.gif"/>
|
||||
<include name="**/*.jpg"/>
|
||||
<include name="**/*.css" />
|
||||
<include name="**/*.png" />
|
||||
<include name="**/*.gif" />
|
||||
<include name="**/*.jpg" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="${project.basedir}/target/site/reference/html">
|
||||
<fileset dir="${project.basedir}/src/docbkx/resources/images">
|
||||
<include name="*.png"/>
|
||||
<include name="*.png" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<move file="${project.basedir}/target/site/reference/pdf/index.pdf"
|
||||
tofile="${project.basedir}/target/site/reference/pdf/spring-data-mongo-reference.pdf"
|
||||
failonerror="false"/>
|
||||
<move file="${project.basedir}/target/site/reference/pdf/index.pdf" tofile="${project.basedir}/target/site/reference/pdf/spring-data-mongo-reference.pdf" failonerror="false" />
|
||||
</postProcess>
|
||||
</configuration>
|
||||
</plugin>
|
||||
@@ -184,7 +183,7 @@
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<javadoc:aggregate>true</javadoc:aggregate>
|
||||
<aggregate>true</aggregate>
|
||||
<breakiterator>true</breakiterator>
|
||||
<header>Spring Data Document</header>
|
||||
<source>1.5</source>
|
||||
@@ -234,7 +233,7 @@
|
||||
<configuration>
|
||||
<tasks>
|
||||
<ant antfile="${basedir}/src/ant/upload-dist.xml">
|
||||
<target name="upload-dist"/>
|
||||
<target name="upload-dist" />
|
||||
</ant>
|
||||
</tasks>
|
||||
</configuration>
|
||||
@@ -270,9 +269,9 @@
|
||||
<url>http://repository.springsource.com/maven/bundles/release</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>repository.springframework.maven.release</id>
|
||||
<id>spring-libs-release</id>
|
||||
<name>Spring Framework Maven Release Repository</name>
|
||||
<url>http://repo.springsource.org/release</url>
|
||||
<url>http://repo.springsource.org/libs-release</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
@@ -282,7 +281,7 @@
|
||||
<site>
|
||||
<id>static.springframework.org</id>
|
||||
<url>
|
||||
scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-data/data-mongodb/docs/${project.version}
|
||||
scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-data/data-mongodb/snapshot-site
|
||||
</url>
|
||||
</site>
|
||||
<repository>
|
||||
@@ -296,5 +295,7 @@
|
||||
<url>s3://maven.springframework.org/snapshot</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<scm>
|
||||
<url>https://github.com/SpringSource/spring-data-mongodb</url>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.0.0.RELEASE</version>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb-cross-store</artifactId>
|
||||
@@ -151,25 +151,7 @@
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jboss-repository</id>
|
||||
<name>JBoss Public Repository</name>
|
||||
<url>http://repository.jboss.org/nexus/content/groups/public-jboss</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-maven-milestones</id>
|
||||
<name>Springframework Maven Milestone Repository</name>
|
||||
<url>http://maven.springframework.org/milestone</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-maven-release</id>
|
||||
<name>Springframework Maven Release Repository</name>
|
||||
<url>http://maven.springframework.org/release</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.0.0.RELEASE</version>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb-log4j</artifactId>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<name>Spring Data MongoDB Parent</name>
|
||||
<description>Spring Data project for MongoDB</description>
|
||||
<url>http://www.springsource.org/spring-data/mongodb</url>
|
||||
<version>1.0.0.RELEASE</version>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
<packaging>pom</packaging>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
@@ -19,9 +19,82 @@
|
||||
<org.springframework.version.30>3.0.7.RELEASE</org.springframework.version.30>
|
||||
<org.springframework.version.40>4.0.0.RELEASE</org.springframework.version.40>
|
||||
<org.springframework.version.range>[${org.springframework.version.30}, ${org.springframework.version.40})</org.springframework.version.range>
|
||||
<data.commons.version>1.2.0.RELEASE</data.commons.version>
|
||||
<data.commons.version>1.2.1.RELEASE</data.commons.version>
|
||||
<aspectj.version>1.6.11.RELEASE</aspectj.version>
|
||||
</properties>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>ogierke</id>
|
||||
<name>Oliver Gierke</name>
|
||||
<email>ogierke at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project lead</role>
|
||||
</roles>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>trisberg</id>
|
||||
<name>Thomas Risberg</name>
|
||||
<email>trisberg at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.SpringSource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Admin</role>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>mpollack</id>
|
||||
<name>Mark Pollack</name>
|
||||
<email>mpollack at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.SpringSource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Admin</role>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>jbrisbin</id>
|
||||
<name>Jon Brisbin</name>
|
||||
<email>jbrisbin at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-6</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
<comments>
|
||||
Copyright 2010 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.
|
||||
</comments>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>strict</id>
|
||||
@@ -65,7 +138,7 @@
|
||||
<site>
|
||||
<id>static.springframework.org</id>
|
||||
<url>
|
||||
scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-data/data-mongodb/docs/${project.version}
|
||||
scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-data/data-mongodb/snapshot-site
|
||||
</url>
|
||||
</site>
|
||||
<repository>
|
||||
@@ -79,6 +152,9 @@
|
||||
<url>s3://maven.springframework.org/snapshot</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
<scm>
|
||||
<url>https://github.com/SpringSource/spring-data-mongodb</url>
|
||||
</scm>
|
||||
<dependencyManagement>
|
||||
<!--
|
||||
inheritable <dependency> declarations for child poms. children still
|
||||
@@ -152,7 +228,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
@@ -369,22 +445,14 @@
|
||||
</build>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<!-- necessary for bundlor and utils -->
|
||||
<id>repository.plugin.springsource.release</id>
|
||||
<name>SpringSource Maven Repository</name>
|
||||
<url>http://repository.springsource.com/maven/bundles/release</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>repository.springframework.maven.release</id>
|
||||
<name>Spring Framework Maven Release Repository</name>
|
||||
<url>http://repo.springsource.org/release</url>
|
||||
<id>spring-plugins-release</id>
|
||||
<url>http://repo.springsource.org/plugins-release</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>repository.springframework.maven.release</id>
|
||||
<name>Spring Framework Maven Release Repository</name>
|
||||
<url>http://repo.springsource.org/release</url>
|
||||
<id>spring-libs-release</id>
|
||||
<url>http://repo.springsource.org/libs-release</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<reporting>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.0.0.RELEASE</version>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
@@ -128,6 +127,7 @@
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -154,15 +154,5 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>querydsl</id>
|
||||
<name>Mysema QueryDsl</name>
|
||||
<url>http://source.mysema.com/maven2/releases</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -143,11 +143,11 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
List<Element> customConvertersElements = DomUtils.getChildElementsByTagName(element, "custom-converters");
|
||||
|
||||
if (customConvertersElements.size() == 1) {
|
||||
|
||||
|
||||
Element customerConvertersElement = customConvertersElements.get(0);
|
||||
ManagedList<BeanMetadataElement> converterBeans = new ManagedList<BeanMetadataElement>();
|
||||
List<Element> converterElements = DomUtils.getChildElementsByTagName(customerConvertersElement, "converter");
|
||||
|
||||
|
||||
if (converterElements != null) {
|
||||
for (Element listenerElement : converterElements) {
|
||||
converterBeans.add(parseConverter(listenerElement, parserContext));
|
||||
@@ -158,9 +158,9 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
String packageToScan = customerConvertersElement.getAttribute(BASE_PACKAGE);
|
||||
if (StringUtils.hasText(packageToScan)) {
|
||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||
provider.addExcludeFilter(new NegatingFilter(new AssignableTypeFilter(Converter.class), new AssignableTypeFilter(
|
||||
GenericConverter.class)));
|
||||
|
||||
provider.addExcludeFilter(new NegatingFilter(new AssignableTypeFilter(Converter.class),
|
||||
new AssignableTypeFilter(GenericConverter.class)));
|
||||
|
||||
for (BeanDefinition candidate : provider.findCandidateComponents(packageToScan)) {
|
||||
converterBeans.add(candidate);
|
||||
}
|
||||
@@ -221,7 +221,7 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
/**
|
||||
* {@link TypeFilter} that returns {@literal false} in case any of the given delegates matches.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class NegatingFilter implements TypeFilter {
|
||||
|
||||
@@ -21,15 +21,16 @@ import com.mongodb.DBObject;
|
||||
import com.mongodb.MongoException;
|
||||
|
||||
/**
|
||||
* An interface used by {@link MongoTemplate} for processing documents returned from a MongoDB query on a per-document basis.
|
||||
* Implementations of this interface perform the actual work of prcoessing each document but don't need to worry about
|
||||
* exception handling. {@MongoException}s will be caught and translated by the calling MongoTemplate
|
||||
* An interface used by {@link MongoTemplate} for processing documents returned from a MongoDB query on a per-document
|
||||
* basis. Implementations of this interface perform the actual work of prcoessing each document but don't need to worry
|
||||
* about exception handling. {@MongoException}s will be caught and translated by the calling
|
||||
* MongoTemplate
|
||||
*
|
||||
* An DocumentCallbackHandler is typically stateful: It keeps the result state within the object, to be available later for later
|
||||
* inspection.
|
||||
* An DocumentCallbackHandler is typically stateful: It keeps the result state within the object, to be available later
|
||||
* for later inspection.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface DocumentCallbackHandler {
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ package org.springframework.data.mongodb.core;
|
||||
public class FindAndModifyOptions {
|
||||
|
||||
boolean returnNew;
|
||||
|
||||
|
||||
boolean upsert;
|
||||
|
||||
|
||||
boolean remove;
|
||||
|
||||
/**
|
||||
@@ -31,17 +31,17 @@ public class FindAndModifyOptions {
|
||||
public static FindAndModifyOptions options() {
|
||||
return new FindAndModifyOptions();
|
||||
}
|
||||
|
||||
|
||||
public FindAndModifyOptions returnNew(boolean returnNew) {
|
||||
this.returnNew = returnNew;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public FindAndModifyOptions upsert(boolean upsert) {
|
||||
this.upsert = upsert;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public FindAndModifyOptions remove(boolean remove) {
|
||||
this.remove = remove;
|
||||
return this;
|
||||
@@ -58,7 +58,5 @@ public class FindAndModifyOptions {
|
||||
public boolean isRemove() {
|
||||
return remove;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -20,35 +20,38 @@ import com.mongodb.DBObject;
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
/**
|
||||
* Represents an action taken against the collection. Used by {@link WriteConcernResolver} to determine a custom
|
||||
* Represents an action taken against the collection. Used by {@link WriteConcernResolver} to determine a custom
|
||||
* WriteConcern based on this information.
|
||||
*
|
||||
* Properties that will always be not-null are collectionName and defaultWriteConcern.
|
||||
* The EntityClass is null only for the MongoActionOperaton.INSERT_LIST.
|
||||
* Properties that will always be not-null are collectionName and defaultWriteConcern. The EntityClass is null only for
|
||||
* the MongoActionOperaton.INSERT_LIST.
|
||||
*
|
||||
* INSERT, SAVE have null query,
|
||||
* REMOVE has null document
|
||||
* INSERT_LIST has null entityClass, document, and query.
|
||||
* <ul>
|
||||
* <li>INSERT, SAVE have null query</li>
|
||||
* <li>REMOVE has null document</li>
|
||||
* <li>INSERT_LIST has null entityClass, document, and query</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class MongoAction {
|
||||
|
||||
|
||||
private String collectionName;
|
||||
|
||||
|
||||
private WriteConcern defaultWriteConcern;
|
||||
|
||||
|
||||
private Class<?> entityClass;
|
||||
|
||||
|
||||
private MongoActionOperation mongoActionOperation;
|
||||
|
||||
|
||||
private DBObject query;
|
||||
|
||||
|
||||
private DBObject document;
|
||||
|
||||
/**
|
||||
* Create an instance of a MongoAction
|
||||
*
|
||||
* @param defaultWriteConcern the default write concern
|
||||
* @param mongoActionOperation action being taken against the collection
|
||||
* @param collectionName the collection name
|
||||
@@ -90,7 +93,5 @@ public class MongoAction {
|
||||
public DBObject getDocument() {
|
||||
return document;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -16,18 +16,14 @@
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
/**
|
||||
* Enumeration for operations on a collection. Used with {@link MongoAction} to help determine the
|
||||
* WriteConcern to use for a given mutating operation
|
||||
* Enumeration for operations on a collection. Used with {@link MongoAction} to help determine the WriteConcern to use
|
||||
* for a given mutating operation
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @see MongoAction
|
||||
*
|
||||
*
|
||||
*/
|
||||
public enum MongoActionOperation {
|
||||
|
||||
REMOVE,
|
||||
UPDATE,
|
||||
INSERT,
|
||||
INSERT_LIST,
|
||||
SAVE
|
||||
|
||||
REMOVE, UPDATE, INSERT, INSERT_LIST, SAVE
|
||||
}
|
||||
|
||||
@@ -89,9 +89,9 @@ public class QueryMapper {
|
||||
newKey = "_id";
|
||||
} else if (key.startsWith("$") && key.endsWith("or")) {
|
||||
// $or/$nor
|
||||
BasicBSONList conditions = (BasicBSONList) value;
|
||||
Iterable<?> conditions = (Iterable<?>) value;
|
||||
BasicBSONList newConditions = new BasicBSONList();
|
||||
Iterator<Object> iter = conditions.iterator();
|
||||
Iterator<?> iter = conditions.iterator();
|
||||
while (iter.hasNext()) {
|
||||
newConditions.add(getMappedObject((DBObject) iter.next(), entity));
|
||||
}
|
||||
@@ -100,7 +100,7 @@ public class QueryMapper {
|
||||
value = convertId(value);
|
||||
} else if (value instanceof DBObject) {
|
||||
newDbo.put(newKey, getMappedObject((DBObject) value, entity));
|
||||
return newDbo;
|
||||
continue;
|
||||
}
|
||||
|
||||
newDbo.put(newKey, converter.convertToMongoType(value));
|
||||
|
||||
@@ -56,7 +56,8 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
public SimpleMongoDbFactory(Mongo mongo, String databaseName) {
|
||||
Assert.notNull(mongo, "Mongo must not be null");
|
||||
Assert.hasText(databaseName, "Database name must not be empty");
|
||||
Assert.isTrue(databaseName.matches("[\\w-]+"), "Database name must only contain letters, numbers, underscores and dashes!");
|
||||
Assert.isTrue(databaseName.matches("[\\w-]+"),
|
||||
"Database name must only contain letters, numbers, underscores and dashes!");
|
||||
this.mongo = mongo;
|
||||
this.databaseName = databaseName;
|
||||
}
|
||||
@@ -73,7 +74,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
this.username = userCredentials.getUsername();
|
||||
this.password = userCredentials.getPassword();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimpleMongoDbFactory} instance from the given {@link MongoURI}.
|
||||
*
|
||||
@@ -82,7 +83,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
* @throws UnknownHostException
|
||||
* @see MongoURI
|
||||
*/
|
||||
public SimpleMongoDbFactory(MongoURI uri) throws MongoException, UnknownHostException {
|
||||
public SimpleMongoDbFactory(MongoURI uri) throws MongoException, UnknownHostException {
|
||||
this(new Mongo(uri), uri.getDatabase(), new UserCredentials(uri.getUsername(), parseChars(uri.getPassword())));
|
||||
}
|
||||
|
||||
@@ -94,7 +95,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
public void setWriteConcern(WriteConcern writeConcern) {
|
||||
this.writeConcern = writeConcern;
|
||||
}
|
||||
|
||||
|
||||
public WriteConcern getWriteConcern() {
|
||||
return writeConcern;
|
||||
}
|
||||
@@ -130,7 +131,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
public void destroy() throws Exception {
|
||||
mongo.close();
|
||||
}
|
||||
|
||||
|
||||
public static String parseChars(char[] chars) {
|
||||
if (chars == null) {
|
||||
return null;
|
||||
|
||||
@@ -24,14 +24,16 @@ import com.mongodb.WriteConcern;
|
||||
* Return the passed in default WriteConcern (a property on MongoAction) if no determination can be made.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface WriteConcernResolver {
|
||||
|
||||
/**
|
||||
* Resolve the WriteConcern given the MongoAction
|
||||
* @param action describes the context of the Mongo action. Contains a default WriteConcern to use if one should not be resolved.
|
||||
* @return a WriteConcern based on the passed in MongoAction value, maybe null
|
||||
*/
|
||||
WriteConcern resolve(MongoAction action);
|
||||
/**
|
||||
* Resolve the WriteConcern given the MongoAction
|
||||
*
|
||||
* @param action describes the context of the Mongo action. Contains a default WriteConcern to use if one should not
|
||||
* be resolved.
|
||||
* @return a WriteConcern based on the passed in MongoAction value, maybe null
|
||||
*/
|
||||
WriteConcern resolve(MongoAction action);
|
||||
}
|
||||
|
||||
@@ -36,8 +36,10 @@ import org.springframework.data.convert.WritingConverter;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BinaryToUUIDConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.UUIDToBinaryConverter;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -89,6 +91,8 @@ public class CustomConversions {
|
||||
this.converters.add(StringToBigDecimalConverter.INSTANCE);
|
||||
this.converters.add(BigIntegerToStringConverter.INSTANCE);
|
||||
this.converters.add(StringToBigIntegerConverter.INSTANCE);
|
||||
this.converters.add(UUIDToBinaryConverter.INSTANCE);
|
||||
this.converters.add(BinaryToUUIDConverter.INSTANCE);
|
||||
this.converters.addAll(converters);
|
||||
|
||||
for (Object c : this.converters) {
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.mongodb.core.convert;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.expression.MapAccessor;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* {@link PropertyAccessor} to allow entity based field access to {@link DBObject}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class DBObjectPropertyAccessor extends MapAccessor {
|
||||
|
||||
static MapAccessor INSTANCE = new DBObjectPropertyAccessor();
|
||||
|
||||
@Override
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return new Class[] { DBObject.class };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) {
|
||||
|
||||
Map<String, Object> source = (Map<String, Object>) target;
|
||||
|
||||
Object value = source.get(name);
|
||||
return value == null ? TypedValue.NULL : new TypedValue(value);
|
||||
}
|
||||
}
|
||||
@@ -50,23 +50,22 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper<DBObject> implemen
|
||||
public DefaultMongoTypeMapper() {
|
||||
this(DEFAULT_TYPE_KEY, Arrays.asList(SimpleTypeInformationMapper.INSTANCE));
|
||||
}
|
||||
|
||||
|
||||
public DefaultMongoTypeMapper(String typeKey) {
|
||||
super(new DBObjectTypeAliasAccessor(typeKey));
|
||||
this.typeKey = typeKey;
|
||||
}
|
||||
|
||||
public DefaultMongoTypeMapper(String typeKey, MappingContext<? extends PersistentEntity<?,?>, ?> mappingContext) {
|
||||
|
||||
public DefaultMongoTypeMapper(String typeKey, MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext) {
|
||||
super(new DBObjectTypeAliasAccessor(typeKey), mappingContext, Arrays.asList(SimpleTypeInformationMapper.INSTANCE));
|
||||
this.typeKey = typeKey;
|
||||
}
|
||||
|
||||
|
||||
public DefaultMongoTypeMapper(String typeKey, List<? extends TypeInformationMapper> mappers) {
|
||||
super(new DBObjectTypeAliasAccessor(typeKey), mappers);
|
||||
this.typeKey = typeKey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.MongoTypeMapper#isTypeKey(java.lang.String)
|
||||
@@ -75,7 +74,6 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper<DBObject> implemen
|
||||
return typeKey == null ? false : typeKey.equals(key);
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.DefaultTypeMapper#getFallbackTypeFor(java.lang.Object)
|
||||
*/
|
||||
@@ -83,29 +81,29 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper<DBObject> implemen
|
||||
protected TypeInformation<?> getFallbackTypeFor(DBObject source) {
|
||||
return source instanceof BasicDBList ? LIST_TYPE_INFO : MAP_TYPE_INFO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static final class DBObjectTypeAliasAccessor implements TypeAliasAccessor<DBObject> {
|
||||
|
||||
|
||||
private final String typeKey;
|
||||
|
||||
|
||||
public DBObjectTypeAliasAccessor(String typeKey) {
|
||||
this.typeKey = typeKey;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeAliasAccessor#readAliasFrom(java.lang.Object)
|
||||
*/
|
||||
public Object readAliasFrom(DBObject source) {
|
||||
|
||||
|
||||
if (source instanceof BasicDBList) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return source.get(typeKey);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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.mongodb.core.convert;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PreferredConstructor;
|
||||
import org.springframework.data.mapping.PreferredConstructor.Parameter;
|
||||
import org.springframework.data.mapping.PropertyPath;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.context.PersistentPropertyPath;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Abstraction for a {@link PreferredConstructor} alongside mapping information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class MappedConstructor {
|
||||
|
||||
private final Set<MappedConstructor.MappedParameter> parameters;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappedConstructor} from the given {@link MongoPersistentEntity} and {@link MappingContext}.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
*/
|
||||
public MappedConstructor(MongoPersistentEntity<?> entity,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) {
|
||||
|
||||
Assert.notNull(entity);
|
||||
Assert.notNull(context);
|
||||
|
||||
this.parameters = new HashSet<MappedConstructor.MappedParameter>();
|
||||
|
||||
for (Parameter<?> parameter : entity.getPreferredConstructor().getParameters()) {
|
||||
parameters.add(new MappedParameter(parameter, entity, context));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link PersistentProperty} is referenced in a constructor argument of the
|
||||
* {@link PersistentEntity} backing this {@link MappedConstructor}.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public boolean isConstructorParameter(PersistentProperty<?> property) {
|
||||
|
||||
Assert.notNull(property);
|
||||
|
||||
for (MappedConstructor.MappedParameter parameter : parameters) {
|
||||
if (parameter.maps(property)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MappedParameter} for the given {@link Parameter}.
|
||||
*
|
||||
* @param parameter must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public MappedParameter getFor(Parameter<?> parameter) {
|
||||
|
||||
for (MappedParameter mappedParameter : parameters) {
|
||||
if (mappedParameter.parameter.equals(parameter)) {
|
||||
return mappedParameter;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format("Didn't find a MappedParameter for %s!", parameter.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstraction of a {@link Parameter} alongside mapping information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
static class MappedParameter {
|
||||
|
||||
private final MongoPersistentProperty property;
|
||||
private final Parameter<?> parameter;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappedParameter} for the given {@link Parameter}, {@link MongoPersistentProperty} and
|
||||
* {@link MappingContext}.
|
||||
*
|
||||
* @param parameter must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
*/
|
||||
public MappedParameter(Parameter<?> parameter, MongoPersistentEntity<?> entity,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, ? extends MongoPersistentProperty> context) {
|
||||
|
||||
Assert.notNull(parameter);
|
||||
Assert.notNull(entity);
|
||||
Assert.notNull(context);
|
||||
|
||||
this.parameter = parameter;
|
||||
|
||||
PropertyPath propertyPath = PropertyPath.from(parameter.getName(), entity.getType());
|
||||
PersistentPropertyPath<? extends MongoPersistentProperty> path = context.getPersistentPropertyPath(propertyPath);
|
||||
this.property = path == null ? null : path.getLeafProperty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there is a SpEL expression configured for this parameter.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean hasSpELExpression() {
|
||||
return parameter.getKey() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field name to be used to lookup the value which in turn shall be converted into the constructor
|
||||
* parameter.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getFieldName() {
|
||||
return property.getFieldName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the property backing the {@link Parameter}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public TypeInformation<?> getPropertyTypeInformation() {
|
||||
return property.getTypeInformation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link PersistentProperty} is mapped by the parameter.
|
||||
*
|
||||
* @param property
|
||||
* @return
|
||||
*/
|
||||
public boolean maps(PersistentProperty<?> property) {
|
||||
return this.property.equals(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ import org.springframework.core.convert.support.ConversionServiceFactory;
|
||||
import org.springframework.data.convert.TypeMapper;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.AssociationHandler;
|
||||
import org.springframework.data.mapping.PreferredConstructor;
|
||||
import org.springframework.data.mapping.PreferredConstructor.Parameter;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
@@ -81,6 +81,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
protected ApplicationContext applicationContext;
|
||||
protected boolean useFieldAccessOnly = true;
|
||||
protected MongoTypeMapper typeMapper;
|
||||
protected String mapKeyDotReplacement = null;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingMongoConverter} given the new {@link MongoDbFactory} and {@link MappingContext}.
|
||||
@@ -116,6 +117,18 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
mappingContext) : typeMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the characters dots potentially contained in a {@link Map} shall be replaced with. By default we don't do
|
||||
* any translation but rather reject a {@link Map} with keys containing dots causing the conversion for the entire
|
||||
* object to fail. If further customization of the translation is needed, have a look at
|
||||
* {@link #potentiallyEscapeMapKey(String)} as well as {@link #potentiallyUnescapeMapKey(String)}.
|
||||
*
|
||||
* @param mapKeyDotReplacement the mapKeyDotReplacement to set
|
||||
*/
|
||||
public void setMapKeyDotReplacement(String mapKeyDotReplacement) {
|
||||
this.mapKeyDotReplacement = mapKeyDotReplacement;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.EntityConverter#getMappingContext()
|
||||
@@ -164,7 +177,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
if (conversions.hasCustomReadTarget(dbo.getClass(), rawType)) {
|
||||
return conversionService.convert(dbo, rawType);
|
||||
}
|
||||
|
||||
|
||||
if (DBObject.class.isAssignableFrom(rawType)) {
|
||||
return (S) dbo;
|
||||
}
|
||||
@@ -189,52 +202,17 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
private <S extends Object> S read(final MongoPersistentEntity<S> entity, final DBObject dbo) {
|
||||
|
||||
final StandardEvaluationContext spelCtx = new StandardEvaluationContext();
|
||||
if (null != applicationContext) {
|
||||
final StandardEvaluationContext spelCtx = new StandardEvaluationContext(dbo);
|
||||
spelCtx.addPropertyAccessor(DBObjectPropertyAccessor.INSTANCE);
|
||||
|
||||
if (applicationContext != null) {
|
||||
spelCtx.setBeanResolver(new BeanFactoryResolver(applicationContext));
|
||||
}
|
||||
if (!(dbo instanceof BasicDBList)) {
|
||||
String[] keySet = dbo.keySet().toArray(new String[dbo.keySet().size()]);
|
||||
for (String key : keySet) {
|
||||
spelCtx.setVariable(key, dbo.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
final List<String> ctorParamNames = new ArrayList<String>();
|
||||
final MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
final MappedConstructor constructor = new MappedConstructor(entity, mappingContext);
|
||||
|
||||
ParameterValueProvider provider = new SpELAwareParameterValueProvider(spelExpressionParser, spelCtx) {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getParameterValue(PreferredConstructor.Parameter<T> parameter) {
|
||||
|
||||
if (parameter.getKey() != null) {
|
||||
return super.getParameterValue(parameter);
|
||||
}
|
||||
|
||||
String name = parameter.getName();
|
||||
TypeInformation<T> type = parameter.getType();
|
||||
Class<T> rawType = parameter.getRawType();
|
||||
String key = idProperty == null ? name : idProperty.getName().equals(name) ? idProperty.getFieldName() : name;
|
||||
Object obj = dbo.get(key);
|
||||
|
||||
ctorParamNames.add(name);
|
||||
if (obj instanceof DBRef) {
|
||||
return read(type, ((DBRef) obj).fetch());
|
||||
} else if (obj instanceof BasicDBList) {
|
||||
BasicDBList objAsDbList = (BasicDBList) obj;
|
||||
return conversionService.convert(readCollectionOrArray(type, objAsDbList), rawType);
|
||||
} else if (obj instanceof DBObject) {
|
||||
return read(type, ((DBObject) obj));
|
||||
} else if (null != obj && obj.getClass().isAssignableFrom(rawType)) {
|
||||
return (T) obj;
|
||||
} else if (null != obj) {
|
||||
return conversionService.convert(obj, rawType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
SpELAwareParameterValueProvider delegate = new SpELAwareParameterValueProvider(spelExpressionParser, spelCtx);
|
||||
ParameterValueProvider provider = new DelegatingParameterValueProvider(constructor, dbo, delegate);
|
||||
|
||||
final BeanWrapper<MongoPersistentEntity<S>, S> wrapper = BeanWrapper.create(entity, provider, conversionService);
|
||||
|
||||
@@ -242,7 +220,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||
public void doWithPersistentProperty(MongoPersistentProperty prop) {
|
||||
|
||||
boolean isConstructorProperty = ctorParamNames.contains(prop.getName());
|
||||
boolean isConstructorProperty = constructor.isConstructorParameter(prop);
|
||||
boolean hasValueForProperty = dbo.containsField(prop.getFieldName());
|
||||
|
||||
if (!hasValueForProperty || isConstructorProperty) {
|
||||
@@ -286,7 +264,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
boolean handledByCustomConverter = conversions.getCustomWriteTarget(obj.getClass(), DBObject.class) != null;
|
||||
TypeInformation<? extends Object> type = ClassTypeInformation.from(obj.getClass());
|
||||
|
||||
|
||||
if (!handledByCustomConverter && !(dbo instanceof BasicDBList)) {
|
||||
typeMapper.writeType(type, dbo);
|
||||
}
|
||||
@@ -345,7 +323,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
// Write the ID
|
||||
final MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
if (!dbo.containsField("_id") && null != idProperty) {
|
||||
|
||||
|
||||
try {
|
||||
Object id = wrapper.getProperty(idProperty, Object.class, useFieldAccessOnly);
|
||||
dbo.put("_id", idMapper.convertId(id));
|
||||
@@ -356,13 +334,13 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
// Write the properties
|
||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||
public void doWithPersistentProperty(MongoPersistentProperty prop) {
|
||||
|
||||
|
||||
if (prop.equals(idProperty)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Object propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
||||
|
||||
|
||||
if (null != propertyObj) {
|
||||
if (!conversions.isSimpleType(propertyObj.getClass())) {
|
||||
writePropertyInternal(propertyObj, dbo, prop);
|
||||
@@ -499,13 +477,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
for (Object element : source) {
|
||||
|
||||
if (element == null) {
|
||||
continue;
|
||||
}
|
||||
Class<?> elementType = element == null ? null : element.getClass();
|
||||
|
||||
Class<?> elementType = element.getClass();
|
||||
|
||||
if (conversions.isSimpleType(elementType)) {
|
||||
if (elementType == null || conversions.isSimpleType(elementType)) {
|
||||
sink.add(getPotentiallyConvertedSimpleWrite(element));
|
||||
} else if (element instanceof Collection || elementType.isArray()) {
|
||||
sink.add(writeCollectionInternal(asCollection(element), componentType, new BasicDBList()));
|
||||
@@ -528,14 +502,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
* @return
|
||||
*/
|
||||
protected DBObject writeMapInternal(Map<Object, Object> obj, DBObject dbo, TypeInformation<?> propertyType) {
|
||||
|
||||
|
||||
for (Map.Entry<Object, Object> entry : obj.entrySet()) {
|
||||
Object key = entry.getKey();
|
||||
Object val = entry.getValue();
|
||||
if (conversions.isSimpleType(key.getClass())) {
|
||||
// Don't use conversion service here as removal of ObjectToString converter results in some primitive types not
|
||||
// being convertable
|
||||
String simpleKey = key.toString();
|
||||
String simpleKey = potentiallyEscapeMapKey(key.toString());
|
||||
if (val == null || conversions.isSimpleType(val.getClass())) {
|
||||
writeSimpleInternal(val, dbo, simpleKey);
|
||||
} else if (val instanceof Collection || val.getClass().isArray()) {
|
||||
@@ -543,7 +517,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
writeCollectionInternal(asCollection(val), propertyType.getMapValueType(), new BasicDBList()));
|
||||
} else {
|
||||
DBObject newDbo = new BasicDBObject();
|
||||
TypeInformation<?> valueTypeInfo = propertyType.isMap() ? propertyType.getMapValueType() : ClassTypeInformation.OBJECT;
|
||||
TypeInformation<?> valueTypeInfo = propertyType.isMap() ? propertyType.getMapValueType()
|
||||
: ClassTypeInformation.OBJECT;
|
||||
writeInternal(val, newDbo, valueTypeInfo);
|
||||
dbo.put(simpleKey, newDbo);
|
||||
}
|
||||
@@ -551,10 +526,43 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
throw new MappingException("Cannot use a complex object as a key value.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return dbo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Potentially replaces dots in the given map key with the configured map key replacement if configured or aborts
|
||||
* conversion if none is configured.
|
||||
*
|
||||
* @see #setMapKeyDotReplacement(String)
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
protected String potentiallyEscapeMapKey(String source) {
|
||||
|
||||
if (!source.contains(".")) {
|
||||
return source;
|
||||
}
|
||||
|
||||
if (mapKeyDotReplacement == null) {
|
||||
throw new MappingException(String.format("Map key %s contains dots but no replacement was configured! Make "
|
||||
+ "sure map keys don't contain dots in the first place or configure an appropriate replacement!", source));
|
||||
}
|
||||
|
||||
return source.replaceAll("\\.", mapKeyDotReplacement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the map key replacements in the given key just read with a dot in case a map key replacement has been
|
||||
* configured.
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
protected String potentiallyUnescapeMapKey(String source) {
|
||||
return mapKeyDotReplacement == null ? source : source.replaceAll(mapKeyDotReplacement, "\\.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds custom type information to the given {@link DBObject} if necessary. That is if the value is not the same as
|
||||
* the one given. This is usually the case if you store a subtype of the actual declared type of the property.
|
||||
@@ -643,7 +651,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
MongoPersistentProperty idProperty = targetEntity.getIdProperty();
|
||||
BeanWrapper<MongoPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(target, conversionService);
|
||||
Object id = wrapper.getProperty(idProperty, Object.class, useFieldAccessOnly);
|
||||
|
||||
|
||||
if (null == id) {
|
||||
throw new MappingException("Cannot create a reference to an object with a NULL id.");
|
||||
}
|
||||
@@ -696,7 +704,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
(BasicDBList) sourceValue);
|
||||
}
|
||||
|
||||
TypeInformation<?> toType = typeMapper.readType((DBObject) sourceValue);
|
||||
TypeInformation<?> toType = typeMapper.readType((DBObject) sourceValue, prop.getTypeInformation());
|
||||
|
||||
// It's a complex object, have to read it in
|
||||
if (toType != null) {
|
||||
@@ -725,8 +733,11 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
Assert.notNull(targetType);
|
||||
|
||||
Class<?> collectionType = targetType.getType();
|
||||
collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class;
|
||||
|
||||
Collection<Object> items = targetType.getType().isArray() ? new ArrayList<Object>() : CollectionFactory
|
||||
.createCollection(targetType.getType(), sourceValue.size());
|
||||
.createCollection(collectionType, sourceValue.size());
|
||||
|
||||
for (int i = 0; i < sourceValue.size(); i++) {
|
||||
Object dbObjItem = sourceValue.get(i);
|
||||
@@ -735,7 +746,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
} else if (dbObjItem instanceof DBObject) {
|
||||
items.add(read(targetType.getComponentType(), (DBObject) dbObjItem));
|
||||
} else {
|
||||
items.add(getPotentiallyConvertedSimpleRead(dbObjItem, targetType.getComponentType().getType()));
|
||||
TypeInformation<?> componentType = targetType.getComponentType();
|
||||
items.add(getPotentiallyConvertedSimpleRead(dbObjItem, componentType == null ? null : componentType.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -763,12 +775,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
continue;
|
||||
}
|
||||
|
||||
Object key = entry.getKey();
|
||||
Object key = potentiallyUnescapeMapKey(entry.getKey());
|
||||
|
||||
TypeInformation<?> keyTypeInformation = type.getComponentType();
|
||||
if (keyTypeInformation != null) {
|
||||
Class<?> keyType = keyTypeInformation.getType();
|
||||
key = conversionService.convert(entry.getKey(), keyType);
|
||||
key = conversionService.convert(key, keyType);
|
||||
}
|
||||
|
||||
Object value = entry.getValue();
|
||||
@@ -858,7 +870,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
}
|
||||
return newDbl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes the type information from the conversion result.
|
||||
*
|
||||
@@ -895,4 +907,55 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
private class DelegatingParameterValueProvider implements ParameterValueProvider {
|
||||
|
||||
private final DBObject source;
|
||||
private final ParameterValueProvider delegate;
|
||||
private final MappedConstructor constructor;
|
||||
|
||||
/**
|
||||
* {@link ParameterValueProvider} to delegate source object lookup to a {@link SpELAwareParameterValueProvider} in
|
||||
* case a MappCon
|
||||
*
|
||||
* @param constructor must not be {@literal null}.
|
||||
* @param source must not be {@literal null}.
|
||||
* @param delegate must not be {@literal null}.
|
||||
*/
|
||||
public DelegatingParameterValueProvider(MappedConstructor constructor, DBObject source,
|
||||
SpELAwareParameterValueProvider delegate) {
|
||||
|
||||
Assert.notNull(constructor);
|
||||
Assert.notNull(source);
|
||||
Assert.notNull(delegate);
|
||||
|
||||
this.constructor = constructor;
|
||||
this.source = source;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.model.ParameterValueProvider#getParameterValue(org.springframework.data.mapping.PreferredConstructor.Parameter)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getParameterValue(Parameter<T> parameter) {
|
||||
|
||||
MappedConstructor.MappedParameter mappedParameter = constructor.getFor(parameter);
|
||||
Object value = mappedParameter.hasSpELExpression() ? delegate.getParameterValue(parameter) : source
|
||||
.get(mappedParameter.getFieldName());
|
||||
|
||||
TypeInformation<?> type = mappedParameter.getPropertyTypeInformation();
|
||||
|
||||
if (value instanceof DBRef) {
|
||||
return (T) read(type, ((DBRef) value).fetch());
|
||||
} else if (value instanceof BasicDBList) {
|
||||
return (T) getPotentiallyConvertedSimpleRead(readCollectionOrArray(type, (BasicDBList) value), type.getType());
|
||||
} else if (value instanceof DBObject) {
|
||||
return (T) read(type, (DBObject) value);
|
||||
} else {
|
||||
return (T) getPotentiallyConvertedSimpleRead(value, type.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -15,11 +15,18 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bson.BSON;
|
||||
import org.bson.types.Binary;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -119,4 +126,52 @@ abstract class MongoConverters {
|
||||
return StringUtils.hasText(source) ? new BigInteger(source) : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom {@link Converter} to convert {@link UUID}s into {@link Binary}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static enum UUIDToBinaryConverter implements Converter<UUID, Binary> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
public Binary convert(UUID source) {
|
||||
|
||||
try {
|
||||
return source == null ? null : new Binary(BSON.B_UUID, source.toString().getBytes("UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new MappingException(String.format("Could nor convert UUID %s into Binary!", source.toString()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static enum BinaryToUUIDConverter implements Converter<Binary, UUID> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(BinaryToUUIDConverter.class);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
public UUID convert(Binary source) {
|
||||
|
||||
if (BSON.B_UUID != source.getType()) {
|
||||
LOG.warn(String.format("Source binary %s is not an UUID actually! Trying to read it nevertheless...",
|
||||
source.toString()));
|
||||
}
|
||||
|
||||
try {
|
||||
return source == null ? null : UUID.fromString(new String(source.getData(), "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new MappingException(String.format("Could not convert Binary %s into UUID!", source.toString()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class Box implements Shape {
|
||||
list.add(getUpperRight().asList());
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
||||
@@ -74,7 +74,7 @@ public class Box implements Shape {
|
||||
public String getCommand() {
|
||||
return "$box";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Box [%s, %s]", first, second);
|
||||
|
||||
@@ -40,10 +40,10 @@ public class Circle implements Shape {
|
||||
*/
|
||||
@PersistenceConstructor
|
||||
public Circle(Point center, double radius) {
|
||||
|
||||
|
||||
Assert.notNull(center);
|
||||
Assert.isTrue(radius >= 0, "Radius must not be negative!");
|
||||
|
||||
|
||||
this.center = center;
|
||||
this.radius = radius;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class Circle implements Shape {
|
||||
public double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#asList()
|
||||
@@ -87,7 +87,7 @@ public class Circle implements Shape {
|
||||
result.add(getRadius());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
||||
@@ -104,26 +104,26 @@ public class Circle implements Shape {
|
||||
public String toString() {
|
||||
return String.format("Circle [center=%s, radius=%f]", center, radius);
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Circle that = (Circle) obj;
|
||||
|
||||
|
||||
return this.center.equals(that.center) && this.radius == that.radius;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
|
||||
@@ -50,22 +50,22 @@ public class Polygon implements Shape, Iterable<Point> {
|
||||
this.points.addAll(Arrays.asList(x, y, z));
|
||||
this.points.addAll(Arrays.asList(others));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#asList()
|
||||
*/
|
||||
public List<List<Double>> asList() {
|
||||
|
||||
|
||||
List<List<Double>> result = new ArrayList<List<Double>>();
|
||||
|
||||
|
||||
for (Point point : points) {
|
||||
result.add(point.asList());
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
||||
@@ -73,7 +73,7 @@ public class Polygon implements Shape, Iterable<Point> {
|
||||
public String getCommand() {
|
||||
return "$polygon";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Iterable#iterator()
|
||||
@@ -88,20 +88,20 @@ public class Polygon implements Shape, Iterable<Point> {
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Polygon that = (Polygon) obj;
|
||||
|
||||
|
||||
return this.points.equals(that.points);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Common interface for all shapes. Allows building MongoDB representations of them.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface Shape {
|
||||
@@ -31,7 +31,7 @@ public interface Shape {
|
||||
* @return
|
||||
*/
|
||||
List<? extends Object> asList();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the command to be used to create the {@literal $within} criterion.
|
||||
*
|
||||
|
||||
@@ -31,7 +31,6 @@ public class IndexInfo {
|
||||
|
||||
private boolean sparse = false;
|
||||
|
||||
|
||||
public IndexInfo(Map<String, Order> fieldSpec, String name, boolean unique, boolean dropDuplicates, boolean sparse) {
|
||||
super();
|
||||
this.fieldSpec = fieldSpec;
|
||||
@@ -107,9 +106,8 @@ public class IndexInfo {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* [{ "v" : 1 , "key" : { "_id" : 1} , "ns" : "database.person" , "name" : "_id_"},
|
||||
{ "v" : 1 , "key" : { "age" : -1} , "ns" : "database.person" , "name" : "age_-1" , "unique" : true , "dropDups" : true}]
|
||||
* [{ "v" : 1 , "key" : { "_id" : 1} , "ns" : "database.person" , "name" : "_id_"}, { "v" : 1 , "key" : { "age" : -1}
|
||||
* , "ns" : "database.person" , "name" : "age_-1" , "unique" : true , "dropDups" : true}]
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
|
||||
/**
|
||||
* An implementation of ApplicationEventPublisher that will only fire MappingContextEvents for use by the index creator when
|
||||
* MongoTemplate is used 'stand-alone', that is not declared inside a Spring ApplicationContext.
|
||||
* An implementation of ApplicationEventPublisher that will only fire MappingContextEvents for use by the index creator
|
||||
* when MongoTemplate is used 'stand-alone', that is not declared inside a Spring ApplicationContext.
|
||||
*
|
||||
* Declare MongoTemplate inside an ApplicationContext to enable the publishing of all persistence events such as
|
||||
* {@link AfterLoadEvent}, {@link AfterSaveEvent}, etc.
|
||||
*
|
||||
* Declare MongoTemplate inside an ApplicationContext to enable the publishing of all persistence events such as
|
||||
* {@link AfterLoadEvent}, {@link AfterSaveEvent}, etc.
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class MongoMappingEventPublisher implements ApplicationEventPublisher {
|
||||
|
||||
@@ -30,7 +30,8 @@ import org.springframework.data.util.TypeInformation;
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Oliver Gierke ogierke@vmware.com
|
||||
*/
|
||||
public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersistentEntity<?>, MongoPersistentProperty> implements ApplicationContextAware {
|
||||
public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersistentEntity<?>, MongoPersistentProperty>
|
||||
implements ApplicationContextAware {
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
@@ -57,16 +58,16 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
|
||||
*/
|
||||
@Override
|
||||
protected <T> BasicMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
|
||||
|
||||
BasicMongoPersistentEntity<T> entity = new BasicMongoPersistentEntity<T>(typeInformation);
|
||||
|
||||
|
||||
if (context != null) {
|
||||
entity.setApplicationContext(context);
|
||||
}
|
||||
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bson.types.Binary;
|
||||
import org.bson.types.CodeWScope;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
@@ -36,7 +37,7 @@ import com.mongodb.DBRef;
|
||||
public abstract class MongoSimpleTypes {
|
||||
|
||||
public static final Set<Class<?>> AUTOGENERATED_ID_TYPES;
|
||||
|
||||
|
||||
static {
|
||||
Set<Class<?>> classes = new HashSet<Class<?>>();
|
||||
classes.add(ObjectId.class);
|
||||
@@ -50,6 +51,7 @@ public abstract class MongoSimpleTypes {
|
||||
simpleTypes.add(CodeWScope.class);
|
||||
simpleTypes.add(DBObject.class);
|
||||
simpleTypes.add(Pattern.class);
|
||||
simpleTypes.add(Binary.class);
|
||||
MONGO_SIMPLE_TYPES = Collections.unmodifiableSet(simpleTypes);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
|
||||
|
||||
protected final Log LOG = LogFactory.getLog(getClass());
|
||||
private final Class<?> domainClass;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link AbstractMongoEventListener}.
|
||||
*/
|
||||
|
||||
@@ -39,9 +39,9 @@ public class AfterLoadEvent<T> extends MongoMappingEvent<DBObject> {
|
||||
* @param type must not be {@literal null}.
|
||||
*/
|
||||
public AfterLoadEvent(DBObject dbo, Class<T> type) {
|
||||
|
||||
|
||||
super(dbo, dbo);
|
||||
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@@ -19,24 +19,19 @@ import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Collects the parameters required to perform a group operation on a collection. The query condition and the input collection are specified on the group method as method arguments
|
||||
* to be consistent with other operations, e.g. map-reduce.
|
||||
* Collects the parameters required to perform a group operation on a collection. The query condition and the input
|
||||
* collection are specified on the group method as method arguments to be consistent with other operations, e.g.
|
||||
* map-reduce.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*/
|
||||
public class GroupBy {
|
||||
|
||||
private DBObject dboKeys;
|
||||
|
||||
private String keyFunction;
|
||||
|
||||
private String initial;
|
||||
|
||||
private DBObject initialDbObject;
|
||||
|
||||
private String reduce;
|
||||
|
||||
private String finalize;
|
||||
|
||||
public GroupBy(String... keys) {
|
||||
@@ -71,24 +66,22 @@ public class GroupBy {
|
||||
initial = initialDocument;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public GroupBy initialDocument(DBObject initialDocument) {
|
||||
initialDbObject = initialDocument;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public GroupBy reduceFunction(String reduceFunction) {
|
||||
reduce = reduceFunction;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public GroupBy finalizeFunction(String finalizeFunction) {
|
||||
finalize = finalizeFunction;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public DBObject getGroupByObject() {
|
||||
// return new GroupCommand(dbCollection, dboKeys, condition, initial, reduce, finalize);
|
||||
BasicDBObject dbo = new BasicDBObject();
|
||||
@@ -100,19 +93,15 @@ public class GroupBy {
|
||||
}
|
||||
|
||||
dbo.put("$reduce", reduce);
|
||||
|
||||
dbo.put("initial", initialDbObject);
|
||||
|
||||
dbo.put("initial", initialDbObject);
|
||||
if (initial != null) {
|
||||
dbo.put("initial", initial);
|
||||
}
|
||||
if (finalize != null) {
|
||||
dbo.put("finalize", finalize);
|
||||
}
|
||||
return dbo;
|
||||
return dbo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -26,31 +26,27 @@ import com.mongodb.DBObject;
|
||||
* Collects the results of executing a group operation.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
* @param <T> The class in which the results are mapped onto, accessible via an interator.
|
||||
*/
|
||||
public class GroupByResults<T> implements Iterable<T> {
|
||||
|
||||
private final List<T> mappedResults;
|
||||
|
||||
private DBObject rawResults;
|
||||
|
||||
private final DBObject rawResults;
|
||||
|
||||
private double count;
|
||||
|
||||
private int keys;
|
||||
|
||||
private String serverUsed;
|
||||
|
||||
|
||||
public GroupByResults(List<T> mappedResults, DBObject rawResults) {
|
||||
Assert.notNull(mappedResults);
|
||||
Assert.notNull(rawResults);
|
||||
this.mappedResults = mappedResults;
|
||||
this.rawResults = rawResults;
|
||||
parseKeys();
|
||||
parseKeys();
|
||||
parseCount();
|
||||
parseServerUsed();
|
||||
}
|
||||
|
||||
|
||||
public double getCount() {
|
||||
return count;
|
||||
}
|
||||
@@ -58,36 +54,36 @@ public class GroupByResults<T> implements Iterable<T> {
|
||||
public int getKeys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
|
||||
public String getServerUsed() {
|
||||
return serverUsed;
|
||||
}
|
||||
|
||||
public Iterator<T> iterator() {
|
||||
return mappedResults.iterator();
|
||||
return mappedResults.iterator();
|
||||
}
|
||||
|
||||
|
||||
public DBObject getRawResults() {
|
||||
return rawResults;
|
||||
}
|
||||
|
||||
|
||||
private void parseCount() {
|
||||
Object object = rawResults.get("count");
|
||||
if (object instanceof Double) {
|
||||
count = (Double) object;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void parseKeys() {
|
||||
Object object = rawResults.get("keys");
|
||||
if (object instanceof Integer) {
|
||||
keys = (Integer) object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void parseServerUsed() {
|
||||
//"serverUsed" : "127.0.0.1:27017"
|
||||
// "serverUsed" : "127.0.0.1:27017"
|
||||
Object object = rawResults.get("serverUsed");
|
||||
if (object instanceof String) {
|
||||
serverUsed = (String) object;
|
||||
|
||||
@@ -15,13 +15,14 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapreduce;
|
||||
|
||||
/**
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
public class MapReduceCounts {
|
||||
|
||||
private int inputCount;
|
||||
|
||||
private int emitCount;
|
||||
|
||||
private int outputCount;
|
||||
private final int inputCount;
|
||||
private final int emitCount;
|
||||
private final int outputCount;
|
||||
|
||||
public MapReduceCounts(int inputCount, int emitCount, int outputCount) {
|
||||
super();
|
||||
@@ -42,12 +43,20 @@ public class MapReduceCounts {
|
||||
return outputCount;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MapReduceCounts [inputCount=" + inputCount + ", emitCount=" + emitCount + ", outputCount=" + outputCount
|
||||
+ "]";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
@@ -58,24 +67,31 @@ public class MapReduceCounts {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
if (this == obj) {
|
||||
return true;
|
||||
if (obj == null)
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
MapReduceCounts other = (MapReduceCounts) obj;
|
||||
if (emitCount != other.emitCount)
|
||||
if (emitCount != other.emitCount) {
|
||||
return false;
|
||||
if (inputCount != other.inputCount)
|
||||
}
|
||||
if (inputCount != other.inputCount) {
|
||||
return false;
|
||||
if (outputCount != other.outputCount)
|
||||
}
|
||||
if (outputCount != other.outputCount) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -39,10 +39,9 @@ public class MapReduceOptions {
|
||||
private Boolean jsMode;
|
||||
|
||||
private Boolean verbose = true;
|
||||
|
||||
|
||||
private Map<String, Object> extraOptions = new HashMap<String, Object>();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Static factory method to create a MapReduceOptions instance
|
||||
*
|
||||
@@ -189,12 +188,12 @@ public class MapReduceOptions {
|
||||
this.verbose = verbose;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add additional extra options that may not have a method on this class. This method will help if you use a
|
||||
* version of this client library with a server version that has added additional map-reduce options that do not
|
||||
* yet have an method for use in setting them.
|
||||
* options
|
||||
* Add additional extra options that may not have a method on this class. This method will help if you use a version
|
||||
* of this client library with a server version that has added additional map-reduce options that do not yet have an
|
||||
* method for use in setting them. options
|
||||
*
|
||||
* @param key The key option
|
||||
* @param value The value of the option
|
||||
* @return MapReduceOptions so that methods can be chained in a fluent API style
|
||||
@@ -203,40 +202,39 @@ public class MapReduceOptions {
|
||||
extraOptions.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Object> getExtraOptions() {
|
||||
return extraOptions;
|
||||
return extraOptions;
|
||||
}
|
||||
|
||||
|
||||
public String getFinalizeFunction() {
|
||||
return this.finalizeFunction;
|
||||
}
|
||||
|
||||
|
||||
public Boolean getJavaScriptMode() {
|
||||
return this.jsMode;
|
||||
}
|
||||
|
||||
|
||||
public String getOutputCollection() {
|
||||
return this.outputCollection;
|
||||
}
|
||||
|
||||
|
||||
public String getOutputDatabase() {
|
||||
return this.outputDatabase;
|
||||
}
|
||||
|
||||
|
||||
public Boolean getOutputSharded() {
|
||||
return this.outputSharded;
|
||||
}
|
||||
|
||||
|
||||
public MapReduceCommand.OutputType getOutputType() {
|
||||
return this.outputType;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Object> getScopeVariables() {
|
||||
return this.scopeVariables;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public DBObject getOptionsObject() {
|
||||
BasicDBObject cmd = new BasicDBObject();
|
||||
|
||||
@@ -253,7 +251,7 @@ public class MapReduceOptions {
|
||||
if (scopeVariables != null) {
|
||||
cmd.put("scope", scopeVariables);
|
||||
}
|
||||
|
||||
|
||||
if (!extraOptions.keySet().isEmpty()) {
|
||||
cmd.putAll(extraOptions);
|
||||
}
|
||||
|
||||
@@ -24,77 +24,77 @@ import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Collects the results of performing a MapReduce operations.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*
|
||||
* @param <T> The class in which the results are mapped onto, accessible via an interator.
|
||||
*/
|
||||
public class MapReduceResults<T> implements Iterable<T> {
|
||||
|
||||
private final List<T> mappedResults;
|
||||
|
||||
|
||||
private DBObject rawResults;
|
||||
|
||||
private MapReduceTiming mapReduceTiming;
|
||||
|
||||
|
||||
private MapReduceCounts mapReduceCounts;
|
||||
|
||||
|
||||
private String outputCollection;
|
||||
|
||||
|
||||
public MapReduceResults(List<T> mappedResults, DBObject rawResults) {
|
||||
Assert.notNull(mappedResults);
|
||||
Assert.notNull(rawResults);
|
||||
this.mappedResults = mappedResults;
|
||||
this.rawResults = rawResults;
|
||||
parseTiming(rawResults);
|
||||
parseCounts(rawResults);
|
||||
parseCounts(rawResults);
|
||||
if (rawResults.get("result") != null) {
|
||||
this.outputCollection = (String) rawResults.get("result");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Iterator<T> iterator() {
|
||||
return mappedResults.iterator();
|
||||
return mappedResults.iterator();
|
||||
}
|
||||
|
||||
|
||||
public MapReduceTiming getTiming() {
|
||||
return mapReduceTiming;
|
||||
}
|
||||
|
||||
|
||||
public MapReduceCounts getCounts() {
|
||||
return mapReduceCounts;
|
||||
}
|
||||
|
||||
|
||||
public String getOutputCollection() {
|
||||
return outputCollection;
|
||||
}
|
||||
|
||||
|
||||
public DBObject getRawResults() {
|
||||
return rawResults;
|
||||
}
|
||||
|
||||
|
||||
protected void parseTiming(DBObject rawResults) {
|
||||
DBObject timing = (DBObject) rawResults.get("timing");
|
||||
if (timing != null) {
|
||||
if (timing.get("mapTime") != null && timing.get("emitLoop") != null && timing.get("total") != null) {
|
||||
mapReduceTiming = new MapReduceTiming( (Long)timing.get("mapTime"),
|
||||
(Integer)timing.get("emitLoop"),
|
||||
(Integer)timing.get("total"));
|
||||
mapReduceTiming = new MapReduceTiming((Long) timing.get("mapTime"), (Integer) timing.get("emitLoop"),
|
||||
(Integer) timing.get("total"));
|
||||
}
|
||||
} else {
|
||||
mapReduceTiming = new MapReduceTiming(-1,-1,-1);
|
||||
mapReduceTiming = new MapReduceTiming(-1, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void parseCounts(DBObject rawResults) {
|
||||
DBObject counts = (DBObject) rawResults.get("counts");
|
||||
if (counts != null) {
|
||||
if (counts.get("input") != null && counts.get("emit") != null && counts.get("output") != null) {
|
||||
mapReduceCounts = new MapReduceCounts( (Integer)counts.get("input"), (Integer)counts.get("emit"), (Integer)counts.get("output"));
|
||||
mapReduceCounts = new MapReduceCounts((Integer) counts.get("input"), (Integer) counts.get("emit"),
|
||||
(Integer) counts.get("output"));
|
||||
}
|
||||
} else {
|
||||
mapReduceCounts = new MapReduceCounts(-1,-1,-1);
|
||||
mapReduceCounts = new MapReduceCounts(-1, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.data.mongodb.core.mapreduce;
|
||||
public class MapReduceTiming {
|
||||
|
||||
private long mapTime;
|
||||
|
||||
|
||||
private long emitLoopTime;
|
||||
|
||||
|
||||
private long totalTime;
|
||||
|
||||
|
||||
public MapReduceTiming(long mapTime, long emitLoopTime, long totalTime) {
|
||||
this.mapTime = mapTime;
|
||||
this.emitLoopTime = emitLoopTime;
|
||||
this.totalTime = totalTime;
|
||||
this.totalTime = totalTime;
|
||||
}
|
||||
|
||||
public long getMapTime() {
|
||||
@@ -73,8 +73,5 @@ public class MapReduceTiming {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Static factory method to create a Criteria using the provided key
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@@ -79,7 +79,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Static factory method to create a Criteria using the provided key
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Criteria and(String key) {
|
||||
@@ -88,7 +88,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using equality
|
||||
*
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
@@ -106,7 +106,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $ne operator
|
||||
*
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
@@ -117,7 +117,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $lt operator
|
||||
*
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
@@ -128,7 +128,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $lte operator
|
||||
*
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
@@ -139,7 +139,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $gt operator
|
||||
*
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
@@ -150,7 +150,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $gte operator
|
||||
*
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
@@ -161,7 +161,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $in operator
|
||||
*
|
||||
*
|
||||
* @param o the values to match against
|
||||
* @return
|
||||
*/
|
||||
@@ -176,7 +176,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $in operator
|
||||
*
|
||||
*
|
||||
* @param c the collection containing the values to match against
|
||||
* @return
|
||||
*/
|
||||
@@ -187,7 +187,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $nin operator
|
||||
*
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
@@ -202,7 +202,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $mod operator
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* @param remainder
|
||||
* @return
|
||||
@@ -217,7 +217,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $all operator
|
||||
*
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
@@ -232,7 +232,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $size operator
|
||||
*
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
@@ -243,7 +243,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $exists operator
|
||||
*
|
||||
*
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
@@ -254,7 +254,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $type operator
|
||||
*
|
||||
*
|
||||
* @param t
|
||||
* @return
|
||||
*/
|
||||
@@ -265,7 +265,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $not meta operator which affects the clause directly following
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Criteria not() {
|
||||
@@ -275,7 +275,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using a $regex
|
||||
*
|
||||
*
|
||||
* @param re
|
||||
* @return
|
||||
*/
|
||||
@@ -286,7 +286,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using a $regex and $options
|
||||
*
|
||||
*
|
||||
* @param re
|
||||
* @param options
|
||||
* @return
|
||||
@@ -301,7 +301,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $within $center operation. This is only available for Mongo 1.7 and higher.
|
||||
*
|
||||
*
|
||||
* @param circle must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
@@ -320,7 +320,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $near operation
|
||||
*
|
||||
*
|
||||
* @param point must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
@@ -332,7 +332,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a geospatial criterion using a $nearSphere operation. This is only available for Mongo 1.7 and higher.
|
||||
*
|
||||
*
|
||||
* @param point must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
@@ -344,7 +344,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a geospatical criterion using a $maxDistance operation, for use with $near
|
||||
*
|
||||
*
|
||||
* @param maxDistance
|
||||
* @return
|
||||
*/
|
||||
@@ -355,7 +355,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a criterion using the $elemMatch operator
|
||||
*
|
||||
*
|
||||
* @param c
|
||||
* @return
|
||||
*/
|
||||
@@ -366,7 +366,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates an 'or' criteria using the $or operator for all of the provided criteria
|
||||
*
|
||||
*
|
||||
* @param criteria
|
||||
*/
|
||||
public Criteria orOperator(Criteria... criteria) {
|
||||
@@ -377,7 +377,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates a 'nor' criteria using the $nor operator for all of the provided criteria
|
||||
*
|
||||
*
|
||||
* @param criteria
|
||||
*/
|
||||
public Criteria norOperator(Criteria... criteria) {
|
||||
@@ -388,7 +388,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates an 'and' criteria using the $and operator for all of the provided criteria
|
||||
*
|
||||
*
|
||||
* @param criteria
|
||||
*/
|
||||
public Criteria andOperator(Criteria... criteria) {
|
||||
@@ -397,7 +397,6 @@ public class Criteria implements CriteriaDefinition {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
@@ -462,11 +461,10 @@ public class Criteria implements CriteriaDefinition {
|
||||
Object existing = dbo.get(key);
|
||||
if (existing == null) {
|
||||
dbo.put(key, value);
|
||||
}
|
||||
else {
|
||||
throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDBObject, " +
|
||||
"you can't add a second '" + key + "' expression specified as '" + key + " : " + value + "'. " +
|
||||
"Criteria already contains '" + key + " : " + existing + "'.");
|
||||
} else {
|
||||
throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDBObject, "
|
||||
+ "you can't add a second '" + key + "' expression specified as '" + key + " : " + value + "'. "
|
||||
+ "Criteria already contains '" + key + " : " + existing + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public class Query {
|
||||
|
||||
/**
|
||||
* Static factory method to create a Query using the provided criteria
|
||||
*
|
||||
*
|
||||
* @param critera
|
||||
* @return
|
||||
*/
|
||||
@@ -56,11 +56,10 @@ public class Query {
|
||||
String key = criteria.getKey();
|
||||
if (existing == null) {
|
||||
this.criteria.put(key, criteria);
|
||||
}
|
||||
else {
|
||||
throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDBObject, " +
|
||||
"you can't add a second '" + key + "' criteria. " +
|
||||
"Query already contains '" + existing.getCriteriaObject() + "'.");
|
||||
} else {
|
||||
throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDBObject, "
|
||||
+ "you can't add a second '" + key + "' criteria. " + "Query already contains '"
|
||||
+ existing.getCriteriaObject() + "'.");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -93,12 +92,12 @@ public class Query {
|
||||
this.hint = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Sort sort() {
|
||||
if (this.sort == null) {
|
||||
this.sort = new Sort();
|
||||
}
|
||||
|
||||
|
||||
return this.sort;
|
||||
}
|
||||
|
||||
@@ -137,7 +136,7 @@ public class Query {
|
||||
public String getHint() {
|
||||
return hint;
|
||||
}
|
||||
|
||||
|
||||
protected List<Criteria> getCriteria() {
|
||||
return new ArrayList<Criteria>(this.criteria.values());
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class MongoRepositoryConfigParser extends
|
||||
protected void postProcessBeanDefinition(MongoRepositoryConfiguration context, BeanDefinitionBuilder builder,
|
||||
BeanDefinitionRegistry registry, Object beanSource) {
|
||||
|
||||
builder.addPropertyReference("template", context.getMongoTemplateRef());
|
||||
builder.addPropertyReference("mongoOperations", context.getMongoTemplateRef());
|
||||
builder.addPropertyValue("createIndexesForQueryMethods", context.getCreateQueryIndexes());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import static org.springframework.data.mongodb.repository.query.QueryUtils.applyPagination;
|
||||
import static org.springframework.data.mongodb.repository.query.QueryUtils.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.GeoPage;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResult;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
@@ -34,10 +34,6 @@ import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Base class for {@link RepositoryQuery} implementations for Mongo.
|
||||
*
|
||||
@@ -46,42 +42,47 @@ import com.mongodb.DBObject;
|
||||
public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
|
||||
private final MongoQueryMethod method;
|
||||
private final MongoOperations mongoOperations;
|
||||
private final MongoOperations operations;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AbstractMongoQuery} from the given {@link MongoQueryMethod} and {@link MongoOperations}.
|
||||
*
|
||||
* @param method
|
||||
* @param template
|
||||
* @param method must not be {@literal null}.
|
||||
* @param operations must not be {@literal null}.
|
||||
*/
|
||||
public AbstractMongoQuery(MongoQueryMethod method, MongoOperations template) {
|
||||
public AbstractMongoQuery(MongoQueryMethod method, MongoOperations operations) {
|
||||
|
||||
Assert.notNull(template);
|
||||
Assert.notNull(operations);
|
||||
Assert.notNull(method);
|
||||
|
||||
this.method = method;
|
||||
this.mongoOperations = template;
|
||||
this.operations = operations;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#getQueryMethod()
|
||||
*/
|
||||
public MongoQueryMethod getQueryMethod() {
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java .lang.Object[])
|
||||
*/
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[])
|
||||
*/
|
||||
public Object execute(Object[] parameters) {
|
||||
|
||||
MongoParameterAccessor accessor = new MongoParametersParameterAccessor(method, parameters);
|
||||
Query query = createQuery(new ConvertingParameterAccessor(mongoOperations.getConverter(), accessor));
|
||||
Query query = createQuery(new ConvertingParameterAccessor(operations.getConverter(), accessor));
|
||||
|
||||
if (method.isGeoNearQuery()) {
|
||||
if (method.isGeoNearQuery() && method.isPageQuery()) {
|
||||
|
||||
MongoParameterAccessor countAccessor = new MongoParametersParameterAccessor(method, parameters);
|
||||
Query countQuery = createCountQuery(new ConvertingParameterAccessor(operations.getConverter(), countAccessor));
|
||||
|
||||
return new GeoNearExecution(accessor).execute(query, countQuery);
|
||||
} else if (method.isGeoNearQuery()) {
|
||||
return new GeoNearExecution(accessor).execute(query);
|
||||
} else if (method.isCollectionQuery()) {
|
||||
return new CollectionExecution().execute(query);
|
||||
@@ -93,14 +94,25 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link Query} instance using the given {@link ParameterAccessor}
|
||||
* Creates a {@link Query} instance using the given {@link ParameterAccessor}
|
||||
*
|
||||
* @param accessor
|
||||
* @param converter
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
protected abstract Query createQuery(ConvertingParameterAccessor accessor);
|
||||
|
||||
/**
|
||||
* Creates a {@link Query} instance using the given {@link ConvertingParameterAccessor}. Will delegate to
|
||||
* {@link #createQuery(ConvertingParameterAccessor)} by default but allows customization of the count query to be
|
||||
* triggered.
|
||||
*
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
protected Query createCountQuery(ConvertingParameterAccessor accessor) {
|
||||
return createQuery(accessor);
|
||||
}
|
||||
|
||||
private abstract class Execution {
|
||||
|
||||
abstract Object execute(Query query);
|
||||
@@ -110,7 +122,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
MongoEntityInformation<?, ?> metadata = method.getEntityInformation();
|
||||
|
||||
String collectionName = metadata.getCollectionName();
|
||||
return mongoOperations.find(query, metadata.getJavaType(), collectionName);
|
||||
return operations.find(query, metadata.getJavaType(), collectionName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,13 +134,11 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
class CollectionExecution extends Execution {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.mongodb.repository.MongoQuery.Execution #execute(com.mongodb.DBObject)
|
||||
*/
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.query.Query)
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Query query) {
|
||||
|
||||
return readCollection(query);
|
||||
}
|
||||
}
|
||||
@@ -162,24 +172,13 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
Object execute(Query query) {
|
||||
|
||||
MongoEntityInformation<?, ?> metadata = method.getEntityInformation();
|
||||
int count = getCollectionCursor(metadata.getCollectionName(), query.getQueryObject()).count();
|
||||
long count = operations.count(query, metadata.getCollectionName());
|
||||
|
||||
List<?> result = mongoOperations.find(applyPagination(query, pageable), metadata.getJavaType(),
|
||||
List<?> result = operations.find(applyPagination(query, pageable), metadata.getJavaType(),
|
||||
metadata.getCollectionName());
|
||||
|
||||
return new PageImpl(result, pageable, count);
|
||||
}
|
||||
|
||||
private DBCursor getCollectionCursor(String collectionName, final DBObject query) {
|
||||
|
||||
return mongoOperations.execute(collectionName, new CollectionCallback<DBCursor>() {
|
||||
|
||||
public DBCursor doInCollection(DBCollection collection) {
|
||||
|
||||
return collection.find(query);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,19 +196,19 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
Object execute(Query query) {
|
||||
|
||||
MongoEntityInformation<?, ?> entityInformation = method.getEntityInformation();
|
||||
return mongoOperations.findOne(query, entityInformation.getJavaType());
|
||||
return operations.findOne(query, entityInformation.getJavaType());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Execution} to execute geo-near queries.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class GeoNearExecution extends Execution {
|
||||
|
||||
|
||||
private final MongoParameterAccessor accessor;
|
||||
|
||||
|
||||
public GeoNearExecution(MongoParameterAccessor accessor) {
|
||||
this.accessor = accessor;
|
||||
}
|
||||
@@ -220,27 +219,48 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
*/
|
||||
@Override
|
||||
Object execute(Query query) {
|
||||
|
||||
|
||||
GeoResults<?> results = doExecuteQuery(query);
|
||||
return isListOfGeoResult() ? results.getContent() : results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given {@link Query} to return a page.
|
||||
*
|
||||
* @param query must not be {@literal null}.
|
||||
* @param countQuery must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
Object execute(Query query, Query countQuery) {
|
||||
|
||||
MongoEntityInformation<?, ?> information = method.getEntityInformation();
|
||||
long count = operations.count(countQuery, information.getCollectionName());
|
||||
|
||||
return new GeoPage<Object>(doExecuteQuery(query), accessor.getPageable(), count);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private GeoResults<Object> doExecuteQuery(Query query) {
|
||||
|
||||
Point nearLocation = accessor.getGeoNearLocation();
|
||||
NearQuery nearQuery = NearQuery.near(nearLocation);
|
||||
|
||||
|
||||
if (query != null) {
|
||||
nearQuery.query(query);
|
||||
}
|
||||
|
||||
|
||||
Distance maxDistance = accessor.getMaxDistance();
|
||||
if (maxDistance != null) {
|
||||
nearQuery.maxDistance(maxDistance);
|
||||
}
|
||||
|
||||
MongoEntityInformation<?,?> entityInformation = method.getEntityInformation();
|
||||
GeoResults<?> results = mongoOperations.geoNear(nearQuery, entityInformation.getJavaType(), entityInformation.getCollectionName());
|
||||
|
||||
return isListOfGeoResult() ? results.getContent() : results;
|
||||
|
||||
MongoEntityInformation<?, ?> entityInformation = method.getEntityInformation();
|
||||
return (GeoResults<Object>) operations.geoNear(nearQuery, entityInformation.getJavaType(),
|
||||
entityInformation.getCollectionName());
|
||||
}
|
||||
|
||||
|
||||
private boolean isListOfGeoResult() {
|
||||
|
||||
|
||||
TypeInformation<?> returnType = method.getReturnType();
|
||||
return returnType.getType().equals(List.class) && GeoResult.class.equals(returnType.getComponentType());
|
||||
}
|
||||
|
||||
@@ -42,10 +42,10 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
|
||||
* @param delegate must not be {@literal null}.
|
||||
*/
|
||||
public ConvertingParameterAccessor(MongoWriter<?> writer, MongoParameterAccessor delegate) {
|
||||
|
||||
|
||||
Assert.notNull(writer);
|
||||
Assert.notNull(delegate);
|
||||
|
||||
|
||||
this.writer = writer;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
@@ -92,7 +92,7 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
|
||||
public Distance getMaxDistance() {
|
||||
return delegate.getMaxDistance();
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getGeoNearLocation()
|
||||
*/
|
||||
|
||||
@@ -17,10 +17,9 @@ package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* Interface for components being able to provide {@link EntityInformationCreator} for a given {@link Class}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface EntityInformationCreator {
|
||||
|
||||
@@ -33,7 +33,7 @@ public interface MongoParameterAccessor extends ParameterAccessor {
|
||||
* at all or the given value for it was {@literal null}.
|
||||
*/
|
||||
Distance getMaxDistance();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the {@link Point} to use for a geo-near query.
|
||||
*
|
||||
|
||||
@@ -35,7 +35,7 @@ public class MongoParameters extends Parameters {
|
||||
|
||||
private final Integer distanceIndex;
|
||||
private Integer nearIndex;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoParameters} instance from the given {@link Method} and {@link MongoQueryMethod}.
|
||||
*
|
||||
@@ -43,55 +43,56 @@ public class MongoParameters extends Parameters {
|
||||
* @param queryMethod must not be {@literal null}.
|
||||
*/
|
||||
public MongoParameters(Method method, boolean isGeoNearMethod) {
|
||||
|
||||
|
||||
super(method);
|
||||
List<Class<?>> parameterTypes = Arrays.asList(method.getParameterTypes());
|
||||
this.distanceIndex = parameterTypes.indexOf(Distance.class);
|
||||
|
||||
|
||||
if (this.nearIndex == null && isGeoNearMethod) {
|
||||
this.nearIndex = getNearIndex(parameterTypes);
|
||||
} else if (this.nearIndex == null) {
|
||||
this.nearIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final int getNearIndex(List<Class<?>> parameterTypes) {
|
||||
|
||||
|
||||
for (Class<?> reference : Arrays.asList(Point.class, double[].class)) {
|
||||
|
||||
|
||||
int nearIndex = parameterTypes.indexOf(reference);
|
||||
|
||||
|
||||
if (nearIndex == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (nearIndex == parameterTypes.lastIndexOf(reference)) {
|
||||
return nearIndex;
|
||||
} else {
|
||||
throw new IllegalStateException("Multiple Point parameters found but none annotated with @Near!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.Parameters#createParameter(org.springframework.core.MethodParameter)
|
||||
*/
|
||||
@Override
|
||||
protected Parameter createParameter(MethodParameter parameter) {
|
||||
|
||||
|
||||
MongoParameter mongoParameter = new MongoParameter(parameter);
|
||||
|
||||
|
||||
// Detect manually annotated @Near Point and reject multiple annotated ones
|
||||
if (this.nearIndex == null && mongoParameter.isManuallyAnnotatedNearParameter()) {
|
||||
this.nearIndex = mongoParameter.getIndex();
|
||||
} else if (mongoParameter.isManuallyAnnotatedNearParameter()) {
|
||||
throw new IllegalStateException(String.format("Found multiple @Near annotations ond method %s! Only one allowed!", parameter.getMethod().toString()));
|
||||
throw new IllegalStateException(String.format(
|
||||
"Found multiple @Near annotations ond method %s! Only one allowed!", parameter.getMethod().toString()));
|
||||
}
|
||||
|
||||
|
||||
return mongoParameter;
|
||||
}
|
||||
|
||||
@@ -103,7 +104,7 @@ public class MongoParameters extends Parameters {
|
||||
public int getDistanceIndex() {
|
||||
return distanceIndex;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the index of the parameter to be used to start a geo-near query from.
|
||||
*
|
||||
@@ -112,16 +113,16 @@ public class MongoParameters extends Parameters {
|
||||
public int getNearIndex() {
|
||||
return nearIndex;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom {@link Parameter} implementation adding parameters of type {@link Distance} to the special ones.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class MongoParameter extends Parameter {
|
||||
|
||||
|
||||
private final MethodParameter parameter;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoParameter}.
|
||||
*
|
||||
@@ -130,7 +131,7 @@ public class MongoParameters extends Parameters {
|
||||
MongoParameter(MethodParameter parameter) {
|
||||
super(parameter);
|
||||
this.parameter = parameter;
|
||||
|
||||
|
||||
if (!isPoint() && hasNearAnnotation()) {
|
||||
throw new IllegalArgumentException("Near annotation is only allowed at Point parameter!");
|
||||
}
|
||||
@@ -142,23 +143,22 @@ public class MongoParameters extends Parameters {
|
||||
*/
|
||||
@Override
|
||||
public boolean isSpecialParameter() {
|
||||
return super.isSpecialParameter() || getType().equals(Distance.class)
|
||||
|| isNearParameter();
|
||||
return super.isSpecialParameter() || getType().equals(Distance.class) || isNearParameter();
|
||||
}
|
||||
|
||||
|
||||
private boolean isNearParameter() {
|
||||
Integer nearIndex = MongoParameters.this.nearIndex;
|
||||
return nearIndex != null && nearIndex.equals(getIndex());
|
||||
}
|
||||
|
||||
|
||||
private boolean isManuallyAnnotatedNearParameter() {
|
||||
return isPoint() && hasNearAnnotation();
|
||||
}
|
||||
|
||||
|
||||
private boolean isPoint() {
|
||||
return getType().equals(Point.class) || getType().equals(double[].class);
|
||||
}
|
||||
|
||||
|
||||
private boolean hasNearAnnotation() {
|
||||
return parameter.getParameterAnnotation(Near.class) != null;
|
||||
}
|
||||
|
||||
@@ -21,13 +21,13 @@ import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
|
||||
/**
|
||||
* Mongo-specific {@link ParametersParameterAccessor} to allow access to the {@link Distance} parameter.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoParametersParameterAccessor extends ParametersParameterAccessor implements MongoParameterAccessor {
|
||||
|
||||
private final MongoQueryMethod method;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoParametersParameterAccessor}.
|
||||
*
|
||||
@@ -47,25 +47,25 @@ public class MongoParametersParameterAccessor extends ParametersParameterAccesso
|
||||
int index = method.getParameters().getDistanceIndex();
|
||||
return index == -1 ? null : (Distance) getValue(index);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getGeoNearLocation()
|
||||
*/
|
||||
public Point getGeoNearLocation() {
|
||||
|
||||
|
||||
int nearIndex = method.getParameters().getNearIndex();
|
||||
|
||||
|
||||
if (nearIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Object value = getValue(nearIndex);
|
||||
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (value instanceof double[]) {
|
||||
double[] typedValue = (double[]) value;
|
||||
if (typedValue.length != 2) {
|
||||
@@ -74,7 +74,7 @@ public class MongoParametersParameterAccessor extends ParametersParameterAccesso
|
||||
return new Point(typedValue[0], typedValue[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (Point) value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +203,8 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
||||
case NEAR:
|
||||
|
||||
Distance distance = accessor.getMaxDistance();
|
||||
Point point = nextAs(parameters, Point.class);
|
||||
Point point = accessor.getGeoNearLocation();
|
||||
point = point == null ? nextAs(parameters, Point.class) : point;
|
||||
|
||||
if (distance == null) {
|
||||
return criteria.near(point);
|
||||
|
||||
@@ -38,8 +38,8 @@ public class PartTreeMongoQuery extends AbstractMongoQuery {
|
||||
/**
|
||||
* Creates a new {@link PartTreeMongoQuery} from the given {@link QueryMethod} and {@link MongoTemplate}.
|
||||
*
|
||||
* @param method
|
||||
* @param template
|
||||
* @param method must not be {@literal null}.
|
||||
* @param template must not be {@literal null}.
|
||||
*/
|
||||
public PartTreeMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations) {
|
||||
|
||||
@@ -50,6 +50,8 @@ public class PartTreeMongoQuery extends AbstractMongoQuery {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link PartTree} backing the query.
|
||||
*
|
||||
* @return the tree
|
||||
*/
|
||||
public PartTree getTree() {
|
||||
@@ -57,16 +59,22 @@ public class PartTreeMongoQuery extends AbstractMongoQuery {
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.mongodb.repository.AbstractMongoQuery#createQuery(org.springframework.data.
|
||||
* document.mongodb.repository.ConvertingParameterAccessor)
|
||||
*/
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery#createQuery(org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor, boolean)
|
||||
*/
|
||||
@Override
|
||||
protected Query createQuery(ConvertingParameterAccessor accessor) {
|
||||
|
||||
MongoQueryCreator creator = new MongoQueryCreator(tree, accessor, context, isGeoNearQuery);
|
||||
return creator.createQuery();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery#createCountQuery(org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor)
|
||||
*/
|
||||
@Override
|
||||
protected Query createCountQuery(ConvertingParameterAccessor accessor) {
|
||||
return new MongoQueryCreator(tree, accessor, context, false).createQuery();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
} else {
|
||||
query = new BasicQuery(queryString);
|
||||
}
|
||||
|
||||
|
||||
QueryUtils.applySorting(query, accessor.getSort());
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
@@ -99,8 +99,12 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
}
|
||||
|
||||
private String getParameterWithIndex(ConvertingParameterAccessor accessor, int index) {
|
||||
|
||||
Object parameter = accessor.getBindableValue(index);
|
||||
if (parameter instanceof String || parameter.getClass().isEnum()) {
|
||||
|
||||
if (parameter == null) {
|
||||
return "null";
|
||||
} else if (parameter instanceof String || parameter.getClass().isEnum()) {
|
||||
return String.format("\"%s\"", parameter);
|
||||
} else if (parameter instanceof ObjectId) {
|
||||
return String.format("{ '$oid' : '%s' }", parameter);
|
||||
|
||||
@@ -25,7 +25,8 @@ import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple {@link EntityInformationCreator} to to create {@link MongoEntityInformation} instances based on a {@link MappingContext}.
|
||||
* Simple {@link EntityInformationCreator} to to create {@link MongoEntityInformation} instances based on a
|
||||
* {@link MappingContext}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
|
||||
@@ -44,7 +44,7 @@ class IndexEnsuringQueryCreationListener implements QueryCreationListener<PartTr
|
||||
|
||||
private static final Set<Type> GEOSPATIAL_TYPES = new HashSet<Type>(Arrays.asList(Type.NEAR, Type.WITHIN));
|
||||
private static final Log LOG = LogFactory.getLog(IndexEnsuringQueryCreationListener.class);
|
||||
|
||||
|
||||
private final MongoOperations operations;
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.data.mongodb.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
|
||||
@@ -32,17 +32,17 @@ import org.springframework.util.Assert;
|
||||
public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends
|
||||
RepositoryFactoryBeanSupport<T, S, ID> {
|
||||
|
||||
private MongoTemplate template;
|
||||
private MongoOperations operations;
|
||||
private boolean createIndexesForQueryMethods = false;
|
||||
|
||||
/**
|
||||
* Configures the {@link MongoTemplate} to be used.
|
||||
* Configures the {@link MongoOperations} to be used.
|
||||
*
|
||||
* @param template the template to set
|
||||
* @param operations the operations to set
|
||||
*/
|
||||
public void setTemplate(MongoTemplate template) {
|
||||
public void setMongoOperations(MongoOperations operations) {
|
||||
|
||||
this.template = template;
|
||||
this.operations = operations;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,10 +64,10 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
|
||||
@Override
|
||||
protected final RepositoryFactorySupport createRepositoryFactory() {
|
||||
|
||||
RepositoryFactorySupport factory = getFactoryInstance(template);
|
||||
RepositoryFactorySupport factory = getFactoryInstance(operations);
|
||||
|
||||
if (createIndexesForQueryMethods) {
|
||||
factory.addQueryCreationListener(new IndexEnsuringQueryCreationListener(template));
|
||||
factory.addQueryCreationListener(new IndexEnsuringQueryCreationListener(operations));
|
||||
}
|
||||
|
||||
return factory;
|
||||
@@ -76,11 +76,11 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
|
||||
/**
|
||||
* Creates and initializes a {@link RepositoryFactorySupport} instance.
|
||||
*
|
||||
* @param template
|
||||
* @param operations
|
||||
* @return
|
||||
*/
|
||||
protected RepositoryFactorySupport getFactoryInstance(MongoTemplate template) {
|
||||
return new MongoRepositoryFactory(template);
|
||||
protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {
|
||||
return new MongoRepositoryFactory(operations);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -94,6 +94,6 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
super.afterPropertiesSet();
|
||||
Assert.notNull(template, "MongoTemplate must not be null!");
|
||||
Assert.notNull(operations, "MongoTemplate must not be null!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
||||
Path<?> parent = metadata.getParent();
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(parent.getType());
|
||||
MongoPersistentProperty property = entity.getPersistentProperty(metadata.getExpression().toString());
|
||||
return property.getFieldName();
|
||||
return property == null ? super.getKeyForPath(expr, metadata) : property.getFieldName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -61,12 +61,10 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#save(java.lang.Object)
|
||||
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Object)
|
||||
*/
|
||||
public T save(T entity) {
|
||||
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null!");
|
||||
|
||||
mongoOperations.save(entity, entityInformation.getCollectionName());
|
||||
@@ -75,14 +73,12 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#save(java.lang.Iterable)
|
||||
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
|
||||
*/
|
||||
public List<T> save(Iterable<? extends T> entities) {
|
||||
|
||||
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
||||
|
||||
|
||||
List<T> result = new ArrayList<T>();
|
||||
|
||||
for (T entity : entities) {
|
||||
@@ -95,10 +91,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#findById(java.io.Serializable
|
||||
* )
|
||||
* @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable)
|
||||
*/
|
||||
public T findOne(ID id) {
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
@@ -115,10 +108,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#exists(java.io.Serializable
|
||||
* )
|
||||
* @see org.springframework.data.repository.CrudRepository#exists(java.io.Serializable)
|
||||
*/
|
||||
public boolean exists(ID id) {
|
||||
|
||||
@@ -129,8 +119,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository#count()
|
||||
* @see org.springframework.data.repository.CrudRepository#count()
|
||||
*/
|
||||
public long count() {
|
||||
|
||||
@@ -139,7 +128,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.Repository#delete(java.io.Serializable)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.io.Serializable)
|
||||
*/
|
||||
public void delete(ID id) {
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
@@ -148,9 +137,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#delete(java.lang.Object)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.lang.Object)
|
||||
*/
|
||||
public void delete(T entity) {
|
||||
Assert.notNull(entity, "The given entity must not be null!");
|
||||
@@ -159,14 +146,12 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#delete(java.lang.Iterable)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.lang.Iterable)
|
||||
*/
|
||||
public void delete(Iterable<? extends T> entities) {
|
||||
|
||||
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
||||
|
||||
|
||||
for (T entity : entities) {
|
||||
delete(entity);
|
||||
}
|
||||
@@ -174,8 +159,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository#deleteAll()
|
||||
* @see org.springframework.data.repository.CrudRepository#deleteAll()
|
||||
*/
|
||||
public void deleteAll() {
|
||||
|
||||
@@ -184,8 +168,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository#findAll()
|
||||
* @see org.springframework.data.repository.CrudRepository#findAll()
|
||||
*/
|
||||
public List<T> findAll() {
|
||||
|
||||
@@ -194,10 +177,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.PagingAndSortingRepository#findAll
|
||||
* (org.springframework.data.domain.Pageable)
|
||||
* @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Pageable)
|
||||
*/
|
||||
public Page<T> findAll(final Pageable pageable) {
|
||||
|
||||
@@ -209,43 +189,13 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.PagingAndSortingRepository#findAll
|
||||
* (org.springframework.data.domain.Sort)
|
||||
* @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
|
||||
*/
|
||||
public List<T> findAll(final Sort sort) {
|
||||
|
||||
return findAll(QueryUtils.applySorting(new Query(), sort));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.Repository#findAll(java.lang.Iterable
|
||||
* )
|
||||
*/
|
||||
public List<T> findAll(Iterable<ID> ids) {
|
||||
|
||||
Query query = null;
|
||||
|
||||
//TODO: verify intent
|
||||
// for (ID id : ids) {
|
||||
// if (query == null) {
|
||||
// query = getIdQuery(id);
|
||||
// } else {
|
||||
// query = new Query().or(getIdQuery(id));
|
||||
// }
|
||||
// }
|
||||
List<ID> idList = new ArrayList<ID>();
|
||||
for (ID id : ids) {
|
||||
idList.add(id);
|
||||
}
|
||||
query = new Query(Criteria.where(entityInformation.getIdAttribute()).in(idList));
|
||||
return findAll(query);
|
||||
}
|
||||
|
||||
private List<T> findAll(Query query) {
|
||||
|
||||
if (query == null) {
|
||||
|
||||
@@ -7,16 +7,14 @@
|
||||
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"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" />
|
||||
<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"/>
|
||||
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"/>
|
||||
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd" />
|
||||
|
||||
<xsd:element name="mongo" type="mongoType">
|
||||
<xsd:annotation>
|
||||
|
||||
@@ -42,10 +42,9 @@ import com.mongodb.DBObject;
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingMongoConverterParserIntegrationTests {
|
||||
|
||||
|
||||
DefaultListableBeanFactory factory;
|
||||
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
factory = new DefaultListableBeanFactory();
|
||||
@@ -55,26 +54,26 @@ public class MappingMongoConverterParserIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void allowsDbFactoryRefAttribute() {
|
||||
|
||||
|
||||
factory.getBeanDefinition("converter");
|
||||
factory.getBean("converter");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void scansForConverterAndSetsUpCustomConversionsAccordingly() {
|
||||
|
||||
|
||||
CustomConversions conversions = factory.getBean(CustomConversions.class);
|
||||
assertThat(conversions.hasCustomWriteTarget(Person.class), is(true));
|
||||
assertThat(conversions.hasCustomWriteTarget(Account.class), is(true));
|
||||
}
|
||||
|
||||
|
||||
@Component
|
||||
public static class SampleConverter implements Converter<Person, DBObject> {
|
||||
public DBObject convert(Person source) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component
|
||||
public static class SampleConverterFactory implements GenericConverter {
|
||||
|
||||
|
||||
@@ -29,17 +29,17 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MongoDbFactory}.
|
||||
*
|
||||
*
|
||||
* @author Thomas Risbergf
|
||||
*/
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class MongoDbFactoryNoDatabaseRunningTests {
|
||||
|
||||
|
||||
@Autowired
|
||||
MongoTemplate mongoTemplate;
|
||||
|
||||
|
||||
/**
|
||||
* @see DATADOC-139
|
||||
*/
|
||||
@@ -47,7 +47,7 @@ public class MongoDbFactoryNoDatabaseRunningTests {
|
||||
public void startsUpWithoutADatabaseRunning() {
|
||||
assertThat(mongoTemplate.getClass().getName(), is("org.springframework.data.mongodb.core.MongoTemplate"));
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = DataAccessResourceFailureException.class)
|
||||
public void failsDataAccessWithoutADatabaseRunning() {
|
||||
mongoTemplate.getCollectionNames();
|
||||
|
||||
@@ -40,14 +40,14 @@ import com.mongodb.WriteConcern;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MongoDbFactoryParser}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoDbFactoryParserIntegrationTests {
|
||||
|
||||
|
||||
DefaultListableBeanFactory factory;
|
||||
BeanDefinitionReader reader;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
factory = new DefaultListableBeanFactory();
|
||||
@@ -61,29 +61,30 @@ public class MongoDbFactoryParserIntegrationTests {
|
||||
dbFactory.getDb();
|
||||
assertThat(WriteConcern.SAFE, is(dbFactory.getWriteConcern()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void parsesWriteConcern() {
|
||||
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("namespace/db-factory-bean.xml");
|
||||
assertWriteConcern(ctx, WriteConcern.SAFE);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void parsesCustomWriteConcern() {
|
||||
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("namespace/db-factory-bean-custom-write-concern.xml");
|
||||
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
|
||||
"namespace/db-factory-bean-custom-write-concern.xml");
|
||||
assertWriteConcern(ctx, new WriteConcern("rack1"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-331
|
||||
*/
|
||||
@Test
|
||||
public void readsReplicasWriteConcernCorrectly() {
|
||||
|
||||
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("namespace/db-factory-bean-custom-write-concern.xml");
|
||||
MongoDbFactory factory = ctx.getBean("second", MongoDbFactory.class);
|
||||
DB db = factory.getDb();
|
||||
|
||||
|
||||
assertThat(db.getWriteConcern(), is(WriteConcern.REPLICAS_SAFE));
|
||||
}
|
||||
|
||||
@@ -96,75 +97,72 @@ public class MongoDbFactoryParserIntegrationTests {
|
||||
MyWriteConcern myDbWriteConcern = new MyWriteConcern(db.getWriteConcern());
|
||||
MyWriteConcern myExpectedWriteConcern = new MyWriteConcern(expectedWriteConcern);
|
||||
|
||||
|
||||
assertThat(myDbFactoryWriteConcern, equalTo(myExpectedWriteConcern));
|
||||
assertThat(myDbWriteConcern, equalTo(myExpectedWriteConcern));
|
||||
assertThat(myDbWriteConcern, equalTo(myDbFactoryWriteConcern));
|
||||
}
|
||||
|
||||
//This test will fail since equals in WriteConcern uses == for _w and not .equals
|
||||
|
||||
// This test will fail since equals in WriteConcern uses == for _w and not .equals
|
||||
public void testWriteConcernEquality() {
|
||||
String s1 = new String("rack1");
|
||||
String s2 = new String("rack1");
|
||||
String s1 = new String("rack1");
|
||||
String s2 = new String("rack1");
|
||||
WriteConcern wc1 = new WriteConcern(s1);
|
||||
WriteConcern wc2 = new WriteConcern(s2);
|
||||
assertThat(wc1, equalTo(wc2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void createsDbFactoryBean() {
|
||||
|
||||
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/db-factory-bean.xml"));
|
||||
factory.getBean("first");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DATADOC-280
|
||||
*/
|
||||
@Test
|
||||
public void parsesMaxAutoConnectRetryTimeCorrectly() {
|
||||
|
||||
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/db-factory-bean.xml"));
|
||||
Mongo mongo = factory.getBean(Mongo.class);
|
||||
assertThat(mongo.getMongoOptions().maxAutoConnectRetryTime, is(27L));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DATADOC-295
|
||||
*/
|
||||
@Test
|
||||
public void setsUpMongoDbFactoryUsingAMongoUri() {
|
||||
|
||||
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/mongo-uri.xml"));
|
||||
BeanDefinition definition = factory.getBeanDefinition("mongoDbFactory");
|
||||
ConstructorArgumentValues constructorArguments = definition.getConstructorArgumentValues();
|
||||
|
||||
|
||||
assertThat(constructorArguments.getArgumentCount(), is(1));
|
||||
ValueHolder argument = constructorArguments.getArgumentValue(0, MongoURI.class);
|
||||
assertThat(argument, is(notNullValue()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DATADOC-306
|
||||
*/
|
||||
@Test
|
||||
public void setsUpMongoDbFactoryUsingAMongoUriWithoutCredentials() {
|
||||
|
||||
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/mongo-uri-no-credentials.xml"));
|
||||
BeanDefinition definition = factory.getBeanDefinition("mongoDbFactory");
|
||||
ConstructorArgumentValues constructorArguments = definition.getConstructorArgumentValues();
|
||||
|
||||
|
||||
assertThat(constructorArguments.getArgumentCount(), is(1));
|
||||
ValueHolder argument = constructorArguments.getArgumentValue(0, MongoURI.class);
|
||||
assertThat(argument, is(notNullValue()));
|
||||
|
||||
|
||||
MongoDbFactory dbFactory = factory.getBean("mongoDbFactory", MongoDbFactory.class);
|
||||
DB db = dbFactory.getDb();
|
||||
assertThat(db.getName(), is("database"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DATADOC-295
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.springframework.data.mongodb.config;
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
public class MyWriteConcern {
|
||||
|
||||
|
||||
public MyWriteConcern(WriteConcern wc) {
|
||||
this._w = wc.getWObject();
|
||||
this._continueOnErrorForInsert = wc.getContinueOnErrorForInsert();
|
||||
@@ -12,11 +12,12 @@ public class MyWriteConcern {
|
||||
this._wtimeout = wc.getWtimeout();
|
||||
}
|
||||
|
||||
Object _w = 0;
|
||||
int _wtimeout = 0;
|
||||
boolean _fsync = false;
|
||||
boolean _j = false;
|
||||
boolean _continueOnErrorForInsert = false;
|
||||
Object _w = 0;
|
||||
int _wtimeout = 0;
|
||||
boolean _fsync = false;
|
||||
boolean _j = false;
|
||||
boolean _continueOnErrorForInsert = false;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
@@ -28,6 +29,7 @@ public class MyWriteConcern {
|
||||
result = prime * result + _wtimeout;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
@@ -52,5 +54,5 @@ public class MyWriteConcern {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -20,24 +20,23 @@ import java.lang.reflect.Field;
|
||||
|
||||
public class NamespaceTestSupport {
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public static <T> T readField(String name, Object target) throws Exception {
|
||||
Field field = null;
|
||||
Class<?> clazz = target.getClass();
|
||||
do {
|
||||
try {
|
||||
field = clazz.getDeclaredField(name);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public static <T> T readField(String name, Object target) throws Exception {
|
||||
Field field = null;
|
||||
Class<?> clazz = target.getClass();
|
||||
do {
|
||||
try {
|
||||
field = clazz.getDeclaredField(name);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
clazz = clazz.getSuperclass();
|
||||
} while (field == null && !clazz.equals(Object.class));
|
||||
|
||||
clazz = clazz.getSuperclass();
|
||||
} while (field == null && !clazz.equals(Object.class));
|
||||
|
||||
if (field == null)
|
||||
throw new IllegalArgumentException("Cannot find field '" + name + "' in the class hierarchy of "
|
||||
+ target.getClass());
|
||||
field.setAccessible(true);
|
||||
return (T) field.get(target);
|
||||
}
|
||||
if (field == null)
|
||||
throw new IllegalArgumentException("Cannot find field '" + name + "' in the class hierarchy of "
|
||||
+ target.getClass());
|
||||
field.setAccessible(true);
|
||||
return (T) field.get(target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
|
||||
public class Friend {
|
||||
|
||||
private String id;
|
||||
|
||||
@@ -23,7 +23,7 @@ import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MongoOptionsFactoryBean}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoOptionsFactoryBeanUnitTests {
|
||||
@@ -33,11 +33,11 @@ public class MongoOptionsFactoryBeanUnitTests {
|
||||
*/
|
||||
@Test
|
||||
public void setsMaxConnectRetryTime() {
|
||||
|
||||
|
||||
MongoOptionsFactoryBean bean = new MongoOptionsFactoryBean();
|
||||
bean.setMaxAutoConnectRetryTime(27);
|
||||
bean.afterPropertiesSet();
|
||||
|
||||
|
||||
MongoOptions options = bean.getObject();
|
||||
assertThat(options.maxAutoConnectRetryTime, is(27L));
|
||||
}
|
||||
|
||||
@@ -1041,7 +1041,7 @@ public class MongoTemplateTests {
|
||||
List<TestClass> testClassList = mappingTemplate.find(new Query(Criteria.where("myDate").is(dateTime.toDate())),
|
||||
TestClass.class);
|
||||
assertThat(testClassList.size(), is(1));
|
||||
assertThat(testClassList.get(0).getMyDate(), is(testClass.getMyDate()));
|
||||
assertThat(testClassList.get(0).myDate, is(testClass.myDate));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1080,23 +1080,19 @@ public class MongoTemplateTests {
|
||||
assertThat(template.findOne(query(where("id").is(id)), Sample.class), is(nullValue()));
|
||||
}
|
||||
|
||||
public class Sample {
|
||||
public static class Sample {
|
||||
|
||||
@Id
|
||||
String id;
|
||||
}
|
||||
|
||||
public class TestClass {
|
||||
static class TestClass {
|
||||
|
||||
private DateTime myDate;
|
||||
DateTime myDate;
|
||||
|
||||
@PersistenceConstructor
|
||||
public TestClass(DateTime date) {
|
||||
this.myDate = date;
|
||||
}
|
||||
|
||||
public DateTime getMyDate() {
|
||||
return myDate;
|
||||
TestClass(DateTime myDate) {
|
||||
this.myDate = myDate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import com.mongodb.DBCursor;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link QueryCursorPreparer}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@@ -41,18 +41,18 @@ public class QueryCursorPreparerUnitTests {
|
||||
MongoDbFactory factory;
|
||||
@Mock
|
||||
DBCursor cursor;
|
||||
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-185
|
||||
*/
|
||||
@Test
|
||||
public void appliesHintsCorrectly() {
|
||||
|
||||
|
||||
Query query = query(where("foo").is("bar")).withHint("hint");
|
||||
|
||||
|
||||
CursorPreparer preparer = new MongoTemplate(factory).new QueryCursorPreparer(query);
|
||||
preparer.prepare(cursor);
|
||||
|
||||
|
||||
verify(cursor).hint("hint");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class SimpleMongoDbFactoryUnitTests {
|
||||
rejectsDatabaseName("foo.bar");
|
||||
rejectsDatabaseName("foo!bar");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DATADOC-254
|
||||
*/
|
||||
@@ -66,16 +66,16 @@ public class SimpleMongoDbFactoryUnitTests {
|
||||
*/
|
||||
@Test
|
||||
public void mongoUriConstructor() throws UnknownHostException {
|
||||
|
||||
|
||||
MongoURI mongoURI = new MongoURI("mongodb://myUsername:myPassword@localhost/myDatabase.myCollection");
|
||||
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoURI);
|
||||
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "username").toString(), is("myUsername"));
|
||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "password").toString(), is("myPassword"));
|
||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
|
||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
|
||||
}
|
||||
|
||||
|
||||
private void rejectsDatabaseName(String databaseName) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -35,5 +35,4 @@ public class TestMongoConfiguration extends AbstractMongoConfiguration {
|
||||
converter.setCustomConversions(new CustomConversions(converters));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,14 +3,17 @@ package org.springframework.data.mongodb.core.convert;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.Format;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bson.types.Binary;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.ConversionServiceFactory;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
|
||||
|
||||
@@ -27,13 +30,13 @@ public class CustomConversionsUnitTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void findsBasicReadAndWriteConversions() {
|
||||
|
||||
CustomConversions conversions = new CustomConversions(Arrays.asList(UuidToStringConverter.INSTANCE,
|
||||
StringToUUIDConverter.INSTANCE));
|
||||
CustomConversions conversions = new CustomConversions(Arrays.asList(FormatToStringConverter.INSTANCE,
|
||||
StringToFormatConverter.INSTANCE));
|
||||
|
||||
assertThat(conversions.getCustomWriteTarget(UUID.class, null), is(typeCompatibleWith(String.class)));
|
||||
assertThat(conversions.getCustomWriteTarget(Format.class, null), is(typeCompatibleWith(String.class)));
|
||||
assertThat(conversions.getCustomWriteTarget(String.class, null), is(nullValue()));
|
||||
|
||||
assertThat(conversions.hasCustomReadTarget(String.class, UUID.class), is(true));
|
||||
assertThat(conversions.hasCustomReadTarget(String.class, Format.class), is(true));
|
||||
assertThat(conversions.hasCustomReadTarget(String.class, Locale.class), is(false));
|
||||
}
|
||||
|
||||
@@ -51,7 +54,7 @@ public class CustomConversionsUnitTests {
|
||||
@Test
|
||||
public void considersTypesWeRegisteredConvertersForAsSimple() {
|
||||
|
||||
CustomConversions conversions = new CustomConversions(Arrays.asList(UuidToStringConverter.INSTANCE));
|
||||
CustomConversions conversions = new CustomConversions(Arrays.asList(FormatToStringConverter.INSTANCE));
|
||||
assertThat(conversions.isSimpleType(UUID.class), is(true));
|
||||
}
|
||||
|
||||
@@ -95,14 +98,13 @@ public class CustomConversionsUnitTests {
|
||||
@Test
|
||||
public void populatesConversionServiceCorrectly() {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
|
||||
GenericConversionService conversionService = new DefaultConversionService();
|
||||
assertThat(conversionService.canConvert(String.class, UUID.class), is(false));
|
||||
|
||||
CustomConversions conversions = new CustomConversions(Arrays.asList(StringToUUIDConverter.INSTANCE));
|
||||
CustomConversions conversions = new CustomConversions(Arrays.asList(StringToFormatConverter.INSTANCE));
|
||||
conversions.registerConvertersIn(conversionService);
|
||||
|
||||
assertThat(conversionService.canConvert(String.class, UUID.class), is(true));
|
||||
assertThat(conversionService.canConvert(String.class, Format.class), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,8 +112,8 @@ public class CustomConversionsUnitTests {
|
||||
*/
|
||||
@Test
|
||||
public void doesNotConsiderTypeSimpleIfOnlyReadConverterIsRegistered() {
|
||||
CustomConversions conversions = new CustomConversions(Arrays.asList(StringToUUIDConverter.INSTANCE));
|
||||
assertThat(conversions.isSimpleType(UUID.class), is(false));
|
||||
CustomConversions conversions = new CustomConversions(Arrays.asList(StringToFormatConverter.INSTANCE));
|
||||
assertThat(conversions.isSimpleType(Format.class), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,18 +142,38 @@ public class CustomConversionsUnitTests {
|
||||
assertThat(conversions.getCustomWriteTarget(String.class), is(nullValue()));
|
||||
}
|
||||
|
||||
enum UuidToStringConverter implements Converter<UUID, String> {
|
||||
/**
|
||||
* @see DATAMONGO-390
|
||||
*/
|
||||
@Test
|
||||
public void considersBinaryASimpleType() {
|
||||
|
||||
CustomConversions conversions = new CustomConversions();
|
||||
assertThat(conversions.isSimpleType(Binary.class), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-390
|
||||
*/
|
||||
@Test
|
||||
public void convertsUUIDsToBinaryByDefault() {
|
||||
|
||||
CustomConversions conversions = new CustomConversions();
|
||||
assertThat(conversions.hasCustomWriteTarget(UUID.class), is(true));
|
||||
}
|
||||
|
||||
enum FormatToStringConverter implements Converter<Format, String> {
|
||||
INSTANCE;
|
||||
|
||||
public String convert(UUID source) {
|
||||
public String convert(Format source) {
|
||||
return source.toString();
|
||||
}
|
||||
}
|
||||
|
||||
enum StringToUUIDConverter implements Converter<String, UUID> {
|
||||
enum StringToFormatConverter implements Converter<String, Format> {
|
||||
INSTANCE;
|
||||
public UUID convert(String source) {
|
||||
return UUID.fromString(source);
|
||||
public Format convert(String source) {
|
||||
return DateFormat.getInstance();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
|
||||
/**
|
||||
* Test case to verify correct usage of custom {@link Converter} implementations to be used.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @see DATADOC-101
|
||||
*/
|
||||
@@ -65,9 +65,9 @@ public class CustomConvertersUnitTests {
|
||||
|
||||
when(barToDBObjectConverter.convert(any(Bar.class))).thenReturn(new BasicDBObject());
|
||||
when(dbObjectToBarConverter.convert(any(DBObject.class))).thenReturn(new Bar());
|
||||
|
||||
|
||||
CustomConversions conversions = new CustomConversions(Arrays.asList(barToDBObjectConverter, dbObjectToBarConverter));
|
||||
|
||||
|
||||
context = new MongoMappingContext();
|
||||
context.setInitialEntitySet(new HashSet<Class<?>>(Arrays.asList(Foo.class, Bar.class)));
|
||||
context.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
|
||||
|
||||
@@ -175,7 +175,7 @@ public class DataDoc273Test {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class Shipment {
|
||||
|
||||
|
||||
Map boxes = new HashMap();
|
||||
|
||||
public Shipment(Map boxes) {
|
||||
|
||||
@@ -38,27 +38,27 @@ public class DefaultMongoTypeMapperUnitTests {
|
||||
|
||||
ConfigurableTypeInformationMapper configurableTypeInformationMapper;
|
||||
SimpleTypeInformationMapper simpleTypeInformationMapper;
|
||||
|
||||
|
||||
|
||||
DefaultMongoTypeMapper typeMapper;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
configurableTypeInformationMapper = new ConfigurableTypeInformationMapper(Collections.singletonMap(String.class, "1"));
|
||||
|
||||
configurableTypeInformationMapper = new ConfigurableTypeInformationMapper(Collections.singletonMap(String.class,
|
||||
"1"));
|
||||
simpleTypeInformationMapper = SimpleTypeInformationMapper.INSTANCE;
|
||||
|
||||
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(
|
||||
configurableTypeInformationMapper));
|
||||
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY,
|
||||
Arrays.asList(configurableTypeInformationMapper));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void defaultInstanceWritesClasses() {
|
||||
|
||||
|
||||
typeMapper = new DefaultMongoTypeMapper();
|
||||
writesTypeToField(new BasicDBObject(), String.class, String.class.getName());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void defaultInstanceReadsClasses() {
|
||||
typeMapper = new DefaultMongoTypeMapper();
|
||||
@@ -74,10 +74,10 @@ public class DefaultMongoTypeMapperUnitTests {
|
||||
|
||||
@Test
|
||||
public void writesClassNamesForUnmappedValuesIfConfigured() {
|
||||
|
||||
|
||||
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(
|
||||
configurableTypeInformationMapper, simpleTypeInformationMapper));
|
||||
|
||||
|
||||
writesTypeToField(new BasicDBObject(), String.class, "1");
|
||||
writesTypeToField(new BasicDBObject(), Object.class, Object.class.getName());
|
||||
}
|
||||
@@ -90,10 +90,10 @@ public class DefaultMongoTypeMapperUnitTests {
|
||||
|
||||
@Test
|
||||
public void readsTypeLoadingClassesForUnmappedTypesIfConfigured() {
|
||||
|
||||
|
||||
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(
|
||||
configurableTypeInformationMapper, simpleTypeInformationMapper));
|
||||
|
||||
|
||||
readsTypeFromField(new BasicDBObject(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, "1"), String.class);
|
||||
readsTypeFromField(new BasicDBObject(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Object.class.getName()), Object.class);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,27 +19,47 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bson.BSON;
|
||||
import org.bson.types.Binary;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BinaryToUUIDConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.UUIDToBinaryConverter;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MongoConverters}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoConvertersUnitTests {
|
||||
|
||||
@Test
|
||||
public void convertsBigDecimalToStringAndBackCorrectly() {
|
||||
|
||||
|
||||
BigDecimal bigDecimal = BigDecimal.valueOf(254, 1);
|
||||
String value = BigDecimalToStringConverter.INSTANCE.convert(bigDecimal);
|
||||
assertThat(value, is("25.4"));
|
||||
|
||||
|
||||
BigDecimal reference = StringToBigDecimalConverter.INSTANCE.convert(value);
|
||||
assertThat(reference, is(bigDecimal));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-390
|
||||
*/
|
||||
@Test
|
||||
public void convertsUUIDToBinaryCorrectly() {
|
||||
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Binary binary = UUIDToBinaryConverter.INSTANCE.convert(uuid);
|
||||
|
||||
assertThat(binary, is(notNullValue()));
|
||||
assertThat(binary.getType(), is(BSON.B_UUID));
|
||||
|
||||
UUID result = BinaryToUUIDConverter.INSTANCE.convert(binary);
|
||||
assertThat(result, is(uuid));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,26 +24,26 @@ import org.springframework.data.mongodb.core.geo.Point;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Box}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class BoxUnitTests {
|
||||
|
||||
|
||||
Box first = new Box(new Point(1d, 1d), new Point(2d, 2d));
|
||||
Box second = new Box(new Point(1d, 1d), new Point(2d, 2d));
|
||||
Box third = new Box(new Point(3d, 3d), new Point(1d, 1d));
|
||||
|
||||
@Test
|
||||
public void equalsWorksCorrectly() {
|
||||
|
||||
|
||||
assertThat(first.equals(second), is(true));
|
||||
assertThat(second.equals(first), is(true));
|
||||
assertThat(first.equals(third), is(false));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void hashCodeWorksCorrectly() {
|
||||
|
||||
|
||||
assertThat(first.hashCode(), is(second.hashCode()));
|
||||
assertThat(first.hashCode(), is(not(third.hashCode())));
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Circle}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class CircleUnitTests {
|
||||
@@ -31,23 +31,23 @@ public class CircleUnitTests {
|
||||
public void rejectsNullOrigin() {
|
||||
new Circle(null, 0);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNegativeRadius() {
|
||||
new Circle(1, 1, -1);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void considersTwoCirclesEqualCorrectly() {
|
||||
|
||||
|
||||
Circle left = new Circle(1, 1, 1);
|
||||
Circle right = new Circle(1, 1, 1);
|
||||
|
||||
|
||||
assertThat(left, is(right));
|
||||
assertThat(right, is(left));
|
||||
|
||||
right = new Circle(new Point(1,1), 1);
|
||||
|
||||
|
||||
right = new Circle(new Point(1, 1), 1);
|
||||
|
||||
assertThat(left, is(right));
|
||||
assertThat(right, is(left));
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.junit.Test;
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class DistanceUnitTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void defaultsMetricToNeutralOne() {
|
||||
assertThat(new Distance(2.5).getMetric(), is((Metric) Metrics.NEUTRAL));
|
||||
@@ -40,7 +40,7 @@ public class DistanceUnitTests {
|
||||
Distance right = new Distance(2.5, KILOMETERS);
|
||||
assertThat(left.add(right), is(new Distance(5.0, KILOMETERS)));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void addsDistancesWithExplicitMetric() {
|
||||
Distance left = new Distance(2.5, KILOMETERS);
|
||||
|
||||
@@ -21,11 +21,11 @@ import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GeoResult}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GeoResultUnitTests {
|
||||
|
||||
|
||||
GeoResult<String> first = new GeoResult<String>("Foo", new Distance(2.5));
|
||||
GeoResult<String> second = new GeoResult<String>("Foo", new Distance(2.5));
|
||||
GeoResult<String> third = new GeoResult<String>("Bar", new Distance(2.5));
|
||||
@@ -33,10 +33,10 @@ public class GeoResultUnitTests {
|
||||
|
||||
@Test
|
||||
public void considersSameInstanceEqual() {
|
||||
|
||||
|
||||
assertThat(first.equals(first), is(true));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void considersSameValuesAsEqual() {
|
||||
assertThat(first.equals(second), is(true));
|
||||
@@ -46,7 +46,7 @@ public class GeoResultUnitTests {
|
||||
assertThat(first.equals(fourth), is(false));
|
||||
assertThat(fourth.equals(first), is(false));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullContent() {
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GeoResults}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GeoResultsUnitTests {
|
||||
@@ -32,11 +32,11 @@ public class GeoResultsUnitTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void calculatesAverageForGivenGeoResults() {
|
||||
|
||||
|
||||
GeoResult<Object> first = new GeoResult<Object>(new Object(), new Distance(2));
|
||||
GeoResult<Object> second = new GeoResult<Object>(new Object(), new Distance(5));
|
||||
GeoResults<Object> geoResults = new GeoResults<Object>(Arrays.asList(first, second));
|
||||
|
||||
|
||||
assertThat(geoResults.getAverageDistance(), is(new Distance(3.5)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ import com.mongodb.WriteConcern;
|
||||
* Modified from https://github.com/deftlabs/mongo-java-geospatial-example
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*/
|
||||
public class GeoSpatialTests {
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@ public class PointUnitTests {
|
||||
public void rejectsNullforCopyConstructor() {
|
||||
new Point(null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void equalsIsImplementedCorrectly() {
|
||||
assertThat(new Point(1.5, 1.5), is(equalTo(new Point(1.5, 1.5))));
|
||||
assertThat(new Point(1.5, 1.5), is(not(equalTo(new Point(2.0, 2.0)))));
|
||||
assertThat(new Point(2.0, 2.0), is(not(equalTo(new Point(1.5, 1.5)))));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void invokingToStringWorksCorrectly() {
|
||||
new Point(1.5, 1.5).toString();
|
||||
|
||||
@@ -35,19 +35,19 @@ public class PolygonUnitTests {
|
||||
public void rejectsNullPoints() {
|
||||
new Polygon(null, null, null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void createsSimplePolygon() {
|
||||
Polygon polygon = new Polygon(third, second, first);
|
||||
assertThat(polygon, is(notNullValue()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void isEqualForSamePoints() {
|
||||
|
||||
|
||||
Polygon left = new Polygon(third, second, first);
|
||||
Polygon right = new Polygon(third, second, first);
|
||||
|
||||
|
||||
assertThat(left, is(right));
|
||||
assertThat(right, is(left));
|
||||
}
|
||||
|
||||
@@ -36,13 +36,13 @@ import com.mongodb.MongoException;
|
||||
|
||||
/**
|
||||
* Integration tests for index handling.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class IndexingIntegrationTests {
|
||||
|
||||
|
||||
@Autowired
|
||||
MongoOperations operations;
|
||||
|
||||
@@ -50,25 +50,24 @@ public class IndexingIntegrationTests {
|
||||
public void tearDown() {
|
||||
operations.dropCollection(IndexedPerson.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see DATADOC-237
|
||||
*/
|
||||
@Test
|
||||
public void createsIndexWithFieldName() {
|
||||
|
||||
|
||||
operations.save(new IndexedPerson());
|
||||
assertThat(hasIndex("_firstname", IndexedPerson.class), is(true));
|
||||
}
|
||||
|
||||
|
||||
class IndexedPerson {
|
||||
|
||||
|
||||
@Field("_firstname")
|
||||
@Indexed
|
||||
String firstname;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether an index with the given name exists for the given entity type.
|
||||
*
|
||||
@@ -77,7 +76,7 @@ public class IndexingIntegrationTests {
|
||||
* @return
|
||||
*/
|
||||
private boolean hasIndex(final String indexName, Class<?> entityType) {
|
||||
|
||||
|
||||
return operations.execute(entityType, new CollectionCallback<Boolean>() {
|
||||
public Boolean doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
for (DBObject indexInfo : collection.getIndexInfo()) {
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.springframework.data.util.ClassTypeInformation;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link BasicMongoPersistentEntity}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@@ -36,59 +36,61 @@ public class BasicMongoPersistentEntityUnitTests {
|
||||
|
||||
@Mock
|
||||
ApplicationContext context;
|
||||
|
||||
|
||||
@Test
|
||||
public void subclassInheritsAtDocumentAnnotation() {
|
||||
|
||||
|
||||
BasicMongoPersistentEntity<Person> entity = new BasicMongoPersistentEntity<Person>(
|
||||
ClassTypeInformation.from(Person.class));
|
||||
assertThat(entity.getCollection(), is("contacts"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void evaluatesSpELExpression() {
|
||||
|
||||
MongoPersistentEntity<Company> entity = new BasicMongoPersistentEntity<Company>(ClassTypeInformation.from(Company.class));
|
||||
|
||||
MongoPersistentEntity<Company> entity = new BasicMongoPersistentEntity<Company>(
|
||||
ClassTypeInformation.from(Company.class));
|
||||
assertThat(entity.getCollection(), is("35"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void collectionAllowsReferencingSpringBean() {
|
||||
|
||||
|
||||
CollectionProvider provider = new CollectionProvider();
|
||||
provider.collectionName = "reference";
|
||||
|
||||
|
||||
when(context.getBean("myBean")).thenReturn(provider);
|
||||
when(context.containsBean("myBean")).thenReturn(true);
|
||||
|
||||
BasicMongoPersistentEntity<DynamicallyMapped> entity = new BasicMongoPersistentEntity<DynamicallyMapped>(ClassTypeInformation.from(DynamicallyMapped.class));
|
||||
|
||||
BasicMongoPersistentEntity<DynamicallyMapped> entity = new BasicMongoPersistentEntity<DynamicallyMapped>(
|
||||
ClassTypeInformation.from(DynamicallyMapped.class));
|
||||
entity.setApplicationContext(context);
|
||||
|
||||
|
||||
assertThat(entity.getCollection(), is("reference"));
|
||||
}
|
||||
|
||||
|
||||
@Document(collection = "contacts")
|
||||
class Contact {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Person extends Contact {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Document(collection = "#{35}")
|
||||
class Company {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Document(collection = "#{myBean.collectionName}")
|
||||
class DynamicallyMapped {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class CollectionProvider {
|
||||
String collectionName;
|
||||
|
||||
|
||||
public String getCollectionName() {
|
||||
return collectionName;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class BasicMongoPersistentPropertyUnitTests {
|
||||
|
||||
|
||||
MongoPersistentEntity<Person> entity;
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
entity = new BasicMongoPersistentEntity<Person>(ClassTypeInformation.from(Person.class));
|
||||
@@ -46,11 +46,11 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
|
||||
@Test
|
||||
public void usesAnnotatedFieldName() {
|
||||
|
||||
|
||||
Field field = ReflectionUtils.findField(Person.class, "firstname");
|
||||
assertThat(getPropertyFor(field).getFieldName(), is("foo"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void returns_IdForIdProperty() {
|
||||
Field field = ReflectionUtils.findField(Person.class, "id");
|
||||
@@ -58,32 +58,32 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
assertThat(property.isIdProperty(), is(true));
|
||||
assertThat(property.getFieldName(), is("_id"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void returnsPropertyNameForUnannotatedProperties() {
|
||||
|
||||
|
||||
Field field = ReflectionUtils.findField(Person.class, "lastname");
|
||||
assertThat(getPropertyFor(field).getFieldName(), is("lastname"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void preventsNegativeOrder() {
|
||||
getPropertyFor(ReflectionUtils.findField(Person.class, "ssn"));
|
||||
}
|
||||
|
||||
|
||||
private MongoPersistentProperty getPropertyFor(Field field) {
|
||||
return new BasicMongoPersistentProperty(field, null, entity, new SimpleTypeHolder());
|
||||
}
|
||||
|
||||
|
||||
class Person {
|
||||
|
||||
|
||||
@Id
|
||||
String id;
|
||||
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.Field("foo")
|
||||
String firstname;
|
||||
String lastname;
|
||||
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.Field(order = -20)
|
||||
String ssn;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -30,7 +29,9 @@ import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for testing the mapping works with generic types.
|
||||
@@ -42,7 +43,7 @@ public class GenericMappingTests {
|
||||
|
||||
MongoMappingContext context;
|
||||
MongoConverter converter;
|
||||
|
||||
|
||||
@Mock
|
||||
MongoDbFactory factory;
|
||||
|
||||
@@ -85,15 +86,15 @@ public class GenericMappingTests {
|
||||
assertThat(result.container.content, is("Foo!"));
|
||||
}
|
||||
|
||||
public class StringWrapper extends Wrapper<String> {
|
||||
static class StringWrapper extends Wrapper<String> {
|
||||
|
||||
}
|
||||
|
||||
public class Wrapper<S> {
|
||||
static class Wrapper<S> {
|
||||
Container<S> container;
|
||||
}
|
||||
|
||||
public class Container<T> {
|
||||
static class Container<T> {
|
||||
T content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ public class GeoIndexedAppConfig extends AbstractMongoConfiguration {
|
||||
public String getMappingBasePackage() {
|
||||
return "org.springframework.data.mongodb.core.core.mapping";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LoggingEventListener mappingEventsListener() {
|
||||
return new LoggingEventListener();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LoggingEventListener mappingEventsListener() {
|
||||
return new LoggingEventListener();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ import com.mongodb.MongoException;
|
||||
*/
|
||||
public class GeoIndexedTests {
|
||||
|
||||
private final String[] collectionsToDrop = new String[] { GeoIndexedAppConfig.GEO_COLLECTION, "Person"};
|
||||
private final String[] collectionsToDrop = new String[] { GeoIndexedAppConfig.GEO_COLLECTION, "Person" };
|
||||
|
||||
ApplicationContext applicationContext;
|
||||
MongoTemplate template;
|
||||
|
||||
@@ -28,11 +28,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bson.types.ObjectId;
|
||||
@@ -46,19 +41,24 @@ import org.springframework.data.mongodb.MongoCollectionUtils;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoDbUtils;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class MappingTests {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(MongoDbUtils.class);
|
||||
private final String[] collectionsToDrop = new String[]{
|
||||
private final String[] collectionsToDrop = new String[] {
|
||||
MongoCollectionUtils.getPreferredCollectionName(Person.class),
|
||||
MongoCollectionUtils.getPreferredCollectionName(PersonMapProperty.class),
|
||||
MongoCollectionUtils.getPreferredCollectionName(PersonWithObjectId.class),
|
||||
@@ -72,8 +72,8 @@ public class MappingTests {
|
||||
MongoCollectionUtils.getPreferredCollectionName(PersonWithLongDBRef.class),
|
||||
MongoCollectionUtils.getPreferredCollectionName(PersonNullProperties.class),
|
||||
MongoCollectionUtils.getPreferredCollectionName(Account.class),
|
||||
MongoCollectionUtils.getPreferredCollectionName(PrimitiveId.class),
|
||||
"foobar", "geolocation", "person1", "person2", "account"};
|
||||
MongoCollectionUtils.getPreferredCollectionName(PrimitiveId.class), "foobar", "geolocation", "person1",
|
||||
"person2", "account" };
|
||||
|
||||
ApplicationContext applicationContext;
|
||||
Mongo mongo;
|
||||
@@ -110,7 +110,8 @@ public class MappingTests {
|
||||
LOGGER.info("done inserting");
|
||||
assertNotNull(p.getId());
|
||||
|
||||
List<PersonWithObjectId> result = template.find(new Query(Criteria.where("ssn").is(12345)), PersonWithObjectId.class);
|
||||
List<PersonWithObjectId> result = template.find(new Query(Criteria.where("ssn").is(12345)),
|
||||
PersonWithObjectId.class);
|
||||
assertThat(result.size(), is(1));
|
||||
assertThat(result.get(0).getSsn(), is(12345));
|
||||
}
|
||||
@@ -166,11 +167,11 @@ public class MappingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void testWriteEntity() {
|
||||
|
||||
Address addr = new Address();
|
||||
addr.setLines(new String[]{"1234 W. 1st Street", "Apt. 12"});
|
||||
addr.setLines(new String[] { "1234 W. 1st Street", "Apt. 12" });
|
||||
addr.setCity("Anytown");
|
||||
addr.setPostalCode(12345);
|
||||
addr.setCountry("USA");
|
||||
@@ -202,10 +203,10 @@ public class MappingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void testUniqueIndex() {
|
||||
Address addr = new Address();
|
||||
addr.setLines(new String[]{"1234 W. 1st Street", "Apt. 12"});
|
||||
addr.setLines(new String[] { "1234 W. 1st Street", "Apt. 12" });
|
||||
addr.setCity("Anytown");
|
||||
addr.setPostalCode(12345);
|
||||
addr.setCountry("USA");
|
||||
@@ -229,17 +230,17 @@ public class MappingTests {
|
||||
persons.add(new PersonCustomCollection2(66666, "Person", "Two"));
|
||||
template.insertAll(persons);
|
||||
|
||||
List<PersonCustomCollection1> p1Results = template.find(new Query(Criteria.where("ssn").is(55555)), PersonCustomCollection1.class,
|
||||
"person1");
|
||||
List<PersonCustomCollection2> p2Results = template.find(new Query(Criteria.where("ssn").is(66666)), PersonCustomCollection2.class,
|
||||
"person2");
|
||||
List<PersonCustomCollection1> p1Results = template.find(new Query(Criteria.where("ssn").is(55555)),
|
||||
PersonCustomCollection1.class, "person1");
|
||||
List<PersonCustomCollection2> p2Results = template.find(new Query(Criteria.where("ssn").is(66666)),
|
||||
PersonCustomCollection2.class, "person2");
|
||||
assertThat(p1Results.size(), is(1));
|
||||
assertThat(p2Results.size(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrimitivesAndCustomCollectionName() {
|
||||
Location loc = new Location(new double[]{1.0, 2.0}, new int[]{1, 2, 3, 4}, new float[]{1.0f, 2.0f});
|
||||
Location loc = new Location(new double[] { 1.0, 2.0 }, new int[] { 1, 2, 3, 4 }, new float[] { 1.0f, 2.0f });
|
||||
template.insert(loc);
|
||||
|
||||
List<Location> result = template.find(new Query(Criteria.where("_id").is(loc.getId())), Location.class, "places");
|
||||
@@ -255,7 +256,8 @@ public class MappingTests {
|
||||
public Boolean doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
List<DBObject> indexes = collection.getIndexInfo();
|
||||
for (DBObject dbo : indexes) {
|
||||
if (dbo.get("name") != null && dbo.get("name") instanceof String && ((String)dbo.get("name")).startsWith("name")) {
|
||||
if (dbo.get("name") != null && dbo.get("name") instanceof String
|
||||
&& ((String) dbo.get("name")).startsWith("name")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -271,7 +273,8 @@ public class MappingTests {
|
||||
public Boolean doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
List<DBObject> indexes = collection.getIndexInfo();
|
||||
for (DBObject dbo : indexes) {
|
||||
if (dbo.get("name") != null && dbo.get("name") instanceof String && ((String)dbo.get("name")).startsWith("name")) {
|
||||
if (dbo.get("name") != null && dbo.get("name") instanceof String
|
||||
&& ((String) dbo.get("name")).startsWith("name")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -282,8 +285,8 @@ public class MappingTests {
|
||||
|
||||
@Test
|
||||
public void testMultiDimensionalArrayProperties() {
|
||||
String[][] grid = new String[][]{new String[]{"1", "2", "3", "4"}, new String[]{"5", "6", "7", "8"},
|
||||
new String[]{"9", "10", "11", "12"}};
|
||||
String[][] grid = new String[][] { new String[] { "1", "2", "3", "4" }, new String[] { "5", "6", "7", "8" },
|
||||
new String[] { "9", "10", "11", "12" } };
|
||||
PersonMultiDimArrays p = new PersonMultiDimArrays(123, "Multi", "Dimensional", grid);
|
||||
|
||||
template.insert(p);
|
||||
@@ -316,7 +319,7 @@ public class MappingTests {
|
||||
|
||||
@Test
|
||||
public void testDbRef() {
|
||||
double[] pos = new double[]{37.0625, -95.677068};
|
||||
double[] pos = new double[] { 37.0625, -95.677068 };
|
||||
GeoLocation geo = new GeoLocation(pos);
|
||||
template.insert(geo);
|
||||
|
||||
@@ -340,7 +343,7 @@ public class MappingTests {
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public void testQueryUpdate() {
|
||||
Address addr = new Address();
|
||||
addr.setLines(new String[]{"1234 W. 1st Street", "Apt. 12"});
|
||||
addr.setLines(new String[] { "1234 W. 1st Street", "Apt. 12" });
|
||||
addr.setCity("Anytown");
|
||||
addr.setPostalCode(12345);
|
||||
addr.setCountry("USA");
|
||||
@@ -354,31 +357,33 @@ public class MappingTests {
|
||||
Person p2 = template.findOne(query(where("ssn").is(1111)), Person.class);
|
||||
assertThat(p2.getAddress().getCity(), is("New Town"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void testUpsert() {
|
||||
Address addr = new Address();
|
||||
addr.setLines(new String[]{"1234 W. 1st Street", "Apt. 12"});
|
||||
addr.setLines(new String[] { "1234 W. 1st Street", "Apt. 12" });
|
||||
addr.setCity("Anytown");
|
||||
addr.setPostalCode(12345);
|
||||
addr.setCountry("USA");
|
||||
|
||||
Person p2 = template.findOne(query(where("ssn").is(1111)), Person.class);
|
||||
assertNull(p2);
|
||||
|
||||
template.upsert(query(where("ssn").is(1111).and("firstName").is("Query").and("lastName").is("Update")), update("address", addr), Person.class);
|
||||
|
||||
template.upsert(query(where("ssn").is(1111).and("firstName").is("Query").and("lastName").is("Update")),
|
||||
update("address", addr), Person.class);
|
||||
|
||||
p2 = template.findOne(query(where("ssn").is(1111)), Person.class);
|
||||
assertThat(p2.getAddress().getCity(), is("Anytown"));
|
||||
|
||||
|
||||
template.dropCollection(Person.class);
|
||||
template.upsert(query(where("ssn").is(1111).and("firstName").is("Query").and("lastName").is("Update")), update("address", addr), "person");
|
||||
template.upsert(query(where("ssn").is(1111).and("firstName").is("Query").and("lastName").is("Update")),
|
||||
update("address", addr), "person");
|
||||
p2 = template.findOne(query(where("ssn").is(1111)), Person.class);
|
||||
assertThat(p2.getAddress().getCity(), is("Anytown"));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOrQuery() {
|
||||
PersonWithObjectId p1 = new PersonWithObjectId(1, "first", "");
|
||||
@@ -386,8 +391,8 @@ public class MappingTests {
|
||||
PersonWithObjectId p2 = new PersonWithObjectId(2, "second", "");
|
||||
template.save(p2);
|
||||
|
||||
List<PersonWithObjectId> results = template.find(new Query(
|
||||
new Criteria().orOperator(where("ssn").is(1), where("ssn").is(2))), PersonWithObjectId.class);
|
||||
List<PersonWithObjectId> results = template.find(
|
||||
new Query(new Criteria().orOperator(where("ssn").is(1), where("ssn").is(2))), PersonWithObjectId.class);
|
||||
|
||||
assertNotNull(results);
|
||||
assertThat(results.size(), is(2));
|
||||
@@ -426,42 +431,35 @@ public class MappingTests {
|
||||
public void testNoMappingAnnotationsUsingLongAsId() {
|
||||
PersonPojoLongId p = new PersonPojoLongId(1, "Text");
|
||||
template.insert(p);
|
||||
template.updateFirst(query(where("id").is(1)), update("text", "New Text"),
|
||||
PersonPojoLongId.class);
|
||||
template.updateFirst(query(where("id").is(1)), update("text", "New Text"), PersonPojoLongId.class);
|
||||
|
||||
PersonPojoLongId p2 = template.findOne(query(where("id").is(1)),
|
||||
PersonPojoLongId.class);
|
||||
PersonPojoLongId p2 = template.findOne(query(where("id").is(1)), PersonPojoLongId.class);
|
||||
assertEquals("New Text", p2.getText());
|
||||
|
||||
p.setText("Different Text");
|
||||
template.save(p);
|
||||
|
||||
PersonPojoLongId p3 = template.findOne(query(where("id").is(1)),
|
||||
PersonPojoLongId.class);
|
||||
PersonPojoLongId p3 = template.findOne(query(where("id").is(1)), PersonPojoLongId.class);
|
||||
assertEquals("Different Text", p3.getText());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoMappingAnnotationsUsingStringAsId() {
|
||||
//Assign the String Id in code
|
||||
// Assign the String Id in code
|
||||
PersonPojoStringId p = new PersonPojoStringId("1", "Text");
|
||||
template.insert(p);
|
||||
template.updateFirst(query(where("id").is("1")), update("text", "New Text"),
|
||||
PersonPojoStringId.class);
|
||||
template.updateFirst(query(where("id").is("1")), update("text", "New Text"), PersonPojoStringId.class);
|
||||
|
||||
PersonPojoStringId p2 = template.findOne(query(where("id").is("1")),
|
||||
PersonPojoStringId.class);
|
||||
PersonPojoStringId p2 = template.findOne(query(where("id").is("1")), PersonPojoStringId.class);
|
||||
assertEquals("New Text", p2.getText());
|
||||
|
||||
p.setText("Different Text");
|
||||
template.save(p);
|
||||
|
||||
PersonPojoStringId p3 = template.findOne(query(where("id").is("1")),
|
||||
PersonPojoStringId.class);
|
||||
PersonPojoStringId p3 = template.findOne(query(where("id").is("1")), PersonPojoStringId.class);
|
||||
assertEquals("Different Text", p3.getText());
|
||||
|
||||
|
||||
PersonPojoStringId p4 = new PersonPojoStringId("2", "Text-2");
|
||||
template.insert(p4);
|
||||
|
||||
@@ -513,8 +511,7 @@ public class MappingTests {
|
||||
assertThat(result.items.get(0).id, is(items.id));
|
||||
}
|
||||
|
||||
|
||||
class Container {
|
||||
static class Container {
|
||||
|
||||
@Id
|
||||
final String id;
|
||||
@@ -529,7 +526,7 @@ public class MappingTests {
|
||||
List<Item> items;
|
||||
}
|
||||
|
||||
class Item {
|
||||
static class Item {
|
||||
|
||||
@Id
|
||||
final String id;
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MongoMappingContext}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoMappingContextUnitTests {
|
||||
|
||||
@@ -18,31 +18,31 @@ import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MongoPersistentPropertyComparator}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MongoPersistentPropertyComparatorUnitTests {
|
||||
|
||||
|
||||
@Mock
|
||||
MongoPersistentProperty firstName;
|
||||
|
||||
|
||||
@Mock
|
||||
MongoPersistentProperty lastName;
|
||||
|
||||
|
||||
@Mock
|
||||
MongoPersistentProperty ssn;
|
||||
|
||||
@Test
|
||||
public void ordersPropertiesCorrectly() {
|
||||
|
||||
|
||||
when(ssn.getFieldOrder()).thenReturn(10);
|
||||
when(firstName.getFieldOrder()).thenReturn(20);
|
||||
when(lastName.getFieldOrder()).thenReturn(Integer.MAX_VALUE);
|
||||
|
||||
|
||||
List<MongoPersistentProperty> properties = Arrays.asList(firstName, lastName, ssn);
|
||||
Collections.sort(properties, MongoPersistentPropertyComparator.INSTANCE);
|
||||
|
||||
|
||||
assertThat(properties.get(0), is(ssn));
|
||||
assertThat(properties.get(1), is(firstName));
|
||||
assertThat(properties.get(2), is(lastName));
|
||||
|
||||
@@ -17,10 +17,10 @@ public class SimpleMappingContextUnitTests {
|
||||
|
||||
@Test
|
||||
public void returnsIdPropertyCorrectly() {
|
||||
|
||||
|
||||
SimpleMongoMappingContext context = new SimpleMongoMappingContext();
|
||||
SimpleMongoPersistentEntity<?> entity = context.getPersistentEntity(Person.class);
|
||||
|
||||
|
||||
MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
assertThat(idProperty, is(notNullValue()));
|
||||
assertThat(idProperty.getName(), is("id"));
|
||||
|
||||
@@ -29,37 +29,37 @@ import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AbstractMongoEventListener}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class AbstractMongoEventListenerUnitTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void invokesCallbackForEventForPerson() {
|
||||
|
||||
|
||||
MongoMappingEvent<Person> event = new BeforeConvertEvent<Person>(new Person("Dave", "Matthews"));
|
||||
SamplePersonEventListener listener = new SamplePersonEventListener();
|
||||
listener.onApplicationEvent(event);
|
||||
assertThat(listener.invokedOnBeforeConvert, is(true));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void dropsEventIfNotForCorrectDomainType() {
|
||||
|
||||
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
|
||||
context.refresh();
|
||||
|
||||
SamplePersonEventListener listener = new SamplePersonEventListener();
|
||||
context.addApplicationListener(listener);
|
||||
|
||||
|
||||
context.publishEvent(new BeforeConvertEvent<Person>(new Person("Dave", "Matthews")));
|
||||
assertThat(listener.invokedOnBeforeConvert, is(true));
|
||||
|
||||
|
||||
listener.invokedOnBeforeConvert = false;
|
||||
context.publishEvent(new BeforeConvertEvent<String>("Test"));
|
||||
assertThat(listener.invokedOnBeforeConvert, is(false));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DATADOC-289
|
||||
*/
|
||||
@@ -115,14 +115,14 @@ public class AbstractMongoEventListenerUnitTests {
|
||||
assertThat(personListener.invokedOnAfterLoad, is(false));
|
||||
assertThat(contactListener.invokedOnAfterLoad, is(true));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DATADOC-333
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public void handlesUntypedImplementations() {
|
||||
|
||||
|
||||
UntypedEventListener listener = new UntypedEventListener();
|
||||
listener.onApplicationEvent(new MongoMappingEvent(new Object(), new BasicDBObject()));
|
||||
}
|
||||
@@ -131,12 +131,12 @@ public class AbstractMongoEventListenerUnitTests {
|
||||
|
||||
boolean invokedOnBeforeConvert;
|
||||
boolean invokedOnAfterLoad;
|
||||
|
||||
|
||||
@Override
|
||||
public void onBeforeConvert(Person source) {
|
||||
invokedOnBeforeConvert = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onAfterLoad(DBObject dbo) {
|
||||
invokedOnAfterLoad = true;
|
||||
@@ -177,6 +177,6 @@ public class AbstractMongoEventListenerUnitTests {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
class UntypedEventListener extends AbstractMongoEventListener {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,46 +65,47 @@ public class ApplicationContextEventTests {
|
||||
db.getCollection(coll).drop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void beforeSaveEvent() {
|
||||
PersonBeforeSaveListener personBeforeSaveListener = applicationContext.getBean(PersonBeforeSaveListener.class);
|
||||
AfterSaveListener afterSaveListener = applicationContext.getBean(AfterSaveListener.class);
|
||||
SimpleMappingEventListener simpleMappingEventListener = applicationContext.getBean(SimpleMappingEventListener.class);
|
||||
|
||||
SimpleMappingEventListener simpleMappingEventListener = applicationContext
|
||||
.getBean(SimpleMappingEventListener.class);
|
||||
|
||||
assertEquals(0, personBeforeSaveListener.seenEvents.size());
|
||||
assertEquals(0, afterSaveListener.seenEvents.size());
|
||||
|
||||
|
||||
assertEquals(0, simpleMappingEventListener.onBeforeSaveEvents.size());
|
||||
assertEquals(0, simpleMappingEventListener.onAfterSaveEvents.size());
|
||||
|
||||
|
||||
|
||||
PersonPojoStringId p = new PersonPojoStringId("1", "Text");
|
||||
template.insert(p);
|
||||
|
||||
|
||||
assertEquals(1, personBeforeSaveListener.seenEvents.size());
|
||||
assertEquals(1, afterSaveListener.seenEvents.size());
|
||||
|
||||
|
||||
assertEquals(1, simpleMappingEventListener.onBeforeSaveEvents.size());
|
||||
assertEquals(1, simpleMappingEventListener.onAfterSaveEvents.size());
|
||||
|
||||
Assert.assertTrue(personBeforeSaveListener.seenEvents.get(0) instanceof BeforeSaveEvent<?>);
|
||||
Assert.assertTrue(afterSaveListener.seenEvents.get(0) instanceof AfterSaveEvent<?>);
|
||||
|
||||
BeforeSaveEvent<PersonPojoStringId> beforeSaveEvent = (BeforeSaveEvent<PersonPojoStringId>)personBeforeSaveListener.seenEvents.get(0);
|
||||
BeforeSaveEvent<PersonPojoStringId> beforeSaveEvent = (BeforeSaveEvent<PersonPojoStringId>) personBeforeSaveListener.seenEvents
|
||||
.get(0);
|
||||
PersonPojoStringId p2 = beforeSaveEvent.getSource();
|
||||
DBObject dbo = beforeSaveEvent.getDBObject();
|
||||
|
||||
|
||||
comparePersonAndDbo(p, p2, dbo);
|
||||
|
||||
AfterSaveEvent<Object> afterSaveEvent = (AfterSaveEvent<Object>)afterSaveListener.seenEvents.get(0);
|
||||
|
||||
AfterSaveEvent<Object> afterSaveEvent = (AfterSaveEvent<Object>) afterSaveListener.seenEvents.get(0);
|
||||
Assert.assertTrue(afterSaveEvent.getSource() instanceof PersonPojoStringId);
|
||||
p2 = (PersonPojoStringId)afterSaveEvent.getSource();
|
||||
p2 = (PersonPojoStringId) afterSaveEvent.getSource();
|
||||
dbo = beforeSaveEvent.getDBObject();
|
||||
|
||||
|
||||
comparePersonAndDbo(p, p2, dbo);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void comparePersonAndDbo(PersonPojoStringId p, PersonPojoStringId p2, DBObject dbo) {
|
||||
|
||||
@@ -39,12 +39,12 @@ public class ApplicationContextEventTestsAppConfig extends AbstractMongoConfigur
|
||||
public PersonBeforeSaveListener personBeforeSaveListener() {
|
||||
return new PersonBeforeSaveListener();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public AfterSaveListener afterSaveListener() {
|
||||
return new AfterSaveListener();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public SimpleMappingEventListener simpleMappingEventListener() {
|
||||
return new SimpleMappingEventListener();
|
||||
|
||||
@@ -19,7 +19,6 @@ import java.util.ArrayList;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
|
||||
public class SimpleMappingEventListener extends AbstractMongoEventListener<Object> {
|
||||
|
||||
public final ArrayList<BeforeConvertEvent<Object>> onBeforeConvertEvents = new ArrayList<BeforeConvertEvent<Object>>();
|
||||
@@ -27,7 +26,7 @@ public class SimpleMappingEventListener extends AbstractMongoEventListener<Objec
|
||||
public final ArrayList<AfterSaveEvent<Object>> onAfterSaveEvents = new ArrayList<AfterSaveEvent<Object>>();
|
||||
public final ArrayList<AfterLoadEvent<Object>> onAfterLoadEvents = new ArrayList<AfterLoadEvent<Object>>();
|
||||
public final ArrayList<AfterConvertEvent<Object>> onAfterConvertEvents = new ArrayList<AfterConvertEvent<Object>>();
|
||||
|
||||
|
||||
@Override
|
||||
public void onBeforeConvert(Object source) {
|
||||
onBeforeConvertEvents.add(new BeforeConvertEvent<Object>(source));
|
||||
|
||||
@@ -3,17 +3,17 @@ package org.springframework.data.mongodb.core.mapreduce;
|
||||
public class ContentAndVersion {
|
||||
|
||||
private String id;
|
||||
|
||||
|
||||
private String document_id;
|
||||
|
||||
|
||||
private String content;
|
||||
|
||||
|
||||
private String author;
|
||||
|
||||
private Long version;
|
||||
|
||||
|
||||
private Long value;
|
||||
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
@@ -38,7 +38,6 @@ public class ContentAndVersion {
|
||||
this.document_id = documentId;
|
||||
}
|
||||
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -68,6 +67,5 @@ public class ContentAndVersion {
|
||||
return "ContentAndVersion [id=" + id + ", document_id=" + document_id + ", content=" + content + ", author="
|
||||
+ author + ", version=" + version + ", value=" + value + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -46,33 +46,30 @@ public class GroupByTests {
|
||||
|
||||
@Autowired
|
||||
MongoDbFactory factory;
|
||||
|
||||
|
||||
@Autowired
|
||||
ApplicationContext applicationContext;
|
||||
|
||||
//@Autowired
|
||||
//MongoTemplate mongoTemplate;
|
||||
|
||||
|
||||
|
||||
// @Autowired
|
||||
// MongoTemplate mongoTemplate;
|
||||
|
||||
MongoTemplate mongoTemplate;
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setMongo(Mongo mongo) throws Exception {
|
||||
|
||||
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
mappingContext.setInitialEntitySet(new HashSet<Class<?>>(Arrays.asList(XObject.class)));
|
||||
mappingContext.afterPropertiesSet();
|
||||
|
||||
MappingMongoConverter mappingConverter = new MappingMongoConverter(factory, mappingContext);
|
||||
MappingMongoConverter mappingConverter = new MappingMongoConverter(factory, mappingContext);
|
||||
mappingConverter.afterPropertiesSet();
|
||||
this.mongoTemplate = new MongoTemplate(factory, mappingConverter);
|
||||
mongoTemplate.setApplicationContext(applicationContext);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
cleanDb();
|
||||
@@ -87,92 +84,95 @@ public class GroupByTests {
|
||||
mongoTemplate.dropCollection(mongoTemplate.getCollectionName(XObject.class));
|
||||
mongoTemplate.dropCollection("group_test_collection");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void singleKeyCreation() {
|
||||
DBObject gc = new GroupBy("a").getGroupByObject();
|
||||
//String expected = "{ \"group\" : { \"ns\" : \"test\" , \"key\" : { \"a\" : 1} , \"cond\" : null , \"$reduce\" : null , \"initial\" : null }}";
|
||||
String expected = "{ \"key\" : { \"a\" : 1} , \"$reduce\" : null , \"initial\" : null }";
|
||||
Assert.assertEquals(expected, gc.toString());
|
||||
public void singleKeyCreation() {
|
||||
DBObject gc = new GroupBy("a").getGroupByObject();
|
||||
// String expected =
|
||||
// "{ \"group\" : { \"ns\" : \"test\" , \"key\" : { \"a\" : 1} , \"cond\" : null , \"$reduce\" : null , \"initial\" : null }}";
|
||||
String expected = "{ \"key\" : { \"a\" : 1} , \"$reduce\" : null , \"initial\" : null }";
|
||||
Assert.assertEquals(expected, gc.toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void multipleKeyCreation() {
|
||||
DBObject gc = GroupBy.key("a","b").getGroupByObject();
|
||||
//String expected = "{ \"group\" : { \"ns\" : \"test\" , \"key\" : { \"a\" : 1 , \"b\" : 1} , \"cond\" : null , \"$reduce\" : null , \"initial\" : null }}";
|
||||
String expected = "{ \"key\" : { \"a\" : 1 , \"b\" : 1} , \"$reduce\" : null , \"initial\" : null }";
|
||||
Assert.assertEquals(expected, gc.toString());
|
||||
DBObject gc = GroupBy.key("a", "b").getGroupByObject();
|
||||
// String expected =
|
||||
// "{ \"group\" : { \"ns\" : \"test\" , \"key\" : { \"a\" : 1 , \"b\" : 1} , \"cond\" : null , \"$reduce\" : null , \"initial\" : null }}";
|
||||
String expected = "{ \"key\" : { \"a\" : 1 , \"b\" : 1} , \"$reduce\" : null , \"initial\" : null }";
|
||||
Assert.assertEquals(expected, gc.toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void keyFunctionCreation() {
|
||||
DBObject gc = GroupBy.keyFunction("classpath:keyFunction.js").getGroupByObject();
|
||||
String expected = "{ \"$keyf\" : \"classpath:keyFunction.js\" , \"$reduce\" : null , \"initial\" : null }";
|
||||
Assert.assertEquals(expected, gc.toString());
|
||||
DBObject gc = GroupBy.keyFunction("classpath:keyFunction.js").getGroupByObject();
|
||||
String expected = "{ \"$keyf\" : \"classpath:keyFunction.js\" , \"$reduce\" : null , \"initial\" : null }";
|
||||
Assert.assertEquals(expected, gc.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void SimpleGroup() {
|
||||
createGroupByData();
|
||||
GroupByResults<XObject> results;
|
||||
|
||||
results = mongoTemplate.group("group_test_collection",
|
||||
GroupBy.key("x").initialDocument(new BasicDBObject("count", 0)).reduceFunction("function(doc, prev) { prev.count += 1 }"), XObject.class);
|
||||
|
||||
|
||||
results = mongoTemplate.group(
|
||||
"group_test_collection",
|
||||
GroupBy.key("x").initialDocument(new BasicDBObject("count", 0))
|
||||
.reduceFunction("function(doc, prev) { prev.count += 1 }"), XObject.class);
|
||||
|
||||
assertMapReduceResults(results);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void SimpleGroupWithKeyFunction() {
|
||||
createGroupByData();
|
||||
GroupByResults<XObject> results;
|
||||
|
||||
results = mongoTemplate.group("group_test_collection",
|
||||
GroupBy.keyFunction("function(doc) { return { x : doc.x }; }").initialDocument("{ count: 0 }").reduceFunction("function(doc, prev) { prev.count += 1 }"), XObject.class);
|
||||
|
||||
assertMapReduceResults(results);
|
||||
|
||||
results = mongoTemplate.group(
|
||||
"group_test_collection",
|
||||
GroupBy.keyFunction("function(doc) { return { x : doc.x }; }").initialDocument("{ count: 0 }")
|
||||
.reduceFunction("function(doc, prev) { prev.count += 1 }"), XObject.class);
|
||||
|
||||
assertMapReduceResults(results);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void SimpleGroupWithFunctionsAsResources() {
|
||||
createGroupByData();
|
||||
GroupByResults<XObject> results;
|
||||
|
||||
results = mongoTemplate.group("group_test_collection",
|
||||
GroupBy.keyFunction("classpath:keyFunction.js").initialDocument("{ count: 0 }").reduceFunction("classpath:groupReduce.js"), XObject.class);
|
||||
|
||||
assertMapReduceResults(results);
|
||||
|
||||
results = mongoTemplate.group("group_test_collection", GroupBy.keyFunction("classpath:keyFunction.js")
|
||||
.initialDocument("{ count: 0 }").reduceFunction("classpath:groupReduce.js"), XObject.class);
|
||||
|
||||
assertMapReduceResults(results);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void SimpleGroupWithQueryAndFunctionsAsResources() {
|
||||
createGroupByData();
|
||||
GroupByResults<XObject> results;
|
||||
|
||||
results = mongoTemplate.group(where("x").gt(0),
|
||||
"group_test_collection",
|
||||
keyFunction("classpath:keyFunction.js").initialDocument("{ count: 0 }").reduceFunction("classpath:groupReduce.js"), XObject.class);
|
||||
|
||||
assertMapReduceResults(results);
|
||||
|
||||
results = mongoTemplate.group(where("x").gt(0), "group_test_collection", keyFunction("classpath:keyFunction.js")
|
||||
.initialDocument("{ count: 0 }").reduceFunction("classpath:groupReduce.js"), XObject.class);
|
||||
|
||||
assertMapReduceResults(results);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void assertMapReduceResults(GroupByResults<XObject> results) {
|
||||
DBObject dboRawResults = results.getRawResults();
|
||||
String expected = "{ \"serverUsed\" : \"127.0.0.1:27017\" , \"retval\" : [ { \"x\" : 1.0 , \"count\" : 2.0} , { \"x\" : 2.0 , \"count\" : 1.0} , { \"x\" : 3.0 , \"count\" : 3.0}] , \"count\" : 6.0 , \"keys\" : 3 , \"ok\" : 1.0}";
|
||||
Assert.assertEquals(expected, dboRawResults.toString());
|
||||
|
||||
|
||||
int numResults = 0;
|
||||
for (XObject xObject : results) {
|
||||
if (xObject.getX() == 1) {
|
||||
if (xObject.getX() == 1) {
|
||||
Assert.assertEquals(2, xObject.getCount(), 0.001);
|
||||
}
|
||||
if (xObject.getX() == 2) {
|
||||
if (xObject.getX() == 2) {
|
||||
Assert.assertEquals(1, xObject.getCount(), 0.001);
|
||||
}
|
||||
if (xObject.getX() == 3) {
|
||||
if (xObject.getX() == 3) {
|
||||
Assert.assertEquals(3, xObject.getCount(), 0.001);
|
||||
}
|
||||
numResults++;
|
||||
@@ -182,7 +182,6 @@ public class GroupByTests {
|
||||
Assert.assertEquals(3, results.getKeys());
|
||||
}
|
||||
|
||||
|
||||
private void createGroupByData() {
|
||||
DBCollection c = mongoTemplate.getDb().getCollection("group_test_collection");
|
||||
c.save(new BasicDBObject("x", 1));
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.junit.Test;
|
||||
|
||||
public class MapReduceOptionsTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void testFinalize() {
|
||||
new MapReduceOptions().finalizeFunction("code");
|
||||
|
||||
@@ -112,10 +112,10 @@ public class MapReduceTests {
|
||||
String reduce = "function (key, values) { return Math.max.apply(Math, values); }";
|
||||
MapReduceResults<ContentAndVersion> results = mongoTemplate.mapReduce("jmr2", map, reduce,
|
||||
new MapReduceOptions().outputCollection("jmr2_out"), ContentAndVersion.class);
|
||||
|
||||
|
||||
int size = 0;
|
||||
for (ContentAndVersion cv : results) {
|
||||
if (cv.getId().equals("Resume")) {
|
||||
if (cv.getId().equals("Resume")) {
|
||||
assertEquals(6, cv.getValue().longValue());
|
||||
}
|
||||
if (cv.getId().equals("Schema")) {
|
||||
@@ -126,7 +126,7 @@ public class MapReduceTests {
|
||||
}
|
||||
size++;
|
||||
}
|
||||
assertEquals(3,size);
|
||||
assertEquals(3, size);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -134,11 +134,11 @@ public class MapReduceTests {
|
||||
createNumberAndVersionData();
|
||||
String map = "function () { emit(this.number, this.version); }";
|
||||
String reduce = "function (key, values) { return Math.max.apply(Math, values); }";
|
||||
MapReduceResults<NumberAndVersion> results =
|
||||
mongoTemplate.mapReduce("jmr2", map, reduce, new MapReduceOptions().outputCollection("jmr2_out"), NumberAndVersion.class);
|
||||
int size = 0;
|
||||
MapReduceResults<NumberAndVersion> results = mongoTemplate.mapReduce("jmr2", map, reduce,
|
||||
new MapReduceOptions().outputCollection("jmr2_out"), NumberAndVersion.class);
|
||||
int size = 0;
|
||||
for (NumberAndVersion nv : results) {
|
||||
if (nv.getId().equals("1")) {
|
||||
if (nv.getId().equals("1")) {
|
||||
assertEquals(2, nv.getValue().longValue());
|
||||
}
|
||||
if (nv.getId().equals("2")) {
|
||||
@@ -149,7 +149,7 @@ public class MapReduceTests {
|
||||
}
|
||||
size++;
|
||||
}
|
||||
assertEquals(3,size);
|
||||
assertEquals(3, size);
|
||||
}
|
||||
|
||||
private void createNumberAndVersionData() {
|
||||
|
||||
@@ -6,35 +6,42 @@ public class NumberAndVersion {
|
||||
private Long number;
|
||||
private Long version;
|
||||
private Long value;
|
||||
|
||||
|
||||
public Long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(Long number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public Long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(Long version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NumberAndVersion [id=" + id + ", number=" + number + ", version=" + version + ", value=" + value + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.springframework.data.mongodb.core.mapreduce;
|
||||
public class ValueObject {
|
||||
|
||||
private String id;
|
||||
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -22,5 +22,5 @@ public class ValueObject {
|
||||
public String toString() {
|
||||
return "ValueObject [id=" + id + ", value=" + value + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,33 +3,28 @@ package org.springframework.data.mongodb.core.mapreduce;
|
||||
public class XObject {
|
||||
|
||||
private float x;
|
||||
|
||||
private float count;
|
||||
|
||||
private float count;
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
public void setX(float x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
|
||||
public float getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
public void setCount(float count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "XObject [x=" + x + " count = " + count + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -26,11 +26,11 @@ import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link BasicQuery}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class BasicQueryUnitTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void createsQueryFromPlainJson() {
|
||||
Query q = new BasicQuery("{ \"name\" : \"Thomas\"}");
|
||||
@@ -45,14 +45,14 @@ public class BasicQueryUnitTests {
|
||||
reference.put("age", new BasicDBObject("$lt", 80));
|
||||
assertThat(q.getQueryObject(), is(reference));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void overridesSortCorrectly() {
|
||||
|
||||
|
||||
BasicQuery query = new BasicQuery("{}");
|
||||
query.setSortObject(new BasicDBObject("name", -1));
|
||||
query.sort().on("lastname", Order.ASCENDING);
|
||||
|
||||
|
||||
DBObject sortReference = new BasicDBObject("name", -1);
|
||||
sortReference.put("lastname", 1);
|
||||
assertThat(query.getSortObject(), is(sortReference));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user