Compare commits
86 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ca16f8d15 | ||
|
|
1b3d49e466 | ||
|
|
bf89cce43c | ||
|
|
aef493fdb8 | ||
|
|
eabd47ae8d | ||
|
|
1d9ee9a28f | ||
|
|
e0b0792643 | ||
|
|
d5f8285d51 | ||
|
|
4ce8da7ebf | ||
|
|
c1030abe96 | ||
|
|
2a8f13d5d5 | ||
|
|
e4adc0ce23 | ||
|
|
beeed68873 | ||
|
|
22872f97dc | ||
|
|
323de58efc | ||
|
|
58f12b8d8f | ||
|
|
48cb155f6c | ||
|
|
594ddbd1c1 | ||
|
|
2c2bbf415b | ||
|
|
9375e7b981 | ||
|
|
30a4682369 | ||
|
|
356e6acd43 | ||
|
|
09ed4aaf24 | ||
|
|
c7995eb462 | ||
|
|
2e6a9a6ee7 | ||
|
|
a82fbade95 | ||
|
|
7a9ba3fe3e | ||
|
|
134e7762a7 | ||
|
|
e41299ff38 | ||
|
|
5cf7a86023 | ||
|
|
0aacb887de | ||
|
|
ba81f21aba | ||
|
|
43dee69fe0 | ||
|
|
1be1297ef9 | ||
|
|
dad0789356 | ||
|
|
80ee7d9553 | ||
|
|
7e3dfa5504 | ||
|
|
b5b11772b6 | ||
|
|
416dc563f2 | ||
|
|
a41b877081 | ||
|
|
c4c8e368ca | ||
|
|
11f0c515b0 | ||
|
|
25a94bc45e | ||
|
|
783cec0325 | ||
|
|
b02e81c481 | ||
|
|
3c90b4987d | ||
|
|
a4a03b0164 | ||
|
|
651255ca58 | ||
|
|
ccf006e41b | ||
|
|
cb6a1b7110 | ||
|
|
ba5a764f5d | ||
|
|
3be35cba2d | ||
|
|
9421c45c5a | ||
|
|
885c1b0f2c | ||
|
|
c8bb46ffb3 | ||
|
|
f82de367c8 | ||
|
|
5e62675bae | ||
|
|
c805d9ccae | ||
|
|
2d97288917 | ||
|
|
e38448a569 | ||
|
|
b1065b8f2d | ||
|
|
8cac1d9368 | ||
|
|
7184950f8a | ||
|
|
edd71cac78 | ||
|
|
82bd7a69eb | ||
|
|
b434a0810e | ||
|
|
40236d4099 | ||
|
|
8f6d940036 | ||
|
|
95a92ccf5d | ||
|
|
a6db24554f | ||
|
|
2f6c61ef9c | ||
|
|
d8bf7ebf3f | ||
|
|
ce42783e73 | ||
|
|
69474327c6 | ||
|
|
1bbe2e8247 | ||
|
|
94af898ae3 | ||
|
|
f6298f7005 | ||
|
|
d5b3c651b2 | ||
|
|
33dd00f0b8 | ||
|
|
3207a81555 | ||
|
|
d231519012 | ||
|
|
e052ecc9a4 | ||
|
|
071f2934a1 | ||
|
|
d2a18e9b11 | ||
|
|
d684fa1f8e | ||
|
|
1a0077231d |
67
pom.xml
67
pom.xml
@@ -1,11 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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">
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-dist</artifactId>
|
<artifactId>spring-data-mongodb-dist</artifactId>
|
||||||
<name>Spring Data MongoDB Distribution</name>
|
<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.5.BUILD-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<modules>
|
<modules>
|
||||||
<module>spring-data-mongodb</module>
|
<module>spring-data-mongodb</module>
|
||||||
@@ -14,7 +15,18 @@
|
|||||||
<module>spring-data-mongodb-parent</module>
|
<module>spring-data-mongodb-parent</module>
|
||||||
</modules>
|
</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>
|
<developer>
|
||||||
<id>trisberg</id>
|
<id>trisberg</id>
|
||||||
<name>Thomas Risberg</name>
|
<name>Thomas Risberg</name>
|
||||||
@@ -39,17 +51,6 @@
|
|||||||
</roles>
|
</roles>
|
||||||
<timezone>-5</timezone>
|
<timezone>-5</timezone>
|
||||||
</developer>
|
</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>
|
<developer>
|
||||||
<id>jbrisbin</id>
|
<id>jbrisbin</id>
|
||||||
<name>Jon Brisbin</name>
|
<name>Jon Brisbin</name>
|
||||||
@@ -145,37 +146,35 @@
|
|||||||
<htmlCustomization>${project.basedir}/src/docbkx/resources/xsl/html.xsl</htmlCustomization>
|
<htmlCustomization>${project.basedir}/src/docbkx/resources/xsl/html.xsl</htmlCustomization>
|
||||||
<useExtensions>1</useExtensions>
|
<useExtensions>1</useExtensions>
|
||||||
<highlightSource>1</highlightSource>
|
<highlightSource>1</highlightSource>
|
||||||
<highlightDefaultLanguage></highlightDefaultLanguage>
|
<highlightDefaultLanguage />
|
||||||
<!-- callouts -->
|
<!-- callouts -->
|
||||||
<entities>
|
<entities>
|
||||||
<entity>
|
<entity>
|
||||||
<name>version</name>
|
<name>version</name>
|
||||||
<value>${pom.version}</value>
|
<value>${project.version}</value>
|
||||||
</entity>
|
</entity>
|
||||||
</entities>
|
</entities>
|
||||||
<postProcess>
|
<postProcess>
|
||||||
<copy todir="${project.basedir}/target/site/reference">
|
<copy todir="${project.basedir}/target/site/reference">
|
||||||
<fileset dir="${project.basedir}/target/docbkx">
|
<fileset dir="${project.basedir}/target/docbkx">
|
||||||
<include name="**/*.html"/>
|
<include name="**/*.html" />
|
||||||
<include name="**/*.pdf"/>
|
<include name="**/*.pdf" />
|
||||||
</fileset>
|
</fileset>
|
||||||
</copy>
|
</copy>
|
||||||
<copy todir="${project.basedir}/target/site/reference/html">
|
<copy todir="${project.basedir}/target/site/reference/html">
|
||||||
<fileset dir="${project.basedir}/src/docbkx/resources">
|
<fileset dir="${project.basedir}/src/docbkx/resources">
|
||||||
<include name="**/*.css"/>
|
<include name="**/*.css" />
|
||||||
<include name="**/*.png"/>
|
<include name="**/*.png" />
|
||||||
<include name="**/*.gif"/>
|
<include name="**/*.gif" />
|
||||||
<include name="**/*.jpg"/>
|
<include name="**/*.jpg" />
|
||||||
</fileset>
|
</fileset>
|
||||||
</copy>
|
</copy>
|
||||||
<copy todir="${project.basedir}/target/site/reference/html">
|
<copy todir="${project.basedir}/target/site/reference/html">
|
||||||
<fileset dir="${project.basedir}/src/docbkx/resources/images">
|
<fileset dir="${project.basedir}/src/docbkx/resources/images">
|
||||||
<include name="*.png"/>
|
<include name="*.png" />
|
||||||
</fileset>
|
</fileset>
|
||||||
</copy>
|
</copy>
|
||||||
<move file="${project.basedir}/target/site/reference/pdf/index.pdf"
|
<move file="${project.basedir}/target/site/reference/pdf/index.pdf" tofile="${project.basedir}/target/site/reference/pdf/spring-data-mongo-reference.pdf" failonerror="false" />
|
||||||
tofile="${project.basedir}/target/site/reference/pdf/spring-data-mongo-reference.pdf"
|
|
||||||
failonerror="false"/>
|
|
||||||
</postProcess>
|
</postProcess>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
@@ -184,7 +183,7 @@
|
|||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>2.5</version>
|
<version>2.5</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<javadoc:aggregate>true</javadoc:aggregate>
|
<aggregate>true</aggregate>
|
||||||
<breakiterator>true</breakiterator>
|
<breakiterator>true</breakiterator>
|
||||||
<header>Spring Data Document</header>
|
<header>Spring Data Document</header>
|
||||||
<source>1.5</source>
|
<source>1.5</source>
|
||||||
@@ -234,7 +233,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<tasks>
|
<tasks>
|
||||||
<ant antfile="${basedir}/src/ant/upload-dist.xml">
|
<ant antfile="${basedir}/src/ant/upload-dist.xml">
|
||||||
<target name="upload-dist"/>
|
<target name="upload-dist" />
|
||||||
</ant>
|
</ant>
|
||||||
</tasks>
|
</tasks>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -270,9 +269,9 @@
|
|||||||
<url>http://repository.springsource.com/maven/bundles/release</url>
|
<url>http://repository.springsource.com/maven/bundles/release</url>
|
||||||
</pluginRepository>
|
</pluginRepository>
|
||||||
<pluginRepository>
|
<pluginRepository>
|
||||||
<id>repository.springframework.maven.release</id>
|
<id>spring-libs-release</id>
|
||||||
<name>Spring Framework Maven Release Repository</name>
|
<name>Spring Framework Maven Release Repository</name>
|
||||||
<url>http://repo.springsource.org/release</url>
|
<url>http://repo.springsource.org/libs-release</url>
|
||||||
</pluginRepository>
|
</pluginRepository>
|
||||||
</pluginRepositories>
|
</pluginRepositories>
|
||||||
|
|
||||||
@@ -282,7 +281,7 @@
|
|||||||
<site>
|
<site>
|
||||||
<id>static.springframework.org</id>
|
<id>static.springframework.org</id>
|
||||||
<url>
|
<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>
|
</url>
|
||||||
</site>
|
</site>
|
||||||
<repository>
|
<repository>
|
||||||
@@ -296,5 +295,7 @@
|
|||||||
<url>s3://maven.springframework.org/snapshot</url>
|
<url>s3://maven.springframework.org/snapshot</url>
|
||||||
</snapshotRepository>
|
</snapshotRepository>
|
||||||
</distributionManagement>
|
</distributionManagement>
|
||||||
|
<scm>
|
||||||
|
<url>https://github.com/SpringSource/spring-data-mongodb</url>
|
||||||
|
</scm>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>1.0.0.RELEASE</version>
|
<version>1.0.5.BUILD-SNAPSHOT</version>
|
||||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>spring-data-mongodb-cross-store</artifactId>
|
<artifactId>spring-data-mongodb-cross-store</artifactId>
|
||||||
@@ -68,24 +68,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>javax.mail</groupId>
|
|
||||||
<artifactId>mail</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>javax.jms</groupId>
|
|
||||||
<artifactId>jms</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.sun.jdmk</groupId>
|
|
||||||
<artifactId>jmxtools</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.sun.jmx</groupId>
|
|
||||||
<artifactId>jmxri</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -95,17 +77,6 @@
|
|||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mockito</groupId>
|
|
||||||
<artifactId>mockito-all</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.aspectj</groupId>
|
<groupId>org.aspectj</groupId>
|
||||||
<artifactId>aspectjrt</artifactId>
|
<artifactId>aspectjrt</artifactId>
|
||||||
@@ -151,25 +122,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</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>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<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">
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>1.0.0.RELEASE</version>
|
<version>1.0.5.BUILD-SNAPSHOT</version>
|
||||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>spring-data-mongodb-log4j</artifactId>
|
<artifactId>spring-data-mongodb-log4j</artifactId>
|
||||||
@@ -28,47 +27,9 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>javax.mail</groupId>
|
|
||||||
<artifactId>mail</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>javax.jms</groupId>
|
|
||||||
<artifactId>jms</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.sun.jdmk</groupId>
|
|
||||||
<artifactId>jmxtools</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.sun.jmx</groupId>
|
|
||||||
<artifactId>jmxri</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Test dependencies -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mockito</groupId>
|
|
||||||
<artifactId>mockito-all</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.hamcrest</groupId>
|
|
||||||
<artifactId>hamcrest-all</artifactId>
|
|
||||||
<version>1.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -1,63 +1,101 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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">
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<name>Spring Data MongoDB Parent</name>
|
<name>Spring Data MongoDB Parent</name>
|
||||||
|
<description>Spring Data project for MongoDB</description>
|
||||||
<url>http://www.springsource.org/spring-data/mongodb</url>
|
<url>http://www.springsource.org/spring-data/mongodb</url>
|
||||||
<version>1.0.0.RELEASE</version>
|
<version>1.0.5.BUILD-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<!-- versions for commonly-used dependencies -->
|
<!-- versions for commonly-used dependencies -->
|
||||||
<junit.version>4.8.1</junit.version>
|
<junit.version>4.10</junit.version>
|
||||||
<log4j.version>1.2.15</log4j.version>
|
<log4j.version>1.2.16</log4j.version>
|
||||||
<org.mockito.version>1.8.4</org.mockito.version>
|
<org.mockito.version>1.8.4</org.mockito.version>
|
||||||
|
<hamcrest.version>1.2.1</hamcrest.version>
|
||||||
<org.slf4j.version>1.5.10</org.slf4j.version>
|
<org.slf4j.version>1.5.10</org.slf4j.version>
|
||||||
<org.codehaus.jackson.version>1.6.1</org.codehaus.jackson.version>
|
<org.codehaus.jackson.version>1.6.1</org.codehaus.jackson.version>
|
||||||
<org.springframework.version.30>3.0.7.RELEASE</org.springframework.version.30>
|
<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.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>
|
<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>
|
<aspectj.version>1.6.11.RELEASE</aspectj.version>
|
||||||
</properties>
|
</properties>
|
||||||
<profiles>
|
|
||||||
<profile>
|
<developers>
|
||||||
<id>strict</id>
|
<developer>
|
||||||
<properties>
|
<id>ogierke</id>
|
||||||
<maven.test.failure.ignore>false</maven.test.failure.ignore>
|
<name>Oliver Gierke</name>
|
||||||
</properties>
|
<email>ogierke at vmware.com</email>
|
||||||
</profile>
|
<organization>SpringSource</organization>
|
||||||
<profile>
|
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||||
<id>fast</id>
|
<roles>
|
||||||
<properties>
|
<role>Project lead</role>
|
||||||
<maven.test.skip>true</maven.test.skip>
|
</roles>
|
||||||
<maven.javadoc.skip>true</maven.javadoc.skip>
|
<timezone>+1</timezone>
|
||||||
</properties>
|
</developer>
|
||||||
</profile>
|
<developer>
|
||||||
<profile>
|
<id>trisberg</id>
|
||||||
<id>staging</id>
|
<name>Thomas Risberg</name>
|
||||||
<distributionManagement>
|
<email>trisberg at vmware.com</email>
|
||||||
<site>
|
<organization>SpringSource</organization>
|
||||||
<id>spring-site-staging</id>
|
<organizationUrl>http://www.SpringSource.com</organizationUrl>
|
||||||
<url>file:///${java.io.tmpdir}/spring-data/mongodb/docs</url>
|
<roles>
|
||||||
</site>
|
<role>Project Admin</role>
|
||||||
<repository>
|
<role>Developer</role>
|
||||||
<id>spring-milestone-staging</id>
|
</roles>
|
||||||
<url>file:///${java.io.tmpdir}/spring-data/mongodb/milestone</url>
|
<timezone>-5</timezone>
|
||||||
</repository>
|
</developer>
|
||||||
<snapshotRepository>
|
<developer>
|
||||||
<id>spring-snapshot-staging</id>
|
<id>mpollack</id>
|
||||||
<url>file:///${java.io.tmpdir}/spring-data/mongodb/snapshot</url>
|
<name>Mark Pollack</name>
|
||||||
</snapshotRepository>
|
<email>mpollack at vmware.com</email>
|
||||||
</distributionManagement>
|
<organization>SpringSource</organization>
|
||||||
</profile>
|
<organizationUrl>http://www.SpringSource.com</organizationUrl>
|
||||||
<profile>
|
<roles>
|
||||||
<id>bootstrap</id>
|
<role>Project Admin</role>
|
||||||
<!-- TODO: move the repositories in here before release -->
|
<role>Developer</role>
|
||||||
</profile>
|
</roles>
|
||||||
</profiles>
|
<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>
|
||||||
|
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
<!-- see 'staging' profile for dry-run deployment settings -->
|
<!-- see 'staging' profile for dry-run deployment settings -->
|
||||||
<downloadUrl>http://www.springsource.com/download/community
|
<downloadUrl>http://www.springsource.com/download/community
|
||||||
@@ -65,7 +103,7 @@
|
|||||||
<site>
|
<site>
|
||||||
<id>static.springframework.org</id>
|
<id>static.springframework.org</id>
|
||||||
<url>
|
<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>
|
</url>
|
||||||
</site>
|
</site>
|
||||||
<repository>
|
<repository>
|
||||||
@@ -79,6 +117,9 @@
|
|||||||
<url>s3://maven.springframework.org/snapshot</url>
|
<url>s3://maven.springframework.org/snapshot</url>
|
||||||
</snapshotRepository>
|
</snapshotRepository>
|
||||||
</distributionManagement>
|
</distributionManagement>
|
||||||
|
<scm>
|
||||||
|
<url>https://github.com/SpringSource/spring-data-mongodb</url>
|
||||||
|
</scm>
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<!--
|
<!--
|
||||||
inheritable <dependency> declarations for child poms. children still
|
inheritable <dependency> declarations for child poms. children still
|
||||||
@@ -111,6 +152,11 @@
|
|||||||
<artifactId>spring-tx</artifactId>
|
<artifactId>spring-tx</artifactId>
|
||||||
<version>${org.springframework.version.range}</version>
|
<version>${org.springframework.version.range}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<version>${org.springframework.version.range}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-orm</artifactId>
|
<artifactId>spring-orm</artifactId>
|
||||||
@@ -152,7 +198,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb</artifactId>
|
<artifactId>spring-data-mongodb</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>1.0.5.BUILD-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Logging -->
|
<!-- Logging -->
|
||||||
@@ -178,24 +224,6 @@
|
|||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
<version>${log4j.version}</version>
|
<version>${log4j.version}</version>
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>javax.mail</groupId>
|
|
||||||
<artifactId>mail</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>javax.jms</groupId>
|
|
||||||
<artifactId>jms</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.sun.jdmk</groupId>
|
|
||||||
<artifactId>jmxtools</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.sun.jmx</groupId>
|
|
||||||
<artifactId>jmxri</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -208,14 +236,14 @@
|
|||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-all</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<version>${org.mockito.version}</version>
|
<version>${org.mockito.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit-dep</artifactId>
|
||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
@@ -223,19 +251,34 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!--
|
|
||||||
dependency definitions to be inherited by child poms. any
|
<!-- Test dependencies -->
|
||||||
<dependency> declarations here will automatically show up on child
|
|
||||||
project classpaths. only items that are truly common across all
|
|
||||||
projects (modules and samples) should go here. otherwise, consider
|
|
||||||
<dependencyManagement> above
|
|
||||||
-->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
<version>${log4j.version}</version>
|
<version>${log4j.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest-library</artifactId>
|
||||||
|
<version>${hamcrest.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit-dep</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -250,48 +293,11 @@
|
|||||||
<version>3.1.0.RELEASE</version>
|
<version>3.1.0.RELEASE</version>
|
||||||
</extension>
|
</extension>
|
||||||
</extensions>
|
</extensions>
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>${project.basedir}/src/main/java</directory>
|
|
||||||
<includes>
|
|
||||||
<include>**/*</include>
|
|
||||||
</includes>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/*.java</exclude>
|
|
||||||
</excludes>
|
|
||||||
</resource>
|
|
||||||
<resource>
|
|
||||||
<directory>${project.basedir}/src/main/resources</directory>
|
|
||||||
<includes>
|
|
||||||
<include>**/*</include>
|
|
||||||
</includes>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
<testResources>
|
|
||||||
<testResource>
|
|
||||||
<directory>${project.basedir}/src/test/java</directory>
|
|
||||||
<includes>
|
|
||||||
<include>**/*</include>
|
|
||||||
</includes>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/*.java</exclude>
|
|
||||||
</excludes>
|
|
||||||
</testResource>
|
|
||||||
<testResource>
|
|
||||||
<directory>${project.basedir}/src/test/resources</directory>
|
|
||||||
<includes>
|
|
||||||
<include>**/*</include>
|
|
||||||
</includes>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/*.java</exclude>
|
|
||||||
</excludes>
|
|
||||||
</testResource>
|
|
||||||
</testResources>
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>2.3.2</version>
|
<version>2.5.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.5</source>
|
<source>1.5</source>
|
||||||
<target>1.5</target>
|
<target>1.5</target>
|
||||||
@@ -311,13 +317,13 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>2.8</version>
|
<version>2.10</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<useFile>false</useFile>
|
<useFile>false</useFile>
|
||||||
<includes>
|
<includes>
|
||||||
<include>**/*Tests.java</include>
|
<include>**/*Tests.java</include>
|
||||||
</includes>
|
</includes>
|
||||||
<junitArtifactName>junit:junit</junitArtifactName>
|
<junitArtifactName>junit:junit-dep</junitArtifactName>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -369,22 +375,18 @@
|
|||||||
</build>
|
</build>
|
||||||
<pluginRepositories>
|
<pluginRepositories>
|
||||||
<pluginRepository>
|
<pluginRepository>
|
||||||
<!-- necessary for bundlor and utils -->
|
<id>spring-plugins-release</id>
|
||||||
<id>repository.plugin.springsource.release</id>
|
<url>http://repo.springsource.org/plugins-release</url>
|
||||||
<name>SpringSource Maven Repository</name>
|
|
||||||
<url>http://repository.springsource.com/maven/bundles/release</url>
|
|
||||||
</pluginRepository>
|
</pluginRepository>
|
||||||
<pluginRepository>
|
<pluginRepository>
|
||||||
<id>repository.springframework.maven.release</id>
|
<id>querydsl</id>
|
||||||
<name>Spring Framework Maven Release Repository</name>
|
<url>http://source.mysema.com/maven2/releases</url>
|
||||||
<url>http://repo.springsource.org/release</url>
|
|
||||||
</pluginRepository>
|
</pluginRepository>
|
||||||
</pluginRepositories>
|
</pluginRepositories>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>repository.springframework.maven.release</id>
|
<id>spring-libs-release</id>
|
||||||
<name>Spring Framework Maven Release Repository</name>
|
<url>http://repo.springsource.org/libs-release</url>
|
||||||
<url>http://repo.springsource.org/release</url>
|
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
<reporting>
|
<reporting>
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<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">
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>1.0.0.RELEASE</version>
|
<version>1.0.5.BUILD-SNAPSHOT</version>
|
||||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>spring-data-mongodb</artifactId>
|
<artifactId>spring-data-mongodb</artifactId>
|
||||||
@@ -19,10 +18,22 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<!-- Spring -->
|
<!-- Spring -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-tx</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-beans</artifactId>
|
<artifactId>spring-beans</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-expression</artifactId>
|
<artifactId>spring-expression</artifactId>
|
||||||
@@ -58,19 +69,6 @@
|
|||||||
<artifactId>querydsl-mongodb</artifactId>
|
<artifactId>querydsl-mongodb</artifactId>
|
||||||
<version>${querydsl.version}</version>
|
<version>${querydsl.version}</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.google.code.morphia</groupId>
|
|
||||||
<artifactId>morphia</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.mysema.querydsl</groupId>
|
|
||||||
<artifactId>querydsl-apt</artifactId>
|
|
||||||
<version>${querydsl.version}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -80,25 +78,6 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Test dependencies -->
|
<!-- Test dependencies -->
|
||||||
<dependency>
|
|
||||||
<groupId>org.mockito</groupId>
|
|
||||||
<artifactId>mockito-all</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.hamcrest</groupId>
|
|
||||||
<artifactId>hamcrest-all</artifactId>
|
|
||||||
<version>1.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>joda-time</groupId>
|
<groupId>joda-time</groupId>
|
||||||
<artifactId>joda-time</artifactId>
|
<artifactId>joda-time</artifactId>
|
||||||
@@ -109,8 +88,8 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>jcl-over-slf4j</artifactId>
|
<artifactId>jcl-over-slf4j</artifactId>
|
||||||
@@ -128,6 +107,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -138,7 +118,14 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.mysema.maven</groupId>
|
<groupId>com.mysema.maven</groupId>
|
||||||
<artifactId>maven-apt-plugin</artifactId>
|
<artifactId>maven-apt-plugin</artifactId>
|
||||||
<version>1.0.2</version>
|
<version>1.0.4</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysema.querydsl</groupId>
|
||||||
|
<artifactId>querydsl-apt</artifactId>
|
||||||
|
<version>${querydsl.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>generate-test-sources</phase>
|
<phase>generate-test-sources</phase>
|
||||||
@@ -154,15 +141,5 @@
|
|||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</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>
|
</project>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011 the original author or authors.
|
* Copyright 2011-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -18,7 +18,6 @@ package org.springframework.data.mongodb.config;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.mongodb.Mongo;
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||||
@@ -35,6 +34,14 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
|||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import com.mongodb.Mongo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class to ease JavaConfig setup for Spring Data MongoDB.
|
||||||
|
*
|
||||||
|
* @author Mark Pollack
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public abstract class AbstractMongoConfiguration {
|
public abstract class AbstractMongoConfiguration {
|
||||||
|
|
||||||
@@ -50,10 +57,11 @@ public abstract class AbstractMongoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public MongoDbFactory mongoDbFactory() throws Exception {
|
public MongoDbFactory mongoDbFactory() throws Exception {
|
||||||
if (getUserCredentials() == null) {
|
UserCredentials credentials = getUserCredentials();
|
||||||
|
if (credentials == null) {
|
||||||
return new SimpleMongoDbFactory(mongo(), getDatabaseName());
|
return new SimpleMongoDbFactory(mongo(), getDatabaseName());
|
||||||
} else {
|
} else {
|
||||||
return new SimpleMongoDbFactory(mongo(), getDatabaseName(), getUserCredentials());
|
return new SimpleMongoDbFactory(mongo(), getDatabaseName(), credentials);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,11 +143,11 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
|||||||
List<Element> customConvertersElements = DomUtils.getChildElementsByTagName(element, "custom-converters");
|
List<Element> customConvertersElements = DomUtils.getChildElementsByTagName(element, "custom-converters");
|
||||||
|
|
||||||
if (customConvertersElements.size() == 1) {
|
if (customConvertersElements.size() == 1) {
|
||||||
|
|
||||||
Element customerConvertersElement = customConvertersElements.get(0);
|
Element customerConvertersElement = customConvertersElements.get(0);
|
||||||
ManagedList<BeanMetadataElement> converterBeans = new ManagedList<BeanMetadataElement>();
|
ManagedList<BeanMetadataElement> converterBeans = new ManagedList<BeanMetadataElement>();
|
||||||
List<Element> converterElements = DomUtils.getChildElementsByTagName(customerConvertersElement, "converter");
|
List<Element> converterElements = DomUtils.getChildElementsByTagName(customerConvertersElement, "converter");
|
||||||
|
|
||||||
if (converterElements != null) {
|
if (converterElements != null) {
|
||||||
for (Element listenerElement : converterElements) {
|
for (Element listenerElement : converterElements) {
|
||||||
converterBeans.add(parseConverter(listenerElement, parserContext));
|
converterBeans.add(parseConverter(listenerElement, parserContext));
|
||||||
@@ -158,9 +158,9 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
|||||||
String packageToScan = customerConvertersElement.getAttribute(BASE_PACKAGE);
|
String packageToScan = customerConvertersElement.getAttribute(BASE_PACKAGE);
|
||||||
if (StringUtils.hasText(packageToScan)) {
|
if (StringUtils.hasText(packageToScan)) {
|
||||||
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||||
provider.addExcludeFilter(new NegatingFilter(new AssignableTypeFilter(Converter.class), new AssignableTypeFilter(
|
provider.addExcludeFilter(new NegatingFilter(new AssignableTypeFilter(Converter.class),
|
||||||
GenericConverter.class)));
|
new AssignableTypeFilter(GenericConverter.class)));
|
||||||
|
|
||||||
for (BeanDefinition candidate : provider.findCandidateComponents(packageToScan)) {
|
for (BeanDefinition candidate : provider.findCandidateComponents(packageToScan)) {
|
||||||
converterBeans.add(candidate);
|
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.
|
* {@link TypeFilter} that returns {@literal false} in case any of the given delegates matches.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
private static class NegatingFilter implements TypeFilter {
|
private static class NegatingFilter implements TypeFilter {
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ package org.springframework.data.mongodb.config;
|
|||||||
|
|
||||||
import java.beans.PropertyEditorSupport;
|
import java.beans.PropertyEditorSupport;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import com.mongodb.ServerAddress;
|
import com.mongodb.ServerAddress;
|
||||||
@@ -30,6 +34,8 @@ import com.mongodb.ServerAddress;
|
|||||||
*/
|
*/
|
||||||
public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
|
private static final Log LOG = LogFactory.getLog(ServerAddressPropertyEditor.class);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||||
@@ -38,21 +44,49 @@ public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
|||||||
public void setAsText(String replicaSetString) {
|
public void setAsText(String replicaSetString) {
|
||||||
|
|
||||||
String[] replicaSetStringArray = StringUtils.commaDelimitedListToStringArray(replicaSetString);
|
String[] replicaSetStringArray = StringUtils.commaDelimitedListToStringArray(replicaSetString);
|
||||||
ServerAddress[] serverAddresses = new ServerAddress[replicaSetStringArray.length];
|
Set<ServerAddress> serverAddresses = new HashSet<ServerAddress>(replicaSetStringArray.length);
|
||||||
|
|
||||||
for (int i = 0; i < replicaSetStringArray.length; i++) {
|
for (String element : replicaSetStringArray) {
|
||||||
|
|
||||||
String[] hostAndPort = StringUtils.delimitedListToStringArray(replicaSetStringArray[i], ":");
|
ServerAddress address = parseServerAddress(element);
|
||||||
|
|
||||||
try {
|
if (address != null) {
|
||||||
serverAddresses[i] = new ServerAddress(hostAndPort[0], Integer.parseInt(hostAndPort[1]));
|
serverAddresses.add(address);
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new IllegalArgumentException("Could not parse port " + hostAndPort[1], e);
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
throw new IllegalArgumentException("Could not parse host " + hostAndPort[0], e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setValue(serverAddresses);
|
if (serverAddresses.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Could not resolve at least one server of the replica set configuration! Validate your config!");
|
||||||
|
}
|
||||||
|
|
||||||
|
setValue(serverAddresses.toArray(new ServerAddress[serverAddresses.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given source into a {@link ServerAddress}.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* @return the
|
||||||
|
*/
|
||||||
|
private ServerAddress parseServerAddress(String source) {
|
||||||
|
|
||||||
|
String[] hostAndPort = StringUtils.delimitedListToStringArray(source.trim(), ":");
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(source) || hostAndPort.length > 2) {
|
||||||
|
LOG.warn(String.format("Could not parse address source '%s'. Check your replica set configuration!", source));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return hostAndPort.length == 1 ? new ServerAddress(hostAndPort[0]) : new ServerAddress(hostAndPort[0],
|
||||||
|
Integer.parseInt(hostAndPort[1]));
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
LOG.warn(String.format("Could not parse host '%s'. Check your replica set configuration!", hostAndPort[0]));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
LOG.warn(String.format("Could not parse port '%s'. Check your replica set configuration!", hostAndPort[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.config;
|
||||||
|
|
||||||
|
import org.springframework.core.convert.converter.Converter;
|
||||||
|
|
||||||
|
import com.mongodb.WriteConcern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converter to create {@link WriteConcern} instances from String representations.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public class StringToWriteConcernConverter implements Converter<String, WriteConcern> {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||||
|
*/
|
||||||
|
public WriteConcern convert(String source) {
|
||||||
|
|
||||||
|
WriteConcern writeConcern = WriteConcern.valueOf(source);
|
||||||
|
return writeConcern != null ? writeConcern : new WriteConcern(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,14 +16,13 @@
|
|||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.data.mongodb.core.index.IndexDefinition;
|
import org.springframework.data.mongodb.core.index.IndexDefinition;
|
||||||
|
import org.springframework.data.mongodb.core.index.IndexField;
|
||||||
import org.springframework.data.mongodb.core.index.IndexInfo;
|
import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||||
import org.springframework.data.mongodb.core.query.Order;
|
import org.springframework.data.mongodb.core.query.Order;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
@@ -123,25 +122,30 @@ public class DefaultIndexOperations implements IndexOperations {
|
|||||||
return getIndexData(dbObjectList);
|
return getIndexData(dbObjectList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private List<IndexInfo> getIndexData(List<DBObject> dbObjectList) {
|
private List<IndexInfo> getIndexData(List<DBObject> dbObjectList) {
|
||||||
|
|
||||||
List<IndexInfo> indexInfoList = new ArrayList<IndexInfo>();
|
List<IndexInfo> indexInfoList = new ArrayList<IndexInfo>();
|
||||||
|
|
||||||
for (DBObject ix : dbObjectList) {
|
for (DBObject ix : dbObjectList) {
|
||||||
|
|
||||||
Map<String, Order> keyOrderMap = new LinkedHashMap<String, Order>();
|
|
||||||
DBObject keyDbObject = (DBObject) ix.get("key");
|
DBObject keyDbObject = (DBObject) ix.get("key");
|
||||||
Iterator<?> entries = keyDbObject.toMap().entrySet().iterator();
|
int numberOfElements = keyDbObject.keySet().size();
|
||||||
|
|
||||||
while (entries.hasNext()) {
|
Map<String, Order> keyOrderMap = new HashMap<String, Order>();
|
||||||
Entry<Object, Integer> thisEntry = (Entry<Object, Integer>) entries.next();
|
List<IndexField> indexFields = new ArrayList<IndexField>(numberOfElements);
|
||||||
String key = thisEntry.getKey().toString();
|
|
||||||
int value = thisEntry.getValue();
|
for (String key : keyDbObject.keySet()) {
|
||||||
if (value == 1) {
|
|
||||||
|
Object value = keyDbObject.get(key);
|
||||||
|
|
||||||
|
if (Integer.valueOf(1).equals(value)) {
|
||||||
keyOrderMap.put(key, Order.ASCENDING);
|
keyOrderMap.put(key, Order.ASCENDING);
|
||||||
} else {
|
indexFields.add(IndexField.create(key, Order.ASCENDING));
|
||||||
|
} else if (Integer.valueOf(-1).equals(value)) {
|
||||||
keyOrderMap.put(key, Order.DESCENDING);
|
keyOrderMap.put(key, Order.DESCENDING);
|
||||||
|
indexFields.add(IndexField.create(key, Order.DESCENDING));
|
||||||
|
} else if ("2d".equals(value)) {
|
||||||
|
indexFields.add(IndexField.geo(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,12 +155,11 @@ public class DefaultIndexOperations implements IndexOperations {
|
|||||||
boolean dropDuplicates = ix.containsField("dropDups") ? (Boolean) ix.get("dropDups") : false;
|
boolean dropDuplicates = ix.containsField("dropDups") ? (Boolean) ix.get("dropDups") : false;
|
||||||
boolean sparse = ix.containsField("sparse") ? (Boolean) ix.get("sparse") : false;
|
boolean sparse = ix.containsField("sparse") ? (Boolean) ix.get("sparse") : false;
|
||||||
|
|
||||||
indexInfoList.add(new IndexInfo(keyOrderMap, name, unique, dropDuplicates, sparse));
|
indexInfoList.add(new IndexInfo(keyOrderMap, indexFields, name, unique, dropDuplicates, sparse));
|
||||||
}
|
}
|
||||||
|
|
||||||
return indexInfoList;
|
return indexInfoList;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,15 +21,16 @@ import com.mongodb.DBObject;
|
|||||||
import com.mongodb.MongoException;
|
import com.mongodb.MongoException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface used by {@link MongoTemplate} for processing documents returned from a MongoDB query on a per-document basis.
|
* An interface used by {@link MongoTemplate} for processing documents returned from a MongoDB query on a per-document
|
||||||
* Implementations of this interface perform the actual work of prcoessing each document but don't need to worry about
|
* basis. Implementations of this interface perform the actual work of prcoessing each document but don't need to worry
|
||||||
* exception handling. {@MongoException}s will be caught and translated by the calling MongoTemplate
|
* 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
|
* An DocumentCallbackHandler is typically stateful: It keeps the result state within the object, to be available later
|
||||||
* inspection.
|
* for later inspection.
|
||||||
*
|
*
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface DocumentCallbackHandler {
|
public interface DocumentCallbackHandler {
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ package org.springframework.data.mongodb.core;
|
|||||||
public class FindAndModifyOptions {
|
public class FindAndModifyOptions {
|
||||||
|
|
||||||
boolean returnNew;
|
boolean returnNew;
|
||||||
|
|
||||||
boolean upsert;
|
boolean upsert;
|
||||||
|
|
||||||
boolean remove;
|
boolean remove;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,17 +31,17 @@ public class FindAndModifyOptions {
|
|||||||
public static FindAndModifyOptions options() {
|
public static FindAndModifyOptions options() {
|
||||||
return new FindAndModifyOptions();
|
return new FindAndModifyOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FindAndModifyOptions returnNew(boolean returnNew) {
|
public FindAndModifyOptions returnNew(boolean returnNew) {
|
||||||
this.returnNew = returnNew;
|
this.returnNew = returnNew;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FindAndModifyOptions upsert(boolean upsert) {
|
public FindAndModifyOptions upsert(boolean upsert) {
|
||||||
this.upsert = upsert;
|
this.upsert = upsert;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FindAndModifyOptions remove(boolean remove) {
|
public FindAndModifyOptions remove(boolean remove) {
|
||||||
this.remove = remove;
|
this.remove = remove;
|
||||||
return this;
|
return this;
|
||||||
@@ -58,7 +58,5 @@ public class FindAndModifyOptions {
|
|||||||
public boolean isRemove() {
|
public boolean isRemove() {
|
||||||
return remove;
|
return remove;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,35 +20,38 @@ import com.mongodb.DBObject;
|
|||||||
import com.mongodb.WriteConcern;
|
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.
|
* WriteConcern based on this information.
|
||||||
*
|
*
|
||||||
* Properties that will always be not-null are collectionName and defaultWriteConcern.
|
* Properties that will always be not-null are collectionName and defaultWriteConcern. The EntityClass is null only for
|
||||||
* The EntityClass is null only for the MongoActionOperaton.INSERT_LIST.
|
* the MongoActionOperaton.INSERT_LIST.
|
||||||
*
|
*
|
||||||
* INSERT, SAVE have null query,
|
* <ul>
|
||||||
* REMOVE has null document
|
* <li>INSERT, SAVE have null query</li>
|
||||||
* INSERT_LIST has null entityClass, document, and query.
|
* <li>REMOVE has null document</li>
|
||||||
|
* <li>INSERT_LIST has null entityClass, document, and query</li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MongoAction {
|
public class MongoAction {
|
||||||
|
|
||||||
private String collectionName;
|
private String collectionName;
|
||||||
|
|
||||||
private WriteConcern defaultWriteConcern;
|
private WriteConcern defaultWriteConcern;
|
||||||
|
|
||||||
private Class<?> entityClass;
|
private Class<?> entityClass;
|
||||||
|
|
||||||
private MongoActionOperation mongoActionOperation;
|
private MongoActionOperation mongoActionOperation;
|
||||||
|
|
||||||
private DBObject query;
|
private DBObject query;
|
||||||
|
|
||||||
private DBObject document;
|
private DBObject document;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance of a MongoAction
|
* Create an instance of a MongoAction
|
||||||
|
*
|
||||||
* @param defaultWriteConcern the default write concern
|
* @param defaultWriteConcern the default write concern
|
||||||
* @param mongoActionOperation action being taken against the collection
|
* @param mongoActionOperation action being taken against the collection
|
||||||
* @param collectionName the collection name
|
* @param collectionName the collection name
|
||||||
@@ -90,7 +93,5 @@ public class MongoAction {
|
|||||||
public DBObject getDocument() {
|
public DBObject getDocument() {
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,18 +16,14 @@
|
|||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumeration for operations on a collection. Used with {@link MongoAction} to help determine the
|
* Enumeration for operations on a collection. Used with {@link MongoAction} to help determine the WriteConcern to use
|
||||||
* WriteConcern to use for a given mutating operation
|
* for a given mutating operation
|
||||||
*
|
*
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
* @see MongoAction
|
* @see MongoAction
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public enum MongoActionOperation {
|
public enum MongoActionOperation {
|
||||||
|
|
||||||
REMOVE,
|
REMOVE, UPDATE, INSERT, INSERT_LIST, SAVE
|
||||||
UPDATE,
|
|
||||||
INSERT,
|
|
||||||
INSERT_LIST,
|
|
||||||
SAVE
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,14 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
import com.mongodb.DB;
|
|
||||||
import com.mongodb.Mongo;
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
|
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import com.mongodb.DB;
|
||||||
|
import com.mongodb.Mongo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class featuring helper methods for internal MongoDb classes.
|
* Helper class featuring helper methods for internal MongoDb classes.
|
||||||
* <p/>
|
* <p/>
|
||||||
@@ -78,7 +79,7 @@ public abstract class MongoDbUtils {
|
|||||||
DB db = null;
|
DB db = null;
|
||||||
if (TransactionSynchronizationManager.isSynchronizationActive() && dbHolder.doesNotHoldNonDefaultDB()) {
|
if (TransactionSynchronizationManager.isSynchronizationActive() && dbHolder.doesNotHoldNonDefaultDB()) {
|
||||||
// Spring transaction management is active ->
|
// Spring transaction management is active ->
|
||||||
db = dbHolder.getDB();
|
db = dbHolder.getDB(databaseName);
|
||||||
if (db != null && !dbHolder.isSynchronizedWithTransaction()) {
|
if (db != null && !dbHolder.isSynchronizedWithTransaction()) {
|
||||||
LOGGER.debug("Registering Spring transaction synchronization for existing Mongo DB");
|
LOGGER.debug("Registering Spring transaction synchronization for existing Mongo DB");
|
||||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(dbHolder, mongo));
|
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(dbHolder, mongo));
|
||||||
@@ -96,10 +97,12 @@ public abstract class MongoDbUtils {
|
|||||||
boolean credentialsGiven = username != null && password != null;
|
boolean credentialsGiven = username != null && password != null;
|
||||||
if (credentialsGiven && !db.isAuthenticated()) {
|
if (credentialsGiven && !db.isAuthenticated()) {
|
||||||
// Note, can only authenticate once against the same com.mongodb.DB object.
|
// Note, can only authenticate once against the same com.mongodb.DB object.
|
||||||
if (!db.authenticate(username, password)) {
|
synchronized (db) {
|
||||||
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName
|
if (!db.authenticate(username, password)) {
|
||||||
+ "], username = [" + username + "], password = [" + new String(password) + "]", databaseName, username,
|
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName
|
||||||
password);
|
+ "], username = [" + username + "], password = [" + new String(password) + "]", databaseName, username,
|
||||||
|
password);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,9 +113,9 @@ public abstract class MongoDbUtils {
|
|||||||
LOGGER.debug("Registering Spring transaction synchronization for new Hibernate Session");
|
LOGGER.debug("Registering Spring transaction synchronization for new Hibernate Session");
|
||||||
DbHolder holderToUse = dbHolder;
|
DbHolder holderToUse = dbHolder;
|
||||||
if (holderToUse == null) {
|
if (holderToUse == null) {
|
||||||
holderToUse = new DbHolder(db);
|
holderToUse = new DbHolder(databaseName, db);
|
||||||
} else {
|
} else {
|
||||||
holderToUse.addDB(db);
|
holderToUse.addDB(databaseName, db);
|
||||||
}
|
}
|
||||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(holderToUse, mongo));
|
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(holderToUse, mongo));
|
||||||
holderToUse.setSynchronizedWithTransaction(true);
|
holderToUse.setSynchronizedWithTransaction(true);
|
||||||
@@ -143,7 +146,7 @@ public abstract class MongoDbUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo);
|
DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo);
|
||||||
return (dbHolder != null && dbHolder.containsDB(db));
|
return dbHolder != null && dbHolder.containsDB(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011 the original author or authors.
|
* Copyright 2010-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,15 +13,14 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||||
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
|
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
|
||||||
@@ -39,12 +38,10 @@ import com.mongodb.WriteConcern;
|
|||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptionTranslator {
|
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, DisposableBean,
|
||||||
|
PersistenceExceptionTranslator {
|
||||||
|
|
||||||
/**
|
private Mongo mongo;
|
||||||
* Logger, available to subclasses.
|
|
||||||
*/
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
|
||||||
|
|
||||||
private MongoOptions mongoOptions;
|
private MongoOptions mongoOptions;
|
||||||
private String host;
|
private String host;
|
||||||
@@ -89,34 +86,7 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptio
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Mongo getObject() throws Exception {
|
public Mongo getObject() throws Exception {
|
||||||
|
|
||||||
Mongo mongo;
|
|
||||||
|
|
||||||
ServerAddress defaultOptions = new ServerAddress();
|
|
||||||
|
|
||||||
if (mongoOptions == null) {
|
|
||||||
mongoOptions = new MongoOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (replicaPair != null) {
|
|
||||||
if (replicaPair.size() < 2) {
|
|
||||||
throw new CannotGetMongoDbConnectionException("A replica pair must have two server entries");
|
|
||||||
}
|
|
||||||
mongo = new Mongo(replicaPair.get(0), replicaPair.get(1), mongoOptions);
|
|
||||||
} else if (replicaSetSeeds != null) {
|
|
||||||
mongo = new Mongo(replicaSetSeeds, mongoOptions);
|
|
||||||
} else {
|
|
||||||
String mongoHost = host != null ? host : defaultOptions.getHost();
|
|
||||||
mongo = port != null ? new Mongo(new ServerAddress(mongoHost, port), mongoOptions) : new Mongo(mongoHost,
|
|
||||||
mongoOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (writeConcern != null) {
|
|
||||||
mongo.setWriteConcern(writeConcern);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mongo;
|
return mongo;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -142,4 +112,45 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptio
|
|||||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||||
return exceptionTranslator.translateExceptionIfPossible(ex);
|
return exceptionTranslator.translateExceptionIfPossible(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||||
|
*/
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
|
||||||
|
Mongo mongo;
|
||||||
|
ServerAddress defaultOptions = new ServerAddress();
|
||||||
|
|
||||||
|
if (mongoOptions == null) {
|
||||||
|
mongoOptions = new MongoOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replicaPair != null) {
|
||||||
|
if (replicaPair.size() < 2) {
|
||||||
|
throw new CannotGetMongoDbConnectionException("A replica pair must have two server entries");
|
||||||
|
}
|
||||||
|
mongo = new Mongo(replicaPair.get(0), replicaPair.get(1), mongoOptions);
|
||||||
|
} else if (replicaSetSeeds != null) {
|
||||||
|
mongo = new Mongo(replicaSetSeeds, mongoOptions);
|
||||||
|
} else {
|
||||||
|
String mongoHost = host != null ? host : defaultOptions.getHost();
|
||||||
|
mongo = port != null ? new Mongo(new ServerAddress(mongoHost, port), mongoOptions) : new Mongo(mongoHost,
|
||||||
|
mongoOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writeConcern != null) {
|
||||||
|
mongo.setWriteConcern(writeConcern);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mongo = mongo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.DisposableBean#destroy()
|
||||||
|
*/
|
||||||
|
public void destroy() throws Exception {
|
||||||
|
this.mongo.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011 the original author or authors.
|
* Copyright 2010-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under t
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
import org.springframework.util.ResourceUtils;
|
|
||||||
|
|
||||||
import org.springframework.data.convert.EntityReader;
|
|
||||||
he Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
@@ -20,6 +16,7 @@ he Apache License, Version 2.0 (the "License");
|
|||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||||
|
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
@@ -50,6 +47,7 @@ import org.springframework.dao.DataIntegrityViolationException;
|
|||||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
import org.springframework.data.authentication.UserCredentials;
|
import org.springframework.data.authentication.UserCredentials;
|
||||||
import org.springframework.data.convert.EntityReader;
|
import org.springframework.data.convert.EntityReader;
|
||||||
|
import org.springframework.data.mapping.PersistentEntity;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.data.mapping.model.BeanWrapper;
|
import org.springframework.data.mapping.model.BeanWrapper;
|
||||||
import org.springframework.data.mapping.model.MappingException;
|
import org.springframework.data.mapping.model.MappingException;
|
||||||
@@ -108,6 +106,7 @@ import com.mongodb.util.JSON;
|
|||||||
* @author Graeme Rocher
|
* @author Graeme Rocher
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
|
* @author Amol Nayak
|
||||||
*/
|
*/
|
||||||
public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||||
|
|
||||||
@@ -333,11 +332,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
Assert.notNull(query);
|
Assert.notNull(query);
|
||||||
|
|
||||||
DBObject queryObject = query.getQueryObject();
|
DBObject queryObject = query.getQueryObject();
|
||||||
|
DBObject sortObject = query.getSortObject();
|
||||||
DBObject fieldsObject = query.getFieldsObject();
|
DBObject fieldsObject = query.getFieldsObject();
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
LOGGER.debug("find using query: " + queryObject + " fields: " + fieldsObject + " in collection: "
|
LOGGER.debug(String.format("Executing query: %s sort: %s fields: %s in collection: $s",
|
||||||
+ collectionName);
|
serializeToJsonSafely(queryObject), sortObject, fieldsObject, collectionName));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.executeQueryInternal(new FindCallback(queryObject, fieldsObject), preparer, dch, collectionName);
|
this.executeQueryInternal(new FindCallback(queryObject, fieldsObject), preparer, dch, collectionName);
|
||||||
@@ -456,7 +456,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
} else {
|
} else {
|
||||||
query.limit(1);
|
query.limit(1);
|
||||||
List<T> results = find(query, entityClass, collectionName);
|
List<T> results = find(query, entityClass, collectionName);
|
||||||
return (results.isEmpty() ? null : results.get(0));
|
return results.isEmpty() ? null : results.get(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -732,11 +732,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.INSERT, collectionName,
|
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.INSERT, collectionName,
|
||||||
entityClass, dbDoc, null);
|
entityClass, dbDoc, null);
|
||||||
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
||||||
|
WriteResult wr;
|
||||||
if (writeConcernToUse == null) {
|
if (writeConcernToUse == null) {
|
||||||
collection.insert(dbDoc);
|
wr = collection.insert(dbDoc);
|
||||||
} else {
|
} else {
|
||||||
collection.insert(dbDoc, writeConcernToUse);
|
wr = collection.insert(dbDoc, writeConcernToUse);
|
||||||
}
|
}
|
||||||
|
handleAnyWriteResultErrors(wr, dbDoc, "insert");
|
||||||
return dbDoc.get(ID);
|
return dbDoc.get(ID);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -755,11 +757,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.INSERT_LIST, collectionName, null,
|
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.INSERT_LIST, collectionName, null,
|
||||||
null, null);
|
null, null);
|
||||||
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
||||||
|
WriteResult wr;
|
||||||
if (writeConcernToUse == null) {
|
if (writeConcernToUse == null) {
|
||||||
collection.insert(dbDocList);
|
wr = collection.insert(dbDocList);
|
||||||
} else {
|
} else {
|
||||||
collection.insert(dbDocList.toArray((DBObject[]) new BasicDBObject[dbDocList.size()]), writeConcernToUse);
|
wr = collection.insert(dbDocList.toArray((DBObject[]) new BasicDBObject[dbDocList.size()]), writeConcernToUse);
|
||||||
}
|
}
|
||||||
|
handleAnyWriteResultErrors(wr, null, "insert_list");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -786,11 +790,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.SAVE, collectionName, entityClass,
|
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.SAVE, collectionName, entityClass,
|
||||||
dbDoc, null);
|
dbDoc, null);
|
||||||
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
||||||
|
WriteResult wr;
|
||||||
if (writeConcernToUse == null) {
|
if (writeConcernToUse == null) {
|
||||||
collection.save(dbDoc);
|
wr = collection.save(dbDoc);
|
||||||
} else {
|
} else {
|
||||||
collection.save(dbDoc, writeConcernToUse);
|
wr = collection.save(dbDoc, writeConcernToUse);
|
||||||
}
|
}
|
||||||
|
handleAnyWriteResultErrors(wr, dbDoc, "save");
|
||||||
return dbDoc.get(ID);
|
return dbDoc.get(ID);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -873,7 +879,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(getIdQueryFor(object), collection);
|
doRemove(collection, getIdQueryFor(object), object.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -938,7 +944,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
entityClass, null, queryObject);
|
entityClass, null, queryObject);
|
||||||
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
LOGGER.debug("remove using query: " + queryObject + " in collection: " + collection.getName());
|
LOGGER.debug("remove using query: " + dboq + " in collection: " + collection.getName());
|
||||||
}
|
}
|
||||||
if (writeConcernToUse == null) {
|
if (writeConcernToUse == null) {
|
||||||
wr = collection.remove(dboq);
|
wr = collection.remove(dboq);
|
||||||
@@ -996,26 +1002,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
LOGGER.debug("Executing MapReduce on collection [" + command.getInput() + "], mapFunction [" + mapFunc
|
LOGGER.debug("Executing MapReduce on collection [" + command.getInput() + "], mapFunction [" + mapFunc
|
||||||
+ "], reduceFunction [" + reduceFunc + "]");
|
+ "], reduceFunction [" + reduceFunc + "]");
|
||||||
}
|
}
|
||||||
CommandResult commandResult = null;
|
|
||||||
try {
|
CommandResult commandResult = command.getOutputType() == MapReduceCommand.OutputType.INLINE ? executeCommand(
|
||||||
if (command.getOutputType() == MapReduceCommand.OutputType.INLINE) {
|
commandObject, getDb().getOptions()) : executeCommand(commandObject);
|
||||||
commandResult = executeCommand(commandObject, getDb().getOptions());
|
handleCommandError(commandResult, commandObject);
|
||||||
} else {
|
|
||||||
commandResult = executeCommand(commandObject);
|
|
||||||
}
|
|
||||||
commandResult.throwOnError();
|
|
||||||
} catch (RuntimeException ex) {
|
|
||||||
this.potentiallyConvertRuntimeException(ex);
|
|
||||||
}
|
|
||||||
String error = commandResult.getErrorMessage();
|
|
||||||
if (error != null) {
|
|
||||||
throw new InvalidDataAccessApiUsageException("Command execution failed: Error [" + error + "], Command = "
|
|
||||||
+ commandObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
LOGGER.debug("MapReduce command result = [" + commandResult + "]");
|
LOGGER.debug(String.format("MapReduce command result = [%s]", serializeToJsonSafely(commandObject)));
|
||||||
}
|
}
|
||||||
|
|
||||||
MapReduceOutput mapReduceOutput = new MapReduceOutput(inputCollection, commandObject, commandResult);
|
MapReduceOutput mapReduceOutput = new MapReduceOutput(inputCollection, commandObject, commandResult);
|
||||||
List<T> mappedResults = new ArrayList<T>();
|
List<T> mappedResults = new ArrayList<T>();
|
||||||
DbObjectCallback<T> callback = new ReadDbObjectCallback<T>(mongoConverter, entityClass);
|
DbObjectCallback<T> callback = new ReadDbObjectCallback<T>(mongoConverter, entityClass);
|
||||||
@@ -1040,7 +1035,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
if (criteria == null) {
|
if (criteria == null) {
|
||||||
dbo.put("cond", null);
|
dbo.put("cond", null);
|
||||||
} else {
|
} else {
|
||||||
dbo.put("cond", criteria.getCriteriaObject());
|
dbo.put("cond", mapper.getMappedObject(criteria.getCriteriaObject(), null));
|
||||||
}
|
}
|
||||||
// If initial document was a JavaScript string, potentially loaded by Spring's Resource abstraction, load it and
|
// If initial document was a JavaScript string, potentially loaded by Spring's Resource abstraction, load it and
|
||||||
// convert to DBObject
|
// convert to DBObject
|
||||||
@@ -1066,21 +1061,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
DBObject commandObject = new BasicDBObject("group", dbo);
|
DBObject commandObject = new BasicDBObject("group", dbo);
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
LOGGER.debug("Executing Group with DBObject [" + commandObject.toString() + "]");
|
LOGGER.debug(String.format("Executing Group with DBObject [%s]", serializeToJsonSafely(commandObject)));
|
||||||
}
|
|
||||||
CommandResult commandResult = null;
|
|
||||||
try {
|
|
||||||
commandResult = executeCommand(commandObject, getDb().getOptions());
|
|
||||||
commandResult.throwOnError();
|
|
||||||
} catch (RuntimeException ex) {
|
|
||||||
this.potentiallyConvertRuntimeException(ex);
|
|
||||||
}
|
|
||||||
String error = commandResult.getErrorMessage();
|
|
||||||
if (error != null) {
|
|
||||||
throw new InvalidDataAccessApiUsageException("Command execution failed: Error [" + error + "], Command = "
|
|
||||||
+ commandObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandResult commandResult = executeCommand(commandObject, getDb().getOptions());
|
||||||
|
handleCommandError(commandResult, commandObject);
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
LOGGER.debug("Group command result = [" + commandResult + "]");
|
LOGGER.debug("Group command result = [" + commandResult + "]");
|
||||||
}
|
}
|
||||||
@@ -1251,11 +1237,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
|
|
||||||
protected <S, T> List<T> doFind(String collectionName, DBObject query, DBObject fields, Class<S> entityClass,
|
protected <S, T> List<T> doFind(String collectionName, DBObject query, DBObject fields, Class<S> entityClass,
|
||||||
CursorPreparer preparer, DbObjectCallback<T> objectCallback) {
|
CursorPreparer preparer, DbObjectCallback<T> objectCallback) {
|
||||||
|
|
||||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
LOGGER.debug("find using query: " + query + " fields: " + fields + " for class: " + entityClass
|
LOGGER.debug(String.format("find using query: %s fields: %s for class: %s in collection: %s",
|
||||||
+ " in collection: " + collectionName);
|
serializeToJsonSafely(query), fields, entityClass, collectionName));
|
||||||
}
|
}
|
||||||
|
|
||||||
return executeFindMultiInternal(new FindCallback(mapper.getMappedObject(query, entity), fields), preparer,
|
return executeFindMultiInternal(new FindCallback(mapper.getMappedObject(query, entity), fields), preparer,
|
||||||
objectCallback, collectionName);
|
objectCallback, collectionName);
|
||||||
}
|
}
|
||||||
@@ -1337,13 +1326,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
updateObj.put(key, mongoConverter.convertToMongoType(updateObj.get(key)));
|
updateObj.put(key, mongoConverter.convertToMongoType(updateObj.get(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DBObject mappedQuery = mapper.getMappedObject(query, entity);
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
LOGGER.debug("findAndModify using query: " + query + " fields: " + fields + " sort: " + sort + " for class: "
|
LOGGER.debug("findAndModify using query: " + mappedQuery + " fields: " + fields + " sort: " + sort
|
||||||
+ entityClass + " and update: " + updateObj + " in collection: " + collectionName);
|
+ " for class: " + entityClass + " and update: " + updateObj + " in collection: " + collectionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return executeFindOneInternal(new FindAndModifyCallback(mapper.getMappedObject(query, entity), fields, sort,
|
return executeFindOneInternal(new FindAndModifyCallback(mappedQuery, fields, sort, updateObj, options),
|
||||||
updateObj, options), new ReadDbObjectCallback<T>(readerToUse, entityClass), collectionName);
|
new ReadDbObjectCallback<T>(readerToUse, entityClass), collectionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1364,9 +1355,19 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConversionService conversionService = mongoConverter.getConversionService();
|
||||||
|
BeanWrapper<PersistentEntity<Object, ?>, Object> wrapper = BeanWrapper.create(savedObject, conversionService);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BeanWrapper.create(savedObject, mongoConverter.getConversionService()).setProperty(idProp, id);
|
|
||||||
return;
|
Object idValue = wrapper.getProperty(idProp, idProp.getType(), true);
|
||||||
|
|
||||||
|
if (idValue != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapper.setProperty(idProp, id);
|
||||||
|
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new MappingException(e.getMessage(), e);
|
throw new MappingException(e.getMessage(), e);
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
@@ -1514,9 +1515,16 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
String error = wr.getError();
|
String error = wr.getError();
|
||||||
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
|
String message;
|
||||||
String message = String.format("Execution of %s%s failed: %s", operation, query == null ? "" : "' using '"
|
if (operation.equals("insert") || operation.equals("save")) {
|
||||||
+ query.toString() + "' query", error);
|
// assuming the insert operations will begin with insert string
|
||||||
|
message = String.format("Insert/Save for %s failed: %s", query, error);
|
||||||
|
} else if (operation.equals("insert_list")) {
|
||||||
|
message = String.format("Insert list failed: %s", error);
|
||||||
|
} else {
|
||||||
|
message = String.format("Execution of %s%s failed: %s", operation,
|
||||||
|
query == null ? "" : "' using '" + query.toString() + "' query", error);
|
||||||
|
}
|
||||||
|
|
||||||
if (WriteResultChecking.EXCEPTION == this.writeResultChecking) {
|
if (WriteResultChecking.EXCEPTION == this.writeResultChecking) {
|
||||||
throw new DataIntegrityViolationException(message);
|
throw new DataIntegrityViolationException(message);
|
||||||
@@ -1539,6 +1547,27 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
|||||||
return resolved == null ? ex : resolved;
|
return resolved == null ? ex : resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inspects the given {@link CommandResult} for erros and potentially throws an
|
||||||
|
* {@link InvalidDataAccessApiUsageException} for that error.
|
||||||
|
*
|
||||||
|
* @param result must not be {@literal null}.
|
||||||
|
* @param source must not be {@literal null}.
|
||||||
|
*/
|
||||||
|
private void handleCommandError(CommandResult result, DBObject source) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
result.throwOnError();
|
||||||
|
} catch (MongoException ex) {
|
||||||
|
|
||||||
|
String error = result.getErrorMessage();
|
||||||
|
error = error == null ? "NO MESSAGE" : error;
|
||||||
|
|
||||||
|
throw new InvalidDataAccessApiUsageException("Command execution failed: Error [" + error + "], Command = "
|
||||||
|
+ source, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final MongoConverter getDefaultMongoConverter(MongoDbFactory factory) {
|
private static final MongoConverter getDefaultMongoConverter(MongoDbFactory factory) {
|
||||||
MappingMongoConverter converter = new MappingMongoConverter(factory, new MongoMappingContext());
|
MappingMongoConverter converter = new MappingMongoConverter(factory, new MongoMappingContext());
|
||||||
converter.afterPropertiesSet();
|
converter.afterPropertiesSet();
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
|||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import com.mongodb.BasicDBList;
|
||||||
import com.mongodb.BasicDBObject;
|
import com.mongodb.BasicDBObject;
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
|
|
||||||
@@ -41,6 +42,9 @@ import com.mongodb.DBObject;
|
|||||||
*/
|
*/
|
||||||
public class QueryMapper {
|
public class QueryMapper {
|
||||||
|
|
||||||
|
private static final List<String> DEFAULT_ID_NAMES = Arrays.asList("id", "_id");
|
||||||
|
private static final String N_OR_PATTERN = "\\$.*or";
|
||||||
|
|
||||||
private final ConversionService conversionService;
|
private final ConversionService conversionService;
|
||||||
private final MongoConverter converter;
|
private final MongoConverter converter;
|
||||||
|
|
||||||
@@ -59,8 +63,8 @@ public class QueryMapper {
|
|||||||
* Replaces the property keys used in the given {@link DBObject} with the appropriate keys by using the
|
* Replaces the property keys used in the given {@link DBObject} with the appropriate keys by using the
|
||||||
* {@link PersistentEntity} metadata.
|
* {@link PersistentEntity} metadata.
|
||||||
*
|
*
|
||||||
* @param query
|
* @param query must not be {@literal null}.
|
||||||
* @param entity
|
* @param entity can be {@literal null}.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public DBObject getMappedObject(DBObject query, MongoPersistentEntity<?> entity) {
|
public DBObject getMappedObject(DBObject query, MongoPersistentEntity<?> entity) {
|
||||||
@@ -68,8 +72,10 @@ public class QueryMapper {
|
|||||||
DBObject newDbo = new BasicDBObject();
|
DBObject newDbo = new BasicDBObject();
|
||||||
|
|
||||||
for (String key : query.keySet()) {
|
for (String key : query.keySet()) {
|
||||||
|
|
||||||
String newKey = key;
|
String newKey = key;
|
||||||
Object value = query.get(key);
|
Object value = query.get(key);
|
||||||
|
|
||||||
if (isIdKey(key, entity)) {
|
if (isIdKey(key, entity)) {
|
||||||
if (value instanceof DBObject) {
|
if (value instanceof DBObject) {
|
||||||
DBObject valueDbo = (DBObject) value;
|
DBObject valueDbo = (DBObject) value;
|
||||||
@@ -80,35 +86,52 @@ public class QueryMapper {
|
|||||||
ids.add(convertId(id));
|
ids.add(convertId(id));
|
||||||
}
|
}
|
||||||
valueDbo.put(inKey, ids.toArray(new Object[ids.size()]));
|
valueDbo.put(inKey, ids.toArray(new Object[ids.size()]));
|
||||||
|
} else if (valueDbo.containsField("$ne")) {
|
||||||
|
valueDbo.put("$ne", convertId(valueDbo.get("$ne")));
|
||||||
} else {
|
} else {
|
||||||
value = getMappedObject((DBObject) value, entity);
|
value = getMappedObject((DBObject) value, null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
value = convertId(value);
|
value = convertId(value);
|
||||||
}
|
}
|
||||||
newKey = "_id";
|
newKey = "_id";
|
||||||
} else if (key.startsWith("$") && key.endsWith("or")) {
|
} else if (key.matches(N_OR_PATTERN)) {
|
||||||
// $or/$nor
|
// $or/$nor
|
||||||
BasicBSONList conditions = (BasicBSONList) value;
|
Iterable<?> conditions = (Iterable<?>) value;
|
||||||
BasicBSONList newConditions = new BasicBSONList();
|
BasicBSONList newConditions = new BasicBSONList();
|
||||||
Iterator<Object> iter = conditions.iterator();
|
Iterator<?> iter = conditions.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
newConditions.add(getMappedObject((DBObject) iter.next(), entity));
|
newConditions.add(getMappedObject((DBObject) iter.next(), entity));
|
||||||
}
|
}
|
||||||
value = newConditions;
|
value = newConditions;
|
||||||
} else if (key.equals("$ne")) {
|
|
||||||
value = convertId(value);
|
|
||||||
} else if (value instanceof DBObject) {
|
|
||||||
newDbo.put(newKey, getMappedObject((DBObject) value, entity));
|
|
||||||
return newDbo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newDbo.put(newKey, converter.convertToMongoType(value));
|
newDbo.put(newKey, convertSimpleOrDBObject(value, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
return newDbo;
|
return newDbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retriggers mapping if the given source is a {@link DBObject} or simply invokes the
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* @param entity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Object convertSimpleOrDBObject(Object source, MongoPersistentEntity<?> entity) {
|
||||||
|
|
||||||
|
if (source instanceof BasicDBList) {
|
||||||
|
return converter.convertToMongoType(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source instanceof DBObject) {
|
||||||
|
return getMappedObject((DBObject) source, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return converter.convertToMongoType(source);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the given key will be considered an id key.
|
* Returns whether the given key will be considered an id key.
|
||||||
*
|
*
|
||||||
@@ -118,12 +141,16 @@ public class QueryMapper {
|
|||||||
*/
|
*/
|
||||||
private boolean isIdKey(String key, MongoPersistentEntity<?> entity) {
|
private boolean isIdKey(String key, MongoPersistentEntity<?> entity) {
|
||||||
|
|
||||||
if (null != entity && entity.getIdProperty() != null) {
|
if (entity == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.getIdProperty() != null) {
|
||||||
MongoPersistentProperty idProperty = entity.getIdProperty();
|
MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||||
return idProperty.getName().equals(key) || idProperty.getFieldName().equals(key);
|
return idProperty.getName().equals(key) || idProperty.getFieldName().equals(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Arrays.asList("id", "_id").contains(key);
|
return DEFAULT_ID_NAMES.contains(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ package org.springframework.data.mongodb.core;
|
|||||||
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.data.authentication.UserCredentials;
|
import org.springframework.data.authentication.UserCredentials;
|
||||||
@@ -39,12 +37,10 @@ import com.mongodb.WriteConcern;
|
|||||||
*/
|
*/
|
||||||
public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||||
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
|
||||||
|
|
||||||
private final Mongo mongo;
|
private final Mongo mongo;
|
||||||
private final String databaseName;
|
private final String databaseName;
|
||||||
private String username;
|
private final boolean mongoInstanceCreated;
|
||||||
private String password;
|
private final UserCredentials credentials;
|
||||||
private WriteConcern writeConcern;
|
private WriteConcern writeConcern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,11 +50,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
|||||||
* @param databaseName database name, not be {@literal null}.
|
* @param databaseName database name, not be {@literal null}.
|
||||||
*/
|
*/
|
||||||
public SimpleMongoDbFactory(Mongo mongo, String databaseName) {
|
public SimpleMongoDbFactory(Mongo mongo, String databaseName) {
|
||||||
Assert.notNull(mongo, "Mongo must not be null");
|
this(mongo, databaseName, new UserCredentials(), false);
|
||||||
Assert.hasText(databaseName, "Database name must not be empty");
|
|
||||||
Assert.isTrue(databaseName.matches("[\\w-]+"), "Database name must only contain letters, numbers, underscores and dashes!");
|
|
||||||
this.mongo = mongo;
|
|
||||||
this.databaseName = databaseName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,14 +58,12 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
|||||||
*
|
*
|
||||||
* @param mongo Mongo instance, must not be {@literal null}.
|
* @param mongo Mongo instance, must not be {@literal null}.
|
||||||
* @param databaseName Database name, must not be {@literal null}.
|
* @param databaseName Database name, must not be {@literal null}.
|
||||||
* @param userCredentials username and password must not be {@literal null}.
|
* @param credentials username and password.
|
||||||
*/
|
*/
|
||||||
public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials userCredentials) {
|
public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials) {
|
||||||
this(mongo, databaseName);
|
this(mongo, databaseName, credentials, false);
|
||||||
this.username = userCredentials.getUsername();
|
|
||||||
this.password = userCredentials.getPassword();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link SimpleMongoDbFactory} instance from the given {@link MongoURI}.
|
* Creates a new {@link SimpleMongoDbFactory} instance from the given {@link MongoURI}.
|
||||||
*
|
*
|
||||||
@@ -82,8 +72,22 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
|||||||
* @throws UnknownHostException
|
* @throws UnknownHostException
|
||||||
* @see MongoURI
|
* @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())));
|
this(new Mongo(uri), uri.getDatabase(), new UserCredentials(uri.getUsername(), parseChars(uri.getPassword())), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials,
|
||||||
|
boolean mongoInstanceCreated) {
|
||||||
|
|
||||||
|
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!");
|
||||||
|
|
||||||
|
this.mongo = mongo;
|
||||||
|
this.databaseName = databaseName;
|
||||||
|
this.mongoInstanceCreated = mongoInstanceCreated;
|
||||||
|
this.credentials = credentials == null ? new UserCredentials() : credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,10 +98,6 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
|||||||
public void setWriteConcern(WriteConcern writeConcern) {
|
public void setWriteConcern(WriteConcern writeConcern) {
|
||||||
this.writeConcern = writeConcern;
|
this.writeConcern = writeConcern;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WriteConcern getWriteConcern() {
|
|
||||||
return writeConcern;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
@@ -115,6 +115,9 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
|||||||
|
|
||||||
Assert.hasText(dbName, "Database name must not be empty.");
|
Assert.hasText(dbName, "Database name must not be empty.");
|
||||||
|
|
||||||
|
String username = credentials.getUsername();
|
||||||
|
String password = credentials.getPassword();
|
||||||
|
|
||||||
DB db = MongoDbUtils.getDB(mongo, dbName, username, password == null ? null : password.toCharArray());
|
DB db = MongoDbUtils.getDB(mongo, dbName, username, password == null ? null : password.toCharArray());
|
||||||
|
|
||||||
if (writeConcern != null) {
|
if (writeConcern != null) {
|
||||||
@@ -125,17 +128,17 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clean up the Mongo instance.
|
* Clean up the Mongo instance if it was created by the factory itself.
|
||||||
|
*
|
||||||
|
* @see DisposableBean#destroy()
|
||||||
*/
|
*/
|
||||||
public void destroy() throws Exception {
|
public void destroy() throws Exception {
|
||||||
mongo.close();
|
if (mongoInstanceCreated) {
|
||||||
}
|
mongo.close();
|
||||||
|
|
||||||
public static String parseChars(char[] chars) {
|
|
||||||
if (chars == null) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return String.valueOf(chars);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String parseChars(char[] chars) {
|
||||||
|
return chars == null ? null : String.valueOf(chars);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,14 +24,16 @@ import com.mongodb.WriteConcern;
|
|||||||
* Return the passed in default WriteConcern (a property on MongoAction) if no determination can be made.
|
* Return the passed in default WriteConcern (a property on MongoAction) if no determination can be made.
|
||||||
*
|
*
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface WriteConcernResolver {
|
public interface WriteConcernResolver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the WriteConcern given the MongoAction
|
* 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
|
* @param action describes the context of the Mongo action. Contains a default WriteConcern to use if one should not
|
||||||
*/
|
* be resolved.
|
||||||
WriteConcern resolve(MongoAction action);
|
* @return a WriteConcern based on the passed in MongoAction value, maybe null
|
||||||
|
*/
|
||||||
|
WriteConcern resolve(MongoAction action);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalT
|
|||||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToStringConverter;
|
import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToStringConverter;
|
||||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
|
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.StringToBigIntegerConverter;
|
||||||
|
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToURLConverter;
|
||||||
|
import org.springframework.data.mongodb.core.convert.MongoConverters.URLToStringConverter;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
|
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
@@ -89,6 +91,8 @@ public class CustomConversions {
|
|||||||
this.converters.add(StringToBigDecimalConverter.INSTANCE);
|
this.converters.add(StringToBigDecimalConverter.INSTANCE);
|
||||||
this.converters.add(BigIntegerToStringConverter.INSTANCE);
|
this.converters.add(BigIntegerToStringConverter.INSTANCE);
|
||||||
this.converters.add(StringToBigIntegerConverter.INSTANCE);
|
this.converters.add(StringToBigIntegerConverter.INSTANCE);
|
||||||
|
this.converters.add(URLToStringConverter.INSTANCE);
|
||||||
|
this.converters.add(StringToURLConverter.INSTANCE);
|
||||||
this.converters.addAll(converters);
|
this.converters.addAll(converters);
|
||||||
|
|
||||||
for (Object c : this.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() {
|
public DefaultMongoTypeMapper() {
|
||||||
this(DEFAULT_TYPE_KEY, Arrays.asList(SimpleTypeInformationMapper.INSTANCE));
|
this(DEFAULT_TYPE_KEY, Arrays.asList(SimpleTypeInformationMapper.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
public DefaultMongoTypeMapper(String typeKey) {
|
public DefaultMongoTypeMapper(String typeKey) {
|
||||||
super(new DBObjectTypeAliasAccessor(typeKey));
|
super(new DBObjectTypeAliasAccessor(typeKey));
|
||||||
this.typeKey = 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));
|
super(new DBObjectTypeAliasAccessor(typeKey), mappingContext, Arrays.asList(SimpleTypeInformationMapper.INSTANCE));
|
||||||
this.typeKey = typeKey;
|
this.typeKey = typeKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DefaultMongoTypeMapper(String typeKey, List<? extends TypeInformationMapper> mappers) {
|
public DefaultMongoTypeMapper(String typeKey, List<? extends TypeInformationMapper> mappers) {
|
||||||
super(new DBObjectTypeAliasAccessor(typeKey), mappers);
|
super(new DBObjectTypeAliasAccessor(typeKey), mappers);
|
||||||
this.typeKey = typeKey;
|
this.typeKey = typeKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.mongodb.core.convert.MongoTypeMapper#isTypeKey(java.lang.String)
|
* @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);
|
return typeKey == null ? false : typeKey.equals(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.convert.DefaultTypeMapper#getFallbackTypeFor(java.lang.Object)
|
* @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) {
|
protected TypeInformation<?> getFallbackTypeFor(DBObject source) {
|
||||||
return source instanceof BasicDBList ? LIST_TYPE_INFO : MAP_TYPE_INFO;
|
return source instanceof BasicDBList ? LIST_TYPE_INFO : MAP_TYPE_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public static final class DBObjectTypeAliasAccessor implements TypeAliasAccessor<DBObject> {
|
public static final class DBObjectTypeAliasAccessor implements TypeAliasAccessor<DBObject> {
|
||||||
|
|
||||||
private final String typeKey;
|
private final String typeKey;
|
||||||
|
|
||||||
public DBObjectTypeAliasAccessor(String typeKey) {
|
public DBObjectTypeAliasAccessor(String typeKey) {
|
||||||
this.typeKey = typeKey;
|
this.typeKey = typeKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.convert.TypeAliasAccessor#readAliasFrom(java.lang.Object)
|
* @see org.springframework.data.convert.TypeAliasAccessor#readAliasFrom(java.lang.Object)
|
||||||
*/
|
*/
|
||||||
public Object readAliasFrom(DBObject source) {
|
public Object readAliasFrom(DBObject source) {
|
||||||
|
|
||||||
if (source instanceof BasicDBList) {
|
if (source instanceof BasicDBList) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return source.get(typeKey);
|
return source.get(typeKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* 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.annotation.PersistenceConstructor;
|
||||||
|
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.mapping.model.MappingException;
|
||||||
|
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 static final String REJECT_CONSTRUCTOR = String.format("Entity doesn't have a usable constructor, either "
|
||||||
|
+ "provide a custom converter or annotate a constructor with @%s!", PersistenceConstructor.class.getSimpleName());
|
||||||
|
|
||||||
|
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}.
|
||||||
|
* @throws MappingException in case the {@link MongoPersistentEntity} handed in does not have a
|
||||||
|
* {@link PreferredConstructor}.
|
||||||
|
*/
|
||||||
|
public MappedConstructor(MongoPersistentEntity<?> entity,
|
||||||
|
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) throws MappingException {
|
||||||
|
|
||||||
|
Assert.notNull(entity);
|
||||||
|
Assert.notNull(context);
|
||||||
|
|
||||||
|
if (entity.getPreferredConstructor() == null) {
|
||||||
|
throw new MappingException(REJECT_CONSTRUCTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
* @throws MappingException in case no {@link MappedParameter} can be found for the given {@link Parameter}.
|
||||||
|
*/
|
||||||
|
public MappedParameter getFor(Parameter<?> parameter) {
|
||||||
|
|
||||||
|
for (MappedParameter mappedParameter : parameters) {
|
||||||
|
if (mappedParameter.parameter.equals(parameter)) {
|
||||||
|
return mappedParameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new MappingException(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.convert.TypeMapper;
|
||||||
import org.springframework.data.mapping.Association;
|
import org.springframework.data.mapping.Association;
|
||||||
import org.springframework.data.mapping.AssociationHandler;
|
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.PropertyHandler;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.data.mapping.model.BeanWrapper;
|
import org.springframework.data.mapping.model.BeanWrapper;
|
||||||
@@ -81,6 +81,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
protected ApplicationContext applicationContext;
|
protected ApplicationContext applicationContext;
|
||||||
protected boolean useFieldAccessOnly = true;
|
protected boolean useFieldAccessOnly = true;
|
||||||
protected MongoTypeMapper typeMapper;
|
protected MongoTypeMapper typeMapper;
|
||||||
|
protected String mapKeyDotReplacement = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link MappingMongoConverter} given the new {@link MongoDbFactory} and {@link MappingContext}.
|
* 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;
|
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)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.convert.EntityConverter#getMappingContext()
|
* @see org.springframework.data.convert.EntityConverter#getMappingContext()
|
||||||
@@ -164,7 +177,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
if (conversions.hasCustomReadTarget(dbo.getClass(), rawType)) {
|
if (conversions.hasCustomReadTarget(dbo.getClass(), rawType)) {
|
||||||
return conversionService.convert(dbo, rawType);
|
return conversionService.convert(dbo, rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DBObject.class.isAssignableFrom(rawType)) {
|
if (DBObject.class.isAssignableFrom(rawType)) {
|
||||||
return (S) dbo;
|
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) {
|
private <S extends Object> S read(final MongoPersistentEntity<S> entity, final DBObject dbo) {
|
||||||
|
|
||||||
final StandardEvaluationContext spelCtx = new StandardEvaluationContext();
|
final StandardEvaluationContext spelCtx = new StandardEvaluationContext(dbo);
|
||||||
if (null != applicationContext) {
|
spelCtx.addPropertyAccessor(DBObjectPropertyAccessor.INSTANCE);
|
||||||
|
|
||||||
|
if (applicationContext != null) {
|
||||||
spelCtx.setBeanResolver(new BeanFactoryResolver(applicationContext));
|
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 MappedConstructor constructor = new MappedConstructor(entity, mappingContext);
|
||||||
final MongoPersistentProperty idProperty = entity.getIdProperty();
|
|
||||||
|
|
||||||
ParameterValueProvider provider = new SpELAwareParameterValueProvider(spelExpressionParser, spelCtx) {
|
SpELAwareParameterValueProvider delegate = new SpELAwareParameterValueProvider(spelExpressionParser, spelCtx);
|
||||||
@Override
|
ParameterValueProvider provider = new DelegatingParameterValueProvider(constructor, dbo, delegate);
|
||||||
@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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
final BeanWrapper<MongoPersistentEntity<S>, S> wrapper = BeanWrapper.create(entity, provider, conversionService);
|
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>() {
|
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||||
public void doWithPersistentProperty(MongoPersistentProperty prop) {
|
public void doWithPersistentProperty(MongoPersistentProperty prop) {
|
||||||
|
|
||||||
boolean isConstructorProperty = ctorParamNames.contains(prop.getName());
|
boolean isConstructorProperty = constructor.isConstructorParameter(prop);
|
||||||
boolean hasValueForProperty = dbo.containsField(prop.getFieldName());
|
boolean hasValueForProperty = dbo.containsField(prop.getFieldName());
|
||||||
|
|
||||||
if (!hasValueForProperty || isConstructorProperty) {
|
if (!hasValueForProperty || isConstructorProperty) {
|
||||||
@@ -286,7 +264,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
|
|
||||||
boolean handledByCustomConverter = conversions.getCustomWriteTarget(obj.getClass(), DBObject.class) != null;
|
boolean handledByCustomConverter = conversions.getCustomWriteTarget(obj.getClass(), DBObject.class) != null;
|
||||||
TypeInformation<? extends Object> type = ClassTypeInformation.from(obj.getClass());
|
TypeInformation<? extends Object> type = ClassTypeInformation.from(obj.getClass());
|
||||||
|
|
||||||
if (!handledByCustomConverter && !(dbo instanceof BasicDBList)) {
|
if (!handledByCustomConverter && !(dbo instanceof BasicDBList)) {
|
||||||
typeMapper.writeType(type, dbo);
|
typeMapper.writeType(type, dbo);
|
||||||
}
|
}
|
||||||
@@ -345,7 +323,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
// Write the ID
|
// Write the ID
|
||||||
final MongoPersistentProperty idProperty = entity.getIdProperty();
|
final MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||||
if (!dbo.containsField("_id") && null != idProperty) {
|
if (!dbo.containsField("_id") && null != idProperty) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Object id = wrapper.getProperty(idProperty, Object.class, useFieldAccessOnly);
|
Object id = wrapper.getProperty(idProperty, Object.class, useFieldAccessOnly);
|
||||||
dbo.put("_id", idMapper.convertId(id));
|
dbo.put("_id", idMapper.convertId(id));
|
||||||
@@ -356,13 +334,13 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
// Write the properties
|
// Write the properties
|
||||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||||
public void doWithPersistentProperty(MongoPersistentProperty prop) {
|
public void doWithPersistentProperty(MongoPersistentProperty prop) {
|
||||||
|
|
||||||
if (prop.equals(idProperty)) {
|
if (prop.equals(idProperty)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
Object propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
||||||
|
|
||||||
if (null != propertyObj) {
|
if (null != propertyObj) {
|
||||||
if (!conversions.isSimpleType(propertyObj.getClass())) {
|
if (!conversions.isSimpleType(propertyObj.getClass())) {
|
||||||
writePropertyInternal(propertyObj, dbo, prop);
|
writePropertyInternal(propertyObj, dbo, prop);
|
||||||
@@ -461,7 +439,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
*
|
*
|
||||||
* @param collection must not be {@literal null}.
|
* @param collection must not be {@literal null}.
|
||||||
* @param property must not be {@literal null}.
|
* @param property must not be {@literal null}.
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected DBObject createCollection(Collection<?> collection, MongoPersistentProperty property) {
|
protected DBObject createCollection(Collection<?> collection, MongoPersistentProperty property) {
|
||||||
@@ -499,13 +476,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
|
|
||||||
for (Object element : source) {
|
for (Object element : source) {
|
||||||
|
|
||||||
if (element == null) {
|
Class<?> elementType = element == null ? null : element.getClass();
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Class<?> elementType = element.getClass();
|
if (elementType == null || conversions.isSimpleType(elementType)) {
|
||||||
|
|
||||||
if (conversions.isSimpleType(elementType)) {
|
|
||||||
sink.add(getPotentiallyConvertedSimpleWrite(element));
|
sink.add(getPotentiallyConvertedSimpleWrite(element));
|
||||||
} else if (element instanceof Collection || elementType.isArray()) {
|
} else if (element instanceof Collection || elementType.isArray()) {
|
||||||
sink.add(writeCollectionInternal(asCollection(element), componentType, new BasicDBList()));
|
sink.add(writeCollectionInternal(asCollection(element), componentType, new BasicDBList()));
|
||||||
@@ -528,14 +501,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected DBObject writeMapInternal(Map<Object, Object> obj, DBObject dbo, TypeInformation<?> propertyType) {
|
protected DBObject writeMapInternal(Map<Object, Object> obj, DBObject dbo, TypeInformation<?> propertyType) {
|
||||||
|
|
||||||
for (Map.Entry<Object, Object> entry : obj.entrySet()) {
|
for (Map.Entry<Object, Object> entry : obj.entrySet()) {
|
||||||
Object key = entry.getKey();
|
Object key = entry.getKey();
|
||||||
Object val = entry.getValue();
|
Object val = entry.getValue();
|
||||||
if (conversions.isSimpleType(key.getClass())) {
|
if (conversions.isSimpleType(key.getClass())) {
|
||||||
// Don't use conversion service here as removal of ObjectToString converter results in some primitive types not
|
// Don't use conversion service here as removal of ObjectToString converter results in some primitive types not
|
||||||
// being convertable
|
// being convertable
|
||||||
String simpleKey = key.toString();
|
String simpleKey = potentiallyEscapeMapKey(key.toString());
|
||||||
if (val == null || conversions.isSimpleType(val.getClass())) {
|
if (val == null || conversions.isSimpleType(val.getClass())) {
|
||||||
writeSimpleInternal(val, dbo, simpleKey);
|
writeSimpleInternal(val, dbo, simpleKey);
|
||||||
} else if (val instanceof Collection || val.getClass().isArray()) {
|
} else if (val instanceof Collection || val.getClass().isArray()) {
|
||||||
@@ -543,7 +516,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
writeCollectionInternal(asCollection(val), propertyType.getMapValueType(), new BasicDBList()));
|
writeCollectionInternal(asCollection(val), propertyType.getMapValueType(), new BasicDBList()));
|
||||||
} else {
|
} else {
|
||||||
DBObject newDbo = new BasicDBObject();
|
DBObject newDbo = new BasicDBObject();
|
||||||
TypeInformation<?> valueTypeInfo = propertyType.isMap() ? propertyType.getMapValueType() : ClassTypeInformation.OBJECT;
|
TypeInformation<?> valueTypeInfo = propertyType.isMap() ? propertyType.getMapValueType()
|
||||||
|
: ClassTypeInformation.OBJECT;
|
||||||
writeInternal(val, newDbo, valueTypeInfo);
|
writeInternal(val, newDbo, valueTypeInfo);
|
||||||
dbo.put(simpleKey, newDbo);
|
dbo.put(simpleKey, newDbo);
|
||||||
}
|
}
|
||||||
@@ -551,10 +525,43 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
throw new MappingException("Cannot use a complex object as a key value.");
|
throw new MappingException("Cannot use a complex object as a key value.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dbo;
|
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
|
* 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.
|
* the one given. This is usually the case if you store a subtype of the actual declared type of the property.
|
||||||
@@ -643,7 +650,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
MongoPersistentProperty idProperty = targetEntity.getIdProperty();
|
MongoPersistentProperty idProperty = targetEntity.getIdProperty();
|
||||||
BeanWrapper<MongoPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(target, conversionService);
|
BeanWrapper<MongoPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(target, conversionService);
|
||||||
Object id = wrapper.getProperty(idProperty, Object.class, useFieldAccessOnly);
|
Object id = wrapper.getProperty(idProperty, Object.class, useFieldAccessOnly);
|
||||||
|
|
||||||
if (null == id) {
|
if (null == id) {
|
||||||
throw new MappingException("Cannot create a reference to an object with a NULL id.");
|
throw new MappingException("Cannot create a reference to an object with a NULL id.");
|
||||||
}
|
}
|
||||||
@@ -696,7 +703,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
(BasicDBList) sourceValue);
|
(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
|
// It's a complex object, have to read it in
|
||||||
if (toType != null) {
|
if (toType != null) {
|
||||||
@@ -721,12 +728,15 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
* @return the converted {@link Collections}, will never be {@literal null}.
|
* @return the converted {@link Collections}, will never be {@literal null}.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Collection<?> readCollectionOrArray(TypeInformation<?> targetType, BasicDBList sourceValue) {
|
private Object readCollectionOrArray(TypeInformation<?> targetType, BasicDBList sourceValue) {
|
||||||
|
|
||||||
Assert.notNull(targetType);
|
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
|
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++) {
|
for (int i = 0; i < sourceValue.size(); i++) {
|
||||||
Object dbObjItem = sourceValue.get(i);
|
Object dbObjItem = sourceValue.get(i);
|
||||||
@@ -735,11 +745,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
} else if (dbObjItem instanceof DBObject) {
|
} else if (dbObjItem instanceof DBObject) {
|
||||||
items.add(read(targetType.getComponentType(), (DBObject) dbObjItem));
|
items.add(read(targetType.getComponentType(), (DBObject) dbObjItem));
|
||||||
} else {
|
} else {
|
||||||
items.add(getPotentiallyConvertedSimpleRead(dbObjItem, targetType.getComponentType().getType()));
|
TypeInformation<?> componentType = targetType.getComponentType();
|
||||||
|
items.add(getPotentiallyConvertedSimpleRead(dbObjItem, componentType == null ? null : componentType.getType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return items;
|
return getPotentiallyConvertedSimpleRead(items, targetType.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -763,12 +774,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object key = entry.getKey();
|
Object key = potentiallyUnescapeMapKey(entry.getKey());
|
||||||
|
|
||||||
TypeInformation<?> keyTypeInformation = type.getComponentType();
|
TypeInformation<?> keyTypeInformation = type.getComponentType();
|
||||||
if (keyTypeInformation != null) {
|
if (keyTypeInformation != null) {
|
||||||
Class<?> keyType = keyTypeInformation.getType();
|
Class<?> keyType = keyTypeInformation.getType();
|
||||||
key = conversionService.convert(entry.getKey(), keyType);
|
key = conversionService.convert(key, keyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object value = entry.getValue();
|
Object value = entry.getValue();
|
||||||
@@ -807,7 +818,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<?> target = conversions.getCustomWriteTarget(getClass());
|
Class<?> target = conversions.getCustomWriteTarget(obj.getClass());
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
return conversionService.convert(obj, target);
|
return conversionService.convert(obj, target);
|
||||||
}
|
}
|
||||||
@@ -838,14 +849,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof List) {
|
|
||||||
return maybeConvertList((List<?>) obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obj.getClass().isArray()) {
|
if (obj.getClass().isArray()) {
|
||||||
return maybeConvertList(Arrays.asList((Object[]) obj));
|
return maybeConvertList(Arrays.asList((Object[]) obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (obj instanceof Collection) {
|
||||||
|
return maybeConvertList((Collection<?>) obj);
|
||||||
|
}
|
||||||
|
|
||||||
DBObject newDbo = new BasicDBObject();
|
DBObject newDbo = new BasicDBObject();
|
||||||
this.write(obj, newDbo);
|
this.write(obj, newDbo);
|
||||||
return removeTypeInfoRecursively(newDbo);
|
return removeTypeInfoRecursively(newDbo);
|
||||||
@@ -858,7 +869,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
}
|
}
|
||||||
return newDbl;
|
return newDbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the type information from the conversion result.
|
* Removes the type information from the conversion result.
|
||||||
*
|
*
|
||||||
@@ -895,4 +906,55 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
|||||||
|
|
||||||
return dbObject;
|
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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,8 +17,12 @@ package org.springframework.data.mongodb.core.convert;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
|
import org.springframework.core.convert.ConversionFailedException;
|
||||||
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
@@ -119,4 +123,28 @@ abstract class MongoConverters {
|
|||||||
return StringUtils.hasText(source) ? new BigInteger(source) : null;
|
return StringUtils.hasText(source) ? new BigInteger(source) : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static enum URLToStringConverter implements Converter<URL, String> {
|
||||||
|
INSTANCE;
|
||||||
|
|
||||||
|
public String convert(URL source) {
|
||||||
|
return source == null ? null : source.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum StringToURLConverter implements Converter<String, URL> {
|
||||||
|
INSTANCE;
|
||||||
|
|
||||||
|
private static final TypeDescriptor SOURCE = TypeDescriptor.valueOf(String.class);
|
||||||
|
private static final TypeDescriptor TARGET = TypeDescriptor.valueOf(URL.class);
|
||||||
|
|
||||||
|
public URL convert(String source) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
return source == null ? null : new URL(source);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new ConversionFailedException(SOURCE, TARGET, source, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class Box implements Shape {
|
|||||||
list.add(getUpperRight().asList());
|
list.add(getUpperRight().asList());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
||||||
@@ -74,7 +74,7 @@ public class Box implements Shape {
|
|||||||
public String getCommand() {
|
public String getCommand() {
|
||||||
return "$box";
|
return "$box";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("Box [%s, %s]", first, second);
|
return String.format("Box [%s, %s]", first, second);
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ public class Circle implements Shape {
|
|||||||
*/
|
*/
|
||||||
@PersistenceConstructor
|
@PersistenceConstructor
|
||||||
public Circle(Point center, double radius) {
|
public Circle(Point center, double radius) {
|
||||||
|
|
||||||
Assert.notNull(center);
|
Assert.notNull(center);
|
||||||
Assert.isTrue(radius >= 0, "Radius must not be negative!");
|
Assert.isTrue(radius >= 0, "Radius must not be negative!");
|
||||||
|
|
||||||
this.center = center;
|
this.center = center;
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ public class Circle implements Shape {
|
|||||||
public double getRadius() {
|
public double getRadius() {
|
||||||
return radius;
|
return radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.mongodb.core.geo.Shape#asList()
|
* @see org.springframework.data.mongodb.core.geo.Shape#asList()
|
||||||
@@ -87,7 +87,7 @@ public class Circle implements Shape {
|
|||||||
result.add(getRadius());
|
result.add(getRadius());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
||||||
@@ -104,26 +104,26 @@ public class Circle implements Shape {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("Circle [center=%s, radius=%f]", center, radius);
|
return String.format("Circle [center=%s, radius=%f]", center, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#equals(java.lang.Object)
|
* @see java.lang.Object#equals(java.lang.Object)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
|
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Circle that = (Circle) obj;
|
Circle that = (Circle) obj;
|
||||||
|
|
||||||
return this.center.equals(that.center) && this.radius == that.radius;
|
return this.center.equals(that.center) && this.radius == that.radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see java.lang.Object#hashCode()
|
* @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(x, y, z));
|
||||||
this.points.addAll(Arrays.asList(others));
|
this.points.addAll(Arrays.asList(others));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.mongodb.core.geo.Shape#asList()
|
* @see org.springframework.data.mongodb.core.geo.Shape#asList()
|
||||||
*/
|
*/
|
||||||
public List<List<Double>> asList() {
|
public List<List<Double>> asList() {
|
||||||
|
|
||||||
List<List<Double>> result = new ArrayList<List<Double>>();
|
List<List<Double>> result = new ArrayList<List<Double>>();
|
||||||
|
|
||||||
for (Point point : points) {
|
for (Point point : points) {
|
||||||
result.add(point.asList());
|
result.add(point.asList());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
||||||
@@ -73,7 +73,7 @@ public class Polygon implements Shape, Iterable<Point> {
|
|||||||
public String getCommand() {
|
public String getCommand() {
|
||||||
return "$polygon";
|
return "$polygon";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see java.lang.Iterable#iterator()
|
* @see java.lang.Iterable#iterator()
|
||||||
@@ -88,20 +88,20 @@ public class Polygon implements Shape, Iterable<Point> {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
|
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygon that = (Polygon) obj;
|
Polygon that = (Polygon) obj;
|
||||||
|
|
||||||
return this.points.equals(that.points);
|
return this.points.equals(that.points);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see java.lang.Object#hashCode()
|
* @see java.lang.Object#hashCode()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Common interface for all shapes. Allows building MongoDB representations of them.
|
* Common interface for all shapes. Allows building MongoDB representations of them.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public interface Shape {
|
public interface Shape {
|
||||||
@@ -31,7 +31,7 @@ public interface Shape {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<? extends Object> asList();
|
List<? extends Object> asList();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the command to be used to create the {@literal $within} criterion.
|
* Returns the command to be used to create the {@literal $within} criterion.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 by the original author(s).
|
* Copyright 2011-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
@@ -13,9 +13,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.data.mongodb.core.index;
|
package org.springframework.data.mongodb.core.index;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@@ -24,14 +24,29 @@ import java.lang.annotation.Target;
|
|||||||
/**
|
/**
|
||||||
* Mark a class to use compound indexes.
|
* Mark a class to use compound indexes.
|
||||||
*
|
*
|
||||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
* @author Jon Brisbin
|
||||||
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
@Target({ ElementType.TYPE })
|
@Target({ ElementType.TYPE })
|
||||||
|
@Documented
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface CompoundIndex {
|
public @interface CompoundIndex {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual index definition in JSON format. The keys of the JSON document are the fields to be indexed, the values
|
||||||
|
* define the index direction (1 for ascending, -1 for descending).
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
String def();
|
String def();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It does not actually make sense to use that attribute as the direction has to be defined in the {@link #def()}
|
||||||
|
* attribute actually.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
IndexDirection direction() default IndexDirection.ASCENDING;
|
IndexDirection direction() default IndexDirection.ASCENDING;
|
||||||
|
|
||||||
boolean unique() default false;
|
boolean unique() default false;
|
||||||
@@ -40,8 +55,18 @@ public @interface CompoundIndex {
|
|||||||
|
|
||||||
boolean dropDups() default false;
|
boolean dropDups() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the index to be created.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
String name() default "";
|
String name() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The collection the index will be created in. Will default to the collection the annotated domain class will be
|
||||||
|
* stored in.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
String collection() default "";
|
String collection() default "";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* 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.index;
|
||||||
|
|
||||||
|
import org.springframework.data.mongodb.core.query.Order;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value object for an index field.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public final class IndexField {
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
private final Order order;
|
||||||
|
private final boolean isGeo;
|
||||||
|
|
||||||
|
private IndexField(String key, Order order, boolean isGeo) {
|
||||||
|
|
||||||
|
Assert.hasText(key);
|
||||||
|
Assert.isTrue(order != null ^ isGeo);
|
||||||
|
|
||||||
|
this.key = key;
|
||||||
|
this.order = order;
|
||||||
|
this.isGeo = isGeo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a default {@link IndexField} with the given key and {@link Order}.
|
||||||
|
*
|
||||||
|
* @param key must not be {@literal null} or emtpy.
|
||||||
|
* @param order must not be {@literal null}.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static IndexField create(String key, Order order) {
|
||||||
|
Assert.notNull(order);
|
||||||
|
return new IndexField(key, order, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a geo {@link IndexField} for the given key.
|
||||||
|
*
|
||||||
|
* @param key must not be {@literal null} or empty.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static IndexField geo(String key) {
|
||||||
|
return new IndexField(key, null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the key
|
||||||
|
*/
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the order of the {@link IndexField} or {@literal null} in case we have a geo index field.
|
||||||
|
*
|
||||||
|
* @return the order
|
||||||
|
*/
|
||||||
|
public Order getOrder() {
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the {@link IndexField} is a geo index field.
|
||||||
|
*
|
||||||
|
* @return the isGeo
|
||||||
|
*/
|
||||||
|
public boolean isGeo() {
|
||||||
|
return isGeo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#equals(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(obj instanceof IndexField)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexField that = (IndexField) obj;
|
||||||
|
|
||||||
|
return this.key.equals(that.key) && ObjectUtils.nullSafeEquals(this.order, that.order) && this.isGeo == that.isGeo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#hashCode()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
|
||||||
|
int result = 17;
|
||||||
|
result += 31 * ObjectUtils.nullSafeHashCode(key);
|
||||||
|
result += 31 * ObjectUtils.nullSafeHashCode(order);
|
||||||
|
result += 31 * ObjectUtils.nullSafeHashCode(isGeo);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("IndexField [ key: %s, order: %s, isGeo: %s]", key, order, isGeo);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,36 +15,52 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core.index;
|
package org.springframework.data.mongodb.core.index;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.query.Order;
|
import org.springframework.data.mongodb.core.query.Order;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
public class IndexInfo {
|
public class IndexInfo {
|
||||||
|
|
||||||
private final Map<String, Order> fieldSpec;
|
private final Map<String, Order> fieldSpec;
|
||||||
|
private final List<IndexField> indexFields;
|
||||||
|
|
||||||
private String name;
|
private final String name;
|
||||||
|
private final boolean unique;
|
||||||
|
private final boolean dropDuplicates;
|
||||||
|
private final boolean sparse;
|
||||||
|
|
||||||
private boolean unique = false;
|
public IndexInfo(Map<String, Order> fieldSpec, List<IndexField> indexFields, String name, boolean unique,
|
||||||
|
boolean dropDuplicates, boolean sparse) {
|
||||||
|
|
||||||
private boolean dropDuplicates = false;
|
|
||||||
|
|
||||||
private boolean sparse = false;
|
|
||||||
|
|
||||||
|
|
||||||
public IndexInfo(Map<String, Order> fieldSpec, String name, boolean unique, boolean dropDuplicates, boolean sparse) {
|
|
||||||
super();
|
|
||||||
this.fieldSpec = fieldSpec;
|
this.fieldSpec = fieldSpec;
|
||||||
|
this.indexFields = Collections.unmodifiableList(indexFields);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.unique = unique;
|
this.unique = unique;
|
||||||
this.dropDuplicates = dropDuplicates;
|
this.dropDuplicates = dropDuplicates;
|
||||||
this.sparse = sparse;
|
this.sparse = sparse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link #getIndexFields()} instead as this {@link Map} does not contain geo indexes.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public Map<String, Order> getFieldSpec() {
|
public Map<String, Order> getFieldSpec() {
|
||||||
return fieldSpec;
|
return fieldSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the individual index fields of the index.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<IndexField> getIndexFields() {
|
||||||
|
return this.indexFields;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@@ -63,7 +79,7 @@ public class IndexInfo {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "IndexInfo [fieldSpec=" + fieldSpec + ", name=" + name + ", unique=" + unique + ", dropDuplicates="
|
return "IndexInfo [indexFields=" + indexFields + ", name=" + name + ", unique=" + unique + ", dropDuplicates="
|
||||||
+ dropDuplicates + ", sparse=" + sparse + "]";
|
+ dropDuplicates + ", sparse=" + sparse + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +88,7 @@ public class IndexInfo {
|
|||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime * result + (dropDuplicates ? 1231 : 1237);
|
result = prime * result + (dropDuplicates ? 1231 : 1237);
|
||||||
result = prime * result + ((fieldSpec == null) ? 0 : fieldSpec.hashCode());
|
result = prime * result + ObjectUtils.nullSafeHashCode(indexFields);
|
||||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
result = prime * result + (sparse ? 1231 : 1237);
|
result = prime * result + (sparse ? 1231 : 1237);
|
||||||
result = prime * result + (unique ? 1231 : 1237);
|
result = prime * result + (unique ? 1231 : 1237);
|
||||||
@@ -81,35 +97,39 @@ public class IndexInfo {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj) {
|
||||||
return true;
|
return true;
|
||||||
if (obj == null)
|
}
|
||||||
|
if (obj == null) {
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
IndexInfo other = (IndexInfo) obj;
|
IndexInfo other = (IndexInfo) obj;
|
||||||
if (dropDuplicates != other.dropDuplicates)
|
if (dropDuplicates != other.dropDuplicates) {
|
||||||
return false;
|
return false;
|
||||||
if (fieldSpec == null) {
|
}
|
||||||
if (other.fieldSpec != null)
|
if (indexFields == null) {
|
||||||
|
if (other.indexFields != null) {
|
||||||
return false;
|
return false;
|
||||||
} else if (!fieldSpec.equals(other.fieldSpec))
|
}
|
||||||
|
} else if (!indexFields.equals(other.indexFields)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
if (other.name != null)
|
if (other.name != null) {
|
||||||
return false;
|
return false;
|
||||||
} else if (!name.equals(other.name))
|
}
|
||||||
|
} else if (!name.equals(other.name)) {
|
||||||
return false;
|
return false;
|
||||||
if (sparse != other.sparse)
|
}
|
||||||
|
if (sparse != other.sparse) {
|
||||||
return false;
|
return false;
|
||||||
if (unique != other.unique)
|
}
|
||||||
|
if (unique != other.unique) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
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}]
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
|||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of ApplicationEventPublisher that will only fire MappingContextEvents for use by the index creator when
|
* An implementation of ApplicationEventPublisher that will only fire MappingContextEvents for use by the index creator
|
||||||
* MongoTemplate is used 'stand-alone', that is not declared inside a Spring ApplicationContext.
|
* 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>
|
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||||
*/
|
*/
|
||||||
public class MongoMappingEventPublisher implements ApplicationEventPublisher {
|
public class MongoMappingEventPublisher implements ApplicationEventPublisher {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 by the original author(s).
|
* Copyright 2011-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.data.mongodb.core.index;
|
package org.springframework.data.mongodb.core.index;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@@ -23,10 +22,10 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.data.mapping.PersistentEntity;
|
||||||
import org.springframework.data.mapping.PropertyHandler;
|
import org.springframework.data.mapping.PropertyHandler;
|
||||||
import org.springframework.data.mapping.event.MappingContextEvent;
|
import org.springframework.data.mapping.event.MappingContextEvent;
|
||||||
import org.springframework.data.mongodb.MongoDbFactory;
|
import org.springframework.data.mongodb.MongoDbFactory;
|
||||||
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
|
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
@@ -38,10 +37,10 @@ import com.mongodb.DBObject;
|
|||||||
import com.mongodb.util.JSON;
|
import com.mongodb.util.JSON;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that inspects {@link BasicMongoPersistentEntity} instances contained in the given
|
* Component that inspects {@link MongoPersistentEntity} instances contained in the given {@link MongoMappingContext}
|
||||||
* {@link MongoMappingContext} for indexing metadata and ensures the indexes to be available.
|
* for indexing metadata and ensures the indexes to be available.
|
||||||
*
|
*
|
||||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
* @author Jon Brisbin
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class MongoPersistentEntityIndexCreator implements
|
public class MongoPersistentEntityIndexCreator implements
|
||||||
@@ -76,7 +75,13 @@ public class MongoPersistentEntityIndexCreator implements
|
|||||||
*/
|
*/
|
||||||
public void onApplicationEvent(
|
public void onApplicationEvent(
|
||||||
MappingContextEvent<MongoPersistentEntity<MongoPersistentProperty>, MongoPersistentProperty> event) {
|
MappingContextEvent<MongoPersistentEntity<MongoPersistentProperty>, MongoPersistentProperty> event) {
|
||||||
checkForIndexes(event.getPersistentEntity());
|
|
||||||
|
PersistentEntity<?, ?> entity = event.getPersistentEntity();
|
||||||
|
|
||||||
|
// Double check type as Spring infrastructure does not consider nested generics
|
||||||
|
if (entity instanceof MongoPersistentEntity) {
|
||||||
|
checkForIndexes(event.getPersistentEntity());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkForIndexes(final MongoPersistentEntity<?> entity) {
|
protected void checkForIndexes(final MongoPersistentEntity<?> entity) {
|
||||||
@@ -90,12 +95,12 @@ public class MongoPersistentEntityIndexCreator implements
|
|||||||
if (type.isAnnotationPresent(CompoundIndexes.class)) {
|
if (type.isAnnotationPresent(CompoundIndexes.class)) {
|
||||||
CompoundIndexes indexes = type.getAnnotation(CompoundIndexes.class);
|
CompoundIndexes indexes = type.getAnnotation(CompoundIndexes.class);
|
||||||
for (CompoundIndex index : indexes.value()) {
|
for (CompoundIndex index : indexes.value()) {
|
||||||
String indexColl = index.collection();
|
|
||||||
if ("".equals(indexColl)) {
|
String indexColl = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection();
|
||||||
indexColl = entity.getCollection();
|
DBObject definition = (DBObject) JSON.parse(index.def());
|
||||||
}
|
|
||||||
ensureIndex(indexColl, index.name(), index.def(), index.direction(), index.unique(), index.dropDups(),
|
ensureIndex(indexColl, index.name(), definition, index.unique(), index.dropDups(), index.sparse());
|
||||||
index.sparse());
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Created compound index " + index);
|
log.debug("Created compound index " + index);
|
||||||
}
|
}
|
||||||
@@ -104,10 +109,14 @@ public class MongoPersistentEntityIndexCreator implements
|
|||||||
|
|
||||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||||
public void doWithPersistentProperty(MongoPersistentProperty persistentProperty) {
|
public void doWithPersistentProperty(MongoPersistentProperty persistentProperty) {
|
||||||
|
|
||||||
Field field = persistentProperty.getField();
|
Field field = persistentProperty.getField();
|
||||||
|
|
||||||
if (field.isAnnotationPresent(Indexed.class)) {
|
if (field.isAnnotationPresent(Indexed.class)) {
|
||||||
|
|
||||||
Indexed index = field.getAnnotation(Indexed.class);
|
Indexed index = field.getAnnotation(Indexed.class);
|
||||||
String name = index.name();
|
String name = index.name();
|
||||||
|
|
||||||
if (!StringUtils.hasText(name)) {
|
if (!StringUtils.hasText(name)) {
|
||||||
name = persistentProperty.getFieldName();
|
name = persistentProperty.getFieldName();
|
||||||
} else {
|
} else {
|
||||||
@@ -119,11 +128,17 @@ public class MongoPersistentEntityIndexCreator implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String collection = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection();
|
String collection = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection();
|
||||||
ensureIndex(collection, name, null, index.direction(), index.unique(), index.dropDups(), index.sparse());
|
int direction = index.direction() == IndexDirection.ASCENDING ? 1 : -1;
|
||||||
|
DBObject definition = new BasicDBObject(persistentProperty.getFieldName(), direction);
|
||||||
|
|
||||||
|
ensureIndex(collection, name, definition, index.unique(), index.dropDups(), index.sparse());
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Created property index " + index);
|
log.debug("Created property index " + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (field.isAnnotationPresent(GeoSpatialIndexed.class)) {
|
} else if (field.isAnnotationPresent(GeoSpatialIndexed.class)) {
|
||||||
|
|
||||||
GeoSpatialIndexed index = field.getAnnotation(GeoSpatialIndexed.class);
|
GeoSpatialIndexed index = field.getAnnotation(GeoSpatialIndexed.class);
|
||||||
@@ -148,21 +163,15 @@ public class MongoPersistentEntityIndexCreator implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ensureIndex(String collection, final String name, final String def, final IndexDirection direction,
|
protected void ensureIndex(String collection, String name, DBObject indexDefinition, boolean unique,
|
||||||
final boolean unique, final boolean dropDups, final boolean sparse) {
|
boolean dropDups, boolean sparse) {
|
||||||
DBObject defObj;
|
|
||||||
if (null != def) {
|
|
||||||
defObj = (DBObject) JSON.parse(def);
|
|
||||||
} else {
|
|
||||||
defObj = new BasicDBObject();
|
|
||||||
defObj.put(name, (direction == IndexDirection.ASCENDING ? 1 : -1));
|
|
||||||
}
|
|
||||||
DBObject opts = new BasicDBObject();
|
DBObject opts = new BasicDBObject();
|
||||||
opts.put("name", name);
|
opts.put("name", name);
|
||||||
opts.put("dropDups", dropDups);
|
opts.put("dropDups", dropDups);
|
||||||
opts.put("sparse", sparse);
|
opts.put("sparse", sparse);
|
||||||
opts.put("unique", unique);
|
opts.put("unique", unique);
|
||||||
mongoDbFactory.getDb().getCollection(collection).ensureIndex(defObj, opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
mongoDbFactory.getDb().getCollection(collection).ensureIndex(indexDefinition, opts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ import org.springframework.data.util.TypeInformation;
|
|||||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||||
* @author Oliver Gierke ogierke@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;
|
private ApplicationContext context;
|
||||||
|
|
||||||
@@ -57,16 +58,16 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected <T> BasicMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
protected <T> BasicMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||||
|
|
||||||
BasicMongoPersistentEntity<T> entity = new BasicMongoPersistentEntity<T>(typeInformation);
|
BasicMongoPersistentEntity<T> entity = new BasicMongoPersistentEntity<T>(typeInformation);
|
||||||
|
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
entity.setApplicationContext(context);
|
entity.setApplicationContext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||||
|
|||||||
@@ -19,8 +19,10 @@ import java.math.BigInteger;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.bson.types.Binary;
|
||||||
import org.bson.types.CodeWScope;
|
import org.bson.types.CodeWScope;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||||
@@ -36,7 +38,7 @@ import com.mongodb.DBRef;
|
|||||||
public abstract class MongoSimpleTypes {
|
public abstract class MongoSimpleTypes {
|
||||||
|
|
||||||
public static final Set<Class<?>> AUTOGENERATED_ID_TYPES;
|
public static final Set<Class<?>> AUTOGENERATED_ID_TYPES;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Set<Class<?>> classes = new HashSet<Class<?>>();
|
Set<Class<?>> classes = new HashSet<Class<?>>();
|
||||||
classes.add(ObjectId.class);
|
classes.add(ObjectId.class);
|
||||||
@@ -50,6 +52,8 @@ public abstract class MongoSimpleTypes {
|
|||||||
simpleTypes.add(CodeWScope.class);
|
simpleTypes.add(CodeWScope.class);
|
||||||
simpleTypes.add(DBObject.class);
|
simpleTypes.add(DBObject.class);
|
||||||
simpleTypes.add(Pattern.class);
|
simpleTypes.add(Pattern.class);
|
||||||
|
simpleTypes.add(Binary.class);
|
||||||
|
simpleTypes.add(UUID.class);
|
||||||
MONGO_SIMPLE_TYPES = Collections.unmodifiableSet(simpleTypes);
|
MONGO_SIMPLE_TYPES = Collections.unmodifiableSet(simpleTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
|
|||||||
|
|
||||||
protected final Log LOG = LogFactory.getLog(getClass());
|
protected final Log LOG = LogFactory.getLog(getClass());
|
||||||
private final Class<?> domainClass;
|
private final Class<?> domainClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link AbstractMongoEventListener}.
|
* Creates a new {@link AbstractMongoEventListener}.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ public class AfterLoadEvent<T> extends MongoMappingEvent<DBObject> {
|
|||||||
* @param type must not be {@literal null}.
|
* @param type must not be {@literal null}.
|
||||||
*/
|
*/
|
||||||
public AfterLoadEvent(DBObject dbo, Class<T> type) {
|
public AfterLoadEvent(DBObject dbo, Class<T> type) {
|
||||||
|
|
||||||
super(dbo, dbo);
|
super(dbo, dbo);
|
||||||
|
|
||||||
Assert.notNull(type, "Type must not be null!");
|
Assert.notNull(type, "Type must not be null!");
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,24 +19,19 @@ import com.mongodb.BasicDBObject;
|
|||||||
import com.mongodb.DBObject;
|
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
|
* Collects the parameters required to perform a group operation on a collection. The query condition and the input
|
||||||
* to be consistent with other operations, e.g. map-reduce.
|
* collection are specified on the group method as method arguments to be consistent with other operations, e.g.
|
||||||
|
* map-reduce.
|
||||||
*
|
*
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class GroupBy {
|
public class GroupBy {
|
||||||
|
|
||||||
private DBObject dboKeys;
|
private DBObject dboKeys;
|
||||||
|
|
||||||
private String keyFunction;
|
private String keyFunction;
|
||||||
|
|
||||||
private String initial;
|
private String initial;
|
||||||
|
|
||||||
private DBObject initialDbObject;
|
private DBObject initialDbObject;
|
||||||
|
|
||||||
private String reduce;
|
private String reduce;
|
||||||
|
|
||||||
private String finalize;
|
private String finalize;
|
||||||
|
|
||||||
public GroupBy(String... keys) {
|
public GroupBy(String... keys) {
|
||||||
@@ -71,24 +66,22 @@ public class GroupBy {
|
|||||||
initial = initialDocument;
|
initial = initialDocument;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupBy initialDocument(DBObject initialDocument) {
|
public GroupBy initialDocument(DBObject initialDocument) {
|
||||||
initialDbObject = initialDocument;
|
initialDbObject = initialDocument;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupBy reduceFunction(String reduceFunction) {
|
public GroupBy reduceFunction(String reduceFunction) {
|
||||||
reduce = reduceFunction;
|
reduce = reduceFunction;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupBy finalizeFunction(String finalizeFunction) {
|
public GroupBy finalizeFunction(String finalizeFunction) {
|
||||||
finalize = finalizeFunction;
|
finalize = finalizeFunction;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public DBObject getGroupByObject() {
|
public DBObject getGroupByObject() {
|
||||||
// return new GroupCommand(dbCollection, dboKeys, condition, initial, reduce, finalize);
|
// return new GroupCommand(dbCollection, dboKeys, condition, initial, reduce, finalize);
|
||||||
BasicDBObject dbo = new BasicDBObject();
|
BasicDBObject dbo = new BasicDBObject();
|
||||||
@@ -100,19 +93,15 @@ public class GroupBy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dbo.put("$reduce", reduce);
|
dbo.put("$reduce", reduce);
|
||||||
|
|
||||||
dbo.put("initial", initialDbObject);
|
dbo.put("initial", initialDbObject);
|
||||||
if (initial != null) {
|
if (initial != null) {
|
||||||
dbo.put("initial", initial);
|
dbo.put("initial", initial);
|
||||||
}
|
}
|
||||||
if (finalize != null) {
|
if (finalize != null) {
|
||||||
dbo.put("finalize", finalize);
|
dbo.put("finalize", finalize);
|
||||||
}
|
}
|
||||||
return dbo;
|
return dbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,31 +26,27 @@ import com.mongodb.DBObject;
|
|||||||
* Collects the results of executing a group operation.
|
* Collects the results of executing a group operation.
|
||||||
*
|
*
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
*
|
|
||||||
* @param <T> The class in which the results are mapped onto, accessible via an interator.
|
* @param <T> The class in which the results are mapped onto, accessible via an interator.
|
||||||
*/
|
*/
|
||||||
public class GroupByResults<T> implements Iterable<T> {
|
public class GroupByResults<T> implements Iterable<T> {
|
||||||
|
|
||||||
private final List<T> mappedResults;
|
private final List<T> mappedResults;
|
||||||
|
private final DBObject rawResults;
|
||||||
private DBObject rawResults;
|
|
||||||
|
|
||||||
private double count;
|
private double count;
|
||||||
|
|
||||||
private int keys;
|
private int keys;
|
||||||
|
|
||||||
private String serverUsed;
|
private String serverUsed;
|
||||||
|
|
||||||
public GroupByResults(List<T> mappedResults, DBObject rawResults) {
|
public GroupByResults(List<T> mappedResults, DBObject rawResults) {
|
||||||
Assert.notNull(mappedResults);
|
Assert.notNull(mappedResults);
|
||||||
Assert.notNull(rawResults);
|
Assert.notNull(rawResults);
|
||||||
this.mappedResults = mappedResults;
|
this.mappedResults = mappedResults;
|
||||||
this.rawResults = rawResults;
|
this.rawResults = rawResults;
|
||||||
parseKeys();
|
parseKeys();
|
||||||
parseCount();
|
parseCount();
|
||||||
parseServerUsed();
|
parseServerUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getCount() {
|
public double getCount() {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@@ -58,36 +54,36 @@ public class GroupByResults<T> implements Iterable<T> {
|
|||||||
public int getKeys() {
|
public int getKeys() {
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServerUsed() {
|
public String getServerUsed() {
|
||||||
return serverUsed;
|
return serverUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterator<T> iterator() {
|
public Iterator<T> iterator() {
|
||||||
return mappedResults.iterator();
|
return mappedResults.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DBObject getRawResults() {
|
public DBObject getRawResults() {
|
||||||
return rawResults;
|
return rawResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseCount() {
|
private void parseCount() {
|
||||||
Object object = rawResults.get("count");
|
Object object = rawResults.get("count");
|
||||||
if (object instanceof Double) {
|
if (object instanceof Double) {
|
||||||
count = (Double) object;
|
count = (Double) object;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseKeys() {
|
private void parseKeys() {
|
||||||
Object object = rawResults.get("keys");
|
Object object = rawResults.get("keys");
|
||||||
if (object instanceof Integer) {
|
if (object instanceof Integer) {
|
||||||
keys = (Integer) object;
|
keys = (Integer) object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseServerUsed() {
|
private void parseServerUsed() {
|
||||||
//"serverUsed" : "127.0.0.1:27017"
|
// "serverUsed" : "127.0.0.1:27017"
|
||||||
Object object = rawResults.get("serverUsed");
|
Object object = rawResults.get("serverUsed");
|
||||||
if (object instanceof String) {
|
if (object instanceof String) {
|
||||||
serverUsed = (String) object;
|
serverUsed = (String) object;
|
||||||
|
|||||||
@@ -15,13 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core.mapreduce;
|
package org.springframework.data.mongodb.core.mapreduce;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mark Pollack
|
||||||
|
*/
|
||||||
public class MapReduceCounts {
|
public class MapReduceCounts {
|
||||||
|
|
||||||
private int inputCount;
|
private final int inputCount;
|
||||||
|
private final int emitCount;
|
||||||
private int emitCount;
|
private final int outputCount;
|
||||||
|
|
||||||
private int outputCount;
|
|
||||||
|
|
||||||
public MapReduceCounts(int inputCount, int emitCount, int outputCount) {
|
public MapReduceCounts(int inputCount, int emitCount, int outputCount) {
|
||||||
super();
|
super();
|
||||||
@@ -42,12 +43,20 @@ public class MapReduceCounts {
|
|||||||
return outputCount;
|
return outputCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "MapReduceCounts [inputCount=" + inputCount + ", emitCount=" + emitCount + ", outputCount=" + outputCount
|
return "MapReduceCounts [inputCount=" + inputCount + ", emitCount=" + emitCount + ", outputCount=" + outputCount
|
||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#hashCode()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
@@ -58,24 +67,31 @@ public class MapReduceCounts {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#equals(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj) {
|
||||||
return true;
|
return true;
|
||||||
if (obj == null)
|
}
|
||||||
|
if (obj == null) {
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
MapReduceCounts other = (MapReduceCounts) obj;
|
MapReduceCounts other = (MapReduceCounts) obj;
|
||||||
if (emitCount != other.emitCount)
|
if (emitCount != other.emitCount) {
|
||||||
return false;
|
return false;
|
||||||
if (inputCount != other.inputCount)
|
}
|
||||||
|
if (inputCount != other.inputCount) {
|
||||||
return false;
|
return false;
|
||||||
if (outputCount != other.outputCount)
|
}
|
||||||
|
if (outputCount != other.outputCount) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,9 @@ public class MapReduceOptions {
|
|||||||
private Boolean jsMode;
|
private Boolean jsMode;
|
||||||
|
|
||||||
private Boolean verbose = true;
|
private Boolean verbose = true;
|
||||||
|
|
||||||
private Map<String, Object> extraOptions = new HashMap<String, Object>();
|
private Map<String, Object> extraOptions = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static factory method to create a MapReduceOptions instance
|
* Static factory method to create a MapReduceOptions instance
|
||||||
*
|
*
|
||||||
@@ -189,12 +188,12 @@ public class MapReduceOptions {
|
|||||||
this.verbose = verbose;
|
this.verbose = verbose;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add additional extra options that may not have a method on this class. This method will help if you use a
|
* Add additional extra options that may not have a method on this class. This method will help if you use a version
|
||||||
* version of this client library with a server version that has added additional map-reduce options that do not
|
* of this client library with a server version that has added additional map-reduce options that do not yet have an
|
||||||
* yet have an method for use in setting them.
|
* method for use in setting them. options
|
||||||
* options
|
*
|
||||||
* @param key The key option
|
* @param key The key option
|
||||||
* @param value The value of the option
|
* @param value The value of the option
|
||||||
* @return MapReduceOptions so that methods can be chained in a fluent API style
|
* @return MapReduceOptions so that methods can be chained in a fluent API style
|
||||||
@@ -203,40 +202,39 @@ public class MapReduceOptions {
|
|||||||
extraOptions.put(key, value);
|
extraOptions.put(key, value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> getExtraOptions() {
|
public Map<String, Object> getExtraOptions() {
|
||||||
return extraOptions;
|
return extraOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFinalizeFunction() {
|
public String getFinalizeFunction() {
|
||||||
return this.finalizeFunction;
|
return this.finalizeFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getJavaScriptMode() {
|
public Boolean getJavaScriptMode() {
|
||||||
return this.jsMode;
|
return this.jsMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOutputCollection() {
|
public String getOutputCollection() {
|
||||||
return this.outputCollection;
|
return this.outputCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOutputDatabase() {
|
public String getOutputDatabase() {
|
||||||
return this.outputDatabase;
|
return this.outputDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getOutputSharded() {
|
public Boolean getOutputSharded() {
|
||||||
return this.outputSharded;
|
return this.outputSharded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapReduceCommand.OutputType getOutputType() {
|
public MapReduceCommand.OutputType getOutputType() {
|
||||||
return this.outputType;
|
return this.outputType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> getScopeVariables() {
|
public Map<String, Object> getScopeVariables() {
|
||||||
return this.scopeVariables;
|
return this.scopeVariables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public DBObject getOptionsObject() {
|
public DBObject getOptionsObject() {
|
||||||
BasicDBObject cmd = new BasicDBObject();
|
BasicDBObject cmd = new BasicDBObject();
|
||||||
|
|
||||||
@@ -253,7 +251,7 @@ public class MapReduceOptions {
|
|||||||
if (scopeVariables != null) {
|
if (scopeVariables != null) {
|
||||||
cmd.put("scope", scopeVariables);
|
cmd.put("scope", scopeVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!extraOptions.keySet().isEmpty()) {
|
if (!extraOptions.keySet().isEmpty()) {
|
||||||
cmd.putAll(extraOptions);
|
cmd.putAll(extraOptions);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -24,77 +24,126 @@ import com.mongodb.DBObject;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects the results of performing a MapReduce operations.
|
* Collects the results of performing a MapReduce operations.
|
||||||
|
*
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
*
|
* @author Oliver Gierke
|
||||||
* @param <T> The class in which the results are mapped onto, accessible via an interator.
|
* @param <T> The class in which the results are mapped onto, accessible via an iterator.
|
||||||
*/
|
*/
|
||||||
public class MapReduceResults<T> implements Iterable<T> {
|
public class MapReduceResults<T> implements Iterable<T> {
|
||||||
|
|
||||||
private final List<T> mappedResults;
|
private final List<T> mappedResults;
|
||||||
|
private final DBObject rawResults;
|
||||||
private DBObject rawResults;
|
private final String outputCollection;
|
||||||
|
private final MapReduceTiming mapReduceTiming;
|
||||||
|
private final MapReduceCounts mapReduceCounts;
|
||||||
|
|
||||||
private MapReduceTiming mapReduceTiming;
|
/**
|
||||||
|
* Creates a new {@link MapReduceResults} from the given mapped results and the raw one.
|
||||||
private MapReduceCounts mapReduceCounts;
|
*
|
||||||
|
* @param mappedResults must not be {@literal null}.
|
||||||
private String outputCollection;
|
* @param rawResults must not be {@literal null}.
|
||||||
|
*/
|
||||||
public MapReduceResults(List<T> mappedResults, DBObject rawResults) {
|
public MapReduceResults(List<T> mappedResults, DBObject rawResults) {
|
||||||
|
|
||||||
Assert.notNull(mappedResults);
|
Assert.notNull(mappedResults);
|
||||||
Assert.notNull(rawResults);
|
Assert.notNull(rawResults);
|
||||||
|
|
||||||
this.mappedResults = mappedResults;
|
this.mappedResults = mappedResults;
|
||||||
this.rawResults = rawResults;
|
this.rawResults = rawResults;
|
||||||
parseTiming(rawResults);
|
this.mapReduceTiming = parseTiming(rawResults);
|
||||||
parseCounts(rawResults);
|
this.mapReduceCounts = parseCounts(rawResults);
|
||||||
if (rawResults.get("result") != null) {
|
this.outputCollection = parseOutputCollection(rawResults);
|
||||||
this.outputCollection = (String) rawResults.get("result");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Iterable#iterator()
|
||||||
|
*/
|
||||||
public Iterator<T> iterator() {
|
public Iterator<T> iterator() {
|
||||||
return mappedResults.iterator();
|
return mappedResults.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapReduceTiming getTiming() {
|
public MapReduceTiming getTiming() {
|
||||||
return mapReduceTiming;
|
return mapReduceTiming;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapReduceCounts getCounts() {
|
public MapReduceCounts getCounts() {
|
||||||
return mapReduceCounts;
|
return mapReduceCounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOutputCollection() {
|
public String getOutputCollection() {
|
||||||
return outputCollection;
|
return outputCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DBObject getRawResults() {
|
public DBObject getRawResults() {
|
||||||
return rawResults;
|
return rawResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void parseTiming(DBObject rawResults) {
|
private MapReduceTiming parseTiming(DBObject rawResults) {
|
||||||
|
|
||||||
DBObject timing = (DBObject) rawResults.get("timing");
|
DBObject timing = (DBObject) rawResults.get("timing");
|
||||||
if (timing != null) {
|
|
||||||
if (timing.get("mapTime") != null && timing.get("emitLoop") != null && timing.get("total") != null) {
|
if (timing == null) {
|
||||||
mapReduceTiming = new MapReduceTiming( (Long)timing.get("mapTime"),
|
return new MapReduceTiming(-1, -1, -1);
|
||||||
(Integer)timing.get("emitLoop"),
|
|
||||||
(Integer)timing.get("total"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mapReduceTiming = new MapReduceTiming(-1,-1,-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timing.get("mapTime") != null && timing.get("emitLoop") != null && timing.get("total") != null) {
|
||||||
|
return new MapReduceTiming(getAsLong(timing, "mapTime"), getAsLong(timing, "emitLoop"),
|
||||||
|
getAsLong(timing, "total"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MapReduceTiming(-1, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
protected void parseCounts(DBObject rawResults) {
|
* Returns the value of the source's field with the given key as {@link Long}.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Long getAsLong(DBObject source, String key) {
|
||||||
|
Object raw = source.get(key);
|
||||||
|
return raw instanceof Long ? (Long) raw : (Integer) raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the raw {@link DBObject} result into a {@link MapReduceCounts} value object.
|
||||||
|
*
|
||||||
|
* @param rawResults
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private MapReduceCounts parseCounts(DBObject rawResults) {
|
||||||
|
|
||||||
DBObject counts = (DBObject) rawResults.get("counts");
|
DBObject counts = (DBObject) rawResults.get("counts");
|
||||||
if (counts != null) {
|
|
||||||
if (counts.get("input") != null && counts.get("emit") != null && counts.get("output") != null) {
|
if (counts == null) {
|
||||||
mapReduceCounts = new MapReduceCounts( (Integer)counts.get("input"), (Integer)counts.get("emit"), (Integer)counts.get("output"));
|
return new MapReduceCounts(-1, -1, -1);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mapReduceCounts = new MapReduceCounts(-1,-1,-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (counts.get("input") != null && counts.get("emit") != null && counts.get("output") != null) {
|
||||||
|
return new MapReduceCounts((Integer) counts.get("input"), (Integer) counts.get("emit"),
|
||||||
|
(Integer) counts.get("output"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MapReduceCounts(-1, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the output collection from the raw {@link DBObject} result.
|
||||||
|
*
|
||||||
|
* @param rawResults
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String parseOutputCollection(DBObject rawResults) {
|
||||||
|
|
||||||
|
Object resultField = rawResults.get("result");
|
||||||
|
|
||||||
|
if (resultField == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultField instanceof DBObject ? ((DBObject) resultField).get("collection").toString() : resultField
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,15 +18,15 @@ package org.springframework.data.mongodb.core.mapreduce;
|
|||||||
public class MapReduceTiming {
|
public class MapReduceTiming {
|
||||||
|
|
||||||
private long mapTime;
|
private long mapTime;
|
||||||
|
|
||||||
private long emitLoopTime;
|
private long emitLoopTime;
|
||||||
|
|
||||||
private long totalTime;
|
private long totalTime;
|
||||||
|
|
||||||
public MapReduceTiming(long mapTime, long emitLoopTime, long totalTime) {
|
public MapReduceTiming(long mapTime, long emitLoopTime, long totalTime) {
|
||||||
this.mapTime = mapTime;
|
this.mapTime = mapTime;
|
||||||
this.emitLoopTime = emitLoopTime;
|
this.emitLoopTime = emitLoopTime;
|
||||||
this.totalTime = totalTime;
|
this.totalTime = totalTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getMapTime() {
|
public long getMapTime() {
|
||||||
@@ -73,8 +73,5 @@ public class MapReduceTiming {
|
|||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,19 +15,23 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core.query;
|
package org.springframework.data.mongodb.core.query;
|
||||||
|
|
||||||
|
import static org.springframework.util.ObjectUtils.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.bson.BSON;
|
||||||
import org.bson.types.BasicBSONList;
|
import org.bson.types.BasicBSONList;
|
||||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||||
import org.springframework.data.mongodb.core.geo.Circle;
|
import org.springframework.data.mongodb.core.geo.Circle;
|
||||||
import org.springframework.data.mongodb.core.geo.Point;
|
import org.springframework.data.mongodb.core.geo.Point;
|
||||||
import org.springframework.data.mongodb.core.geo.Shape;
|
import org.springframework.data.mongodb.core.geo.Shape;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
import com.mongodb.BasicDBObject;
|
import com.mongodb.BasicDBObject;
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
@@ -69,7 +73,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Static factory method to create a Criteria using the provided key
|
* Static factory method to create a Criteria using the provided key
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -79,7 +83,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Static factory method to create a Criteria using the provided key
|
* Static factory method to create a Criteria using the provided key
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Criteria and(String key) {
|
public Criteria and(String key) {
|
||||||
@@ -88,7 +92,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using equality
|
* Creates a criterion using equality
|
||||||
*
|
*
|
||||||
* @param o
|
* @param o
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -97,16 +101,20 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
throw new InvalidMongoDbApiUsageException(
|
throw new InvalidMongoDbApiUsageException(
|
||||||
"Multiple 'is' values declared. You need to use 'and' with multiple criteria");
|
"Multiple 'is' values declared. You need to use 'and' with multiple criteria");
|
||||||
}
|
}
|
||||||
if (this.criteria.size() > 0 && "$not".equals(this.criteria.keySet().toArray()[this.criteria.size() - 1])) {
|
if (lastOperatorWasNot()) {
|
||||||
throw new InvalidMongoDbApiUsageException("Invalid query: 'not' can't be used with 'is' - use 'ne' instead.");
|
throw new InvalidMongoDbApiUsageException("Invalid query: 'not' can't be used with 'is' - use 'ne' instead.");
|
||||||
}
|
}
|
||||||
this.isValue = o;
|
this.isValue = o;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean lastOperatorWasNot() {
|
||||||
|
return this.criteria.size() > 0 && "$not".equals(this.criteria.keySet().toArray()[this.criteria.size() - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $ne operator
|
* Creates a criterion using the $ne operator
|
||||||
*
|
*
|
||||||
* @param o
|
* @param o
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -117,7 +125,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $lt operator
|
* Creates a criterion using the $lt operator
|
||||||
*
|
*
|
||||||
* @param o
|
* @param o
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -128,7 +136,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $lte operator
|
* Creates a criterion using the $lte operator
|
||||||
*
|
*
|
||||||
* @param o
|
* @param o
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -139,7 +147,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $gt operator
|
* Creates a criterion using the $gt operator
|
||||||
*
|
*
|
||||||
* @param o
|
* @param o
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -150,7 +158,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $gte operator
|
* Creates a criterion using the $gte operator
|
||||||
*
|
*
|
||||||
* @param o
|
* @param o
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -161,7 +169,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $in operator
|
* Creates a criterion using the $in operator
|
||||||
*
|
*
|
||||||
* @param o the values to match against
|
* @param o the values to match against
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -176,7 +184,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $in operator
|
* Creates a criterion using the $in operator
|
||||||
*
|
*
|
||||||
* @param c the collection containing the values to match against
|
* @param c the collection containing the values to match against
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -187,7 +195,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $nin operator
|
* Creates a criterion using the $nin operator
|
||||||
*
|
*
|
||||||
* @param o
|
* @param o
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -202,7 +210,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $mod operator
|
* Creates a criterion using the $mod operator
|
||||||
*
|
*
|
||||||
* @param value
|
* @param value
|
||||||
* @param remainder
|
* @param remainder
|
||||||
* @return
|
* @return
|
||||||
@@ -217,7 +225,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $all operator
|
* Creates a criterion using the $all operator
|
||||||
*
|
*
|
||||||
* @param o
|
* @param o
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -232,7 +240,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $size operator
|
* Creates a criterion using the $size operator
|
||||||
*
|
*
|
||||||
* @param s
|
* @param s
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -243,7 +251,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $exists operator
|
* Creates a criterion using the $exists operator
|
||||||
*
|
*
|
||||||
* @param b
|
* @param b
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -254,7 +262,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $type operator
|
* Creates a criterion using the $type operator
|
||||||
*
|
*
|
||||||
* @param t
|
* @param t
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -265,43 +273,65 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $not meta operator which affects the clause directly following
|
* Creates a criterion using the $not meta operator which affects the clause directly following
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Criteria not() {
|
public Criteria not() {
|
||||||
criteria.put("$not", null);
|
return not(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Criteria not(Object value) {
|
||||||
|
criteria.put("$not", value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using a $regex
|
* Creates a criterion using a $regex
|
||||||
*
|
*
|
||||||
* @param re
|
* @param re
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Criteria regex(String re) {
|
public Criteria regex(String re) {
|
||||||
criteria.put("$regex", re);
|
return regex(re, null);
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using a $regex and $options
|
* Creates a criterion using a $regex and $options
|
||||||
*
|
*
|
||||||
* @param re
|
* @param re
|
||||||
* @param options
|
* @param options
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Criteria regex(String re, String options) {
|
public Criteria regex(String re, String options) {
|
||||||
criteria.put("$regex", re);
|
return regex(toPattern(re, options));
|
||||||
if (StringUtils.hasText(options)) {
|
}
|
||||||
criteria.put("$options", options);
|
|
||||||
|
/**
|
||||||
|
* Syntactical sugar for {@link #is(Object)} making obvious that we create a regex predicate.
|
||||||
|
*
|
||||||
|
* @param pattern
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Criteria regex(Pattern pattern) {
|
||||||
|
|
||||||
|
Assert.notNull(pattern);
|
||||||
|
|
||||||
|
if (lastOperatorWasNot()) {
|
||||||
|
return not(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.isValue = pattern;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Pattern toPattern(String regex, String options) {
|
||||||
|
Assert.notNull(regex);
|
||||||
|
return Pattern.compile(regex, options == null ? 0 : BSON.regexFlags(options));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a geospatial criterion using a $within $center operation. This is only available for Mongo 1.7 and higher.
|
* 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}
|
* @param circle must not be {@literal null}
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -320,7 +350,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a geospatial criterion using a $near operation
|
* Creates a geospatial criterion using a $near operation
|
||||||
*
|
*
|
||||||
* @param point must not be {@literal null}
|
* @param point must not be {@literal null}
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -332,7 +362,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a geospatial criterion using a $nearSphere operation. This is only available for Mongo 1.7 and higher.
|
* 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}
|
* @param point must not be {@literal null}
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -344,7 +374,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a geospatical criterion using a $maxDistance operation, for use with $near
|
* Creates a geospatical criterion using a $maxDistance operation, for use with $near
|
||||||
*
|
*
|
||||||
* @param maxDistance
|
* @param maxDistance
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -355,7 +385,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a criterion using the $elemMatch operator
|
* Creates a criterion using the $elemMatch operator
|
||||||
*
|
*
|
||||||
* @param c
|
* @param c
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -366,7 +396,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an 'or' criteria using the $or operator for all of the provided criteria
|
* Creates an 'or' criteria using the $or operator for all of the provided criteria
|
||||||
*
|
*
|
||||||
* @param criteria
|
* @param criteria
|
||||||
*/
|
*/
|
||||||
public Criteria orOperator(Criteria... criteria) {
|
public Criteria orOperator(Criteria... criteria) {
|
||||||
@@ -377,7 +407,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a 'nor' criteria using the $nor operator for all of the provided criteria
|
* Creates a 'nor' criteria using the $nor operator for all of the provided criteria
|
||||||
*
|
*
|
||||||
* @param criteria
|
* @param criteria
|
||||||
*/
|
*/
|
||||||
public Criteria norOperator(Criteria... criteria) {
|
public Criteria norOperator(Criteria... criteria) {
|
||||||
@@ -388,7 +418,7 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an 'and' criteria using the $and operator for all of the provided criteria
|
* Creates an 'and' criteria using the $and operator for all of the provided criteria
|
||||||
*
|
*
|
||||||
* @param criteria
|
* @param criteria
|
||||||
*/
|
*/
|
||||||
public Criteria andOperator(Criteria... criteria) {
|
public Criteria andOperator(Criteria... criteria) {
|
||||||
@@ -397,17 +427,14 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
return this.key;
|
return this.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.mongodb.core.query.CriteriaDefinition#getCriteriaObject()
|
||||||
* @see org.springframework.datastore.document.mongodb.query.Criteria#
|
*/
|
||||||
* getCriteriaObject(java.lang.String)
|
|
||||||
*/
|
|
||||||
public DBObject getCriteriaObject() {
|
public DBObject getCriteriaObject() {
|
||||||
if (this.criteriaChain.size() == 1) {
|
if (this.criteriaChain.size() == 1) {
|
||||||
return criteriaChain.get(0).getSingleCriteriaObject();
|
return criteriaChain.get(0).getSingleCriteriaObject();
|
||||||
@@ -427,16 +454,17 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
DBObject dbo = new BasicDBObject();
|
DBObject dbo = new BasicDBObject();
|
||||||
boolean not = false;
|
boolean not = false;
|
||||||
for (String k : this.criteria.keySet()) {
|
for (String k : this.criteria.keySet()) {
|
||||||
|
Object value = this.criteria.get(k);
|
||||||
if (not) {
|
if (not) {
|
||||||
DBObject notDbo = new BasicDBObject();
|
DBObject notDbo = new BasicDBObject();
|
||||||
notDbo.put(k, this.criteria.get(k));
|
notDbo.put(k, value);
|
||||||
dbo.put("$not", notDbo);
|
dbo.put("$not", notDbo);
|
||||||
not = false;
|
not = false;
|
||||||
} else {
|
} else {
|
||||||
if ("$not".equals(k)) {
|
if ("$not".equals(k) && value == null) {
|
||||||
not = true;
|
not = true;
|
||||||
} else {
|
} else {
|
||||||
dbo.put(k, this.criteria.get(k));
|
dbo.put(k, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -462,12 +490,89 @@ public class Criteria implements CriteriaDefinition {
|
|||||||
Object existing = dbo.get(key);
|
Object existing = dbo.get(key);
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
dbo.put(key, value);
|
dbo.put(key, value);
|
||||||
}
|
} else {
|
||||||
else {
|
throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDBObject, "
|
||||||
throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDBObject, " +
|
+ "you can't add a second '" + key + "' expression specified as '" + key + " : " + value + "'. "
|
||||||
"you can't add a second '" + key + "' expression specified as '" + key + " : " + value + "'. " +
|
+ "Criteria already contains '" + key + " : " + existing + "'.");
|
||||||
"Criteria already contains '" + key + " : " + existing + "'.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Criteria that = (Criteria) obj;
|
||||||
|
|
||||||
|
if (this.criteriaChain.size() != that.criteriaChain.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < this.criteriaChain.size(); i++) {
|
||||||
|
|
||||||
|
Criteria left = this.criteriaChain.get(i);
|
||||||
|
Criteria right = that.criteriaChain.get(i);
|
||||||
|
|
||||||
|
if (!simpleCriteriaEquals(left, right)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean simpleCriteriaEquals(Criteria left, Criteria right) {
|
||||||
|
|
||||||
|
boolean keyEqual = left.key == null ? right.key == null : left.key.equals(right.key);
|
||||||
|
boolean criteriaEqual = left.criteria.equals(right.criteria);
|
||||||
|
boolean valueEqual = isEqual(left.isValue, right.isValue);
|
||||||
|
|
||||||
|
return keyEqual && criteriaEqual && valueEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the given objects for equality. Handles {@link Pattern} and arrays correctly.
|
||||||
|
*
|
||||||
|
* @param left
|
||||||
|
* @param right
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isEqual(Object left, Object right) {
|
||||||
|
|
||||||
|
if (left == null) {
|
||||||
|
return right == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left instanceof Pattern) {
|
||||||
|
return right instanceof Pattern ? ((Pattern) left).pattern().equals(((Pattern) right).pattern()) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ObjectUtils.nullSafeEquals(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#hashCode()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
|
||||||
|
int result = 17;
|
||||||
|
|
||||||
|
result += nullSafeHashCode(key);
|
||||||
|
result += criteria.hashCode();
|
||||||
|
result += nullSafeHashCode(isValue);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011 the original author or authors.
|
* Copyright 2011-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -18,6 +18,12 @@ package org.springframework.data.mongodb.core.query;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link Criteria#orOperator(Criteria...)} instead.
|
||||||
|
* @author Thomas Risberg
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public class OrQuery extends Query {
|
public class OrQuery extends Query {
|
||||||
|
|
||||||
public OrQuery(Query... q) {
|
public OrQuery(Query... q) {
|
||||||
@@ -31,5 +37,4 @@ public class OrQuery extends Query {
|
|||||||
}
|
}
|
||||||
return new Criteria(criteriaList, "$or");
|
return new Criteria(criteriaList, "$or");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core.query;
|
package org.springframework.data.mongodb.core.query;
|
||||||
|
|
||||||
|
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
|
||||||
|
import static org.springframework.util.ObjectUtils.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -36,7 +39,7 @@ public class Query {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Static factory method to create a Query using the provided criteria
|
* Static factory method to create a Query using the provided criteria
|
||||||
*
|
*
|
||||||
* @param critera
|
* @param critera
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -56,11 +59,10 @@ public class Query {
|
|||||||
String key = criteria.getKey();
|
String key = criteria.getKey();
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
this.criteria.put(key, criteria);
|
this.criteria.put(key, criteria);
|
||||||
}
|
} else {
|
||||||
else {
|
throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDBObject, "
|
||||||
throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDBObject, " +
|
+ "you can't add a second '" + key + "' criteria. " + "Query already contains '"
|
||||||
"you can't add a second '" + key + "' criteria. " +
|
+ existing.getCriteriaObject() + "'.");
|
||||||
"Query already contains '" + existing.getCriteriaObject() + "'.");
|
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -93,12 +95,12 @@ public class Query {
|
|||||||
this.hint = name;
|
this.hint = name;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sort sort() {
|
public Sort sort() {
|
||||||
if (this.sort == null) {
|
if (this.sort == null) {
|
||||||
this.sort = new Sort();
|
this.sort = new Sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.sort;
|
return this.sort;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,8 +139,64 @@ public class Query {
|
|||||||
public String getHint() {
|
public String getHint() {
|
||||||
return hint;
|
return hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<Criteria> getCriteria() {
|
protected List<Criteria> getCriteria() {
|
||||||
return new ArrayList<Criteria>(this.criteria.values());
|
return new ArrayList<Criteria>(this.criteria.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("Query: %s, Fields: %s, Sort: %s", serializeToJsonSafely(getQueryObject()),
|
||||||
|
serializeToJsonSafely(getFieldsObject()), serializeToJsonSafely(getSortObject()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Query that = (Query) obj;
|
||||||
|
|
||||||
|
boolean criteriaEqual = this.criteria.equals(that.criteria);
|
||||||
|
boolean fieldsEqual = this.fieldSpec == null ? that.fieldSpec == null : this.fieldSpec.equals(that.fieldSpec);
|
||||||
|
boolean sortEqual = this.sort == null ? that.sort == null : this.sort.equals(that.sort);
|
||||||
|
boolean hintEqual = this.hint == null ? that.hint == null : this.hint.equals(that.hint);
|
||||||
|
boolean skipEqual = this.skip == that.skip;
|
||||||
|
boolean limitEqual = this.limit == that.limit;
|
||||||
|
|
||||||
|
return criteriaEqual && fieldsEqual && sortEqual && hintEqual && skipEqual && limitEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#hashCode()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
|
||||||
|
int result = 17;
|
||||||
|
|
||||||
|
result += 31 * criteria.hashCode();
|
||||||
|
result += 31 * nullSafeHashCode(fieldSpec);
|
||||||
|
result += 31 * nullSafeHashCode(sort);
|
||||||
|
result += 31 * nullSafeHashCode(hint);
|
||||||
|
result += 31 * skip;
|
||||||
|
result += 31 * limit;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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.query;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.springframework.core.convert.converter.Converter;
|
||||||
|
|
||||||
|
import com.mongodb.DBObject;
|
||||||
|
import com.mongodb.util.JSON;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods for JSON serialization.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public abstract class SerializationUtils {
|
||||||
|
|
||||||
|
private SerializationUtils() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the given object into pseudo-JSON meaning it's trying to create a JSON representation as far as possible
|
||||||
|
* but falling back to the given object's {@link Object#toString()} method if it's not serializable. Useful for
|
||||||
|
* printing raw {@link DBObject}s containing complex values before actually converting them into Mongo native types.
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String serializeToJsonSafely(Object value) {
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return JSON.serialize(value);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (value instanceof Collection) {
|
||||||
|
return toString((Collection<?>) value);
|
||||||
|
} else if (value instanceof Map) {
|
||||||
|
return toString((Map<?, ?>) value);
|
||||||
|
} else if (value instanceof DBObject) {
|
||||||
|
return toString(((DBObject) value).toMap());
|
||||||
|
} else {
|
||||||
|
return String.format("{ $java : %s }", value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toString(Map<?, ?> source) {
|
||||||
|
return iterableToDelimitedString(source.entrySet(), "{ ", " }", new Converter<Entry<?, ?>, Object>() {
|
||||||
|
public Object convert(Entry<?, ?> source) {
|
||||||
|
return String.format("\"%s\" : %s", source.getKey(), serializeToJsonSafely(source.getValue()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toString(Collection<?> source) {
|
||||||
|
return iterableToDelimitedString(source, "[ ", " ]", new Converter<Object, Object>() {
|
||||||
|
public Object convert(Object source) {
|
||||||
|
return serializeToJsonSafely(source);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a string representation from the given {@link Iterable} prepending the postfix, applying the given
|
||||||
|
* {@link Converter} to each element before adding it to the result {@link String}, concatenating each element with
|
||||||
|
* {@literal ,} and applying the postfix.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* @param prefix
|
||||||
|
* @param postfix
|
||||||
|
* @param transformer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static <T> String iterableToDelimitedString(Iterable<T> source, String prefix, String postfix,
|
||||||
|
Converter<? super T, Object> transformer) {
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder(prefix);
|
||||||
|
Iterator<T> iterator = source.iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
builder.append(transformer.convert(iterator.next()));
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
builder.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.append(postfix).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,7 +48,7 @@ public class MongoRepositoryConfigParser extends
|
|||||||
protected void postProcessBeanDefinition(MongoRepositoryConfiguration context, BeanDefinitionBuilder builder,
|
protected void postProcessBeanDefinition(MongoRepositoryConfiguration context, BeanDefinitionBuilder builder,
|
||||||
BeanDefinitionRegistry registry, Object beanSource) {
|
BeanDefinitionRegistry registry, Object beanSource) {
|
||||||
|
|
||||||
builder.addPropertyReference("template", context.getMongoTemplateRef());
|
builder.addPropertyReference("mongoOperations", context.getMongoTemplateRef());
|
||||||
builder.addPropertyValue("createIndexesForQueryMethods", context.getCreateQueryIndexes());
|
builder.addPropertyValue("createIndexesForQueryMethods", context.getCreateQueryIndexes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2010-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,15 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.repository.query;
|
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 java.util.List;
|
||||||
|
|
||||||
import org.springframework.data.domain.PageImpl;
|
import org.springframework.data.domain.PageImpl;
|
||||||
import org.springframework.data.domain.Pageable;
|
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.MongoOperations;
|
||||||
import org.springframework.data.mongodb.core.geo.Distance;
|
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.GeoResult;
|
||||||
import org.springframework.data.mongodb.core.geo.GeoResults;
|
import org.springframework.data.mongodb.core.geo.GeoResults;
|
||||||
import org.springframework.data.mongodb.core.geo.Point;
|
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.data.util.TypeInformation;
|
||||||
import org.springframework.util.Assert;
|
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.
|
* Base class for {@link RepositoryQuery} implementations for Mongo.
|
||||||
*
|
*
|
||||||
@@ -46,45 +42,50 @@ import com.mongodb.DBObject;
|
|||||||
public abstract class AbstractMongoQuery implements RepositoryQuery {
|
public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||||
|
|
||||||
private final MongoQueryMethod method;
|
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}.
|
* Creates a new {@link AbstractMongoQuery} from the given {@link MongoQueryMethod} and {@link MongoOperations}.
|
||||||
*
|
*
|
||||||
* @param method
|
* @param method must not be {@literal null}.
|
||||||
* @param template
|
* @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);
|
Assert.notNull(method);
|
||||||
|
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.mongoOperations = template;
|
this.operations = operations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.repository.query.RepositoryQuery#getQueryMethod()
|
* @see org.springframework.data.repository.query.RepositoryQuery#getQueryMethod()
|
||||||
*/
|
*/
|
||||||
public MongoQueryMethod getQueryMethod() {
|
public MongoQueryMethod getQueryMethod() {
|
||||||
|
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[])
|
||||||
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java .lang.Object[])
|
*/
|
||||||
*/
|
|
||||||
public Object execute(Object[] parameters) {
|
public Object execute(Object[] parameters) {
|
||||||
|
|
||||||
MongoParameterAccessor accessor = new MongoParametersParameterAccessor(method, 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);
|
return new GeoNearExecution(accessor).execute(query);
|
||||||
} else if (method.isCollectionQuery()) {
|
} else if (method.isCollectionQuery()) {
|
||||||
return new CollectionExecution().execute(query);
|
return new CollectionExecution(accessor.getPageable()).execute(query);
|
||||||
} else if (method.isPageQuery()) {
|
} else if (method.isPageQuery()) {
|
||||||
return new PagedExecution(accessor.getPageable()).execute(query);
|
return new PagedExecution(accessor.getPageable()).execute(query);
|
||||||
} else {
|
} else {
|
||||||
@@ -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 accessor must not be {@literal null}.
|
||||||
* @param converter
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected abstract Query createQuery(ConvertingParameterAccessor accessor);
|
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 {
|
private abstract class Execution {
|
||||||
|
|
||||||
abstract Object execute(Query query);
|
abstract Object execute(Query query);
|
||||||
@@ -110,7 +122,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
|||||||
MongoEntityInformation<?, ?> metadata = method.getEntityInformation();
|
MongoEntityInformation<?, ?> metadata = method.getEntityInformation();
|
||||||
|
|
||||||
String collectionName = metadata.getCollectionName();
|
String collectionName = metadata.getCollectionName();
|
||||||
return mongoOperations.find(query, metadata.getJavaType(), collectionName);
|
return operations.find(query, metadata.getJavaType(), collectionName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,14 +133,23 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
|||||||
*/
|
*/
|
||||||
class CollectionExecution extends Execution {
|
class CollectionExecution extends Execution {
|
||||||
|
|
||||||
|
private final Pageable pageable;
|
||||||
|
|
||||||
|
CollectionExecution(Pageable pageable) {
|
||||||
|
this.pageable = pageable;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.query.Query)
|
||||||
* @see org.springframework.data.mongodb.repository.MongoQuery.Execution #execute(com.mongodb.DBObject)
|
*/
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Object execute(Query query) {
|
public Object execute(Query query) {
|
||||||
|
|
||||||
|
if (pageable != null) {
|
||||||
|
query = applyPagination(query, pageable);
|
||||||
|
}
|
||||||
|
|
||||||
return readCollection(query);
|
return readCollection(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,24 +183,13 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
|||||||
Object execute(Query query) {
|
Object execute(Query query) {
|
||||||
|
|
||||||
MongoEntityInformation<?, ?> metadata = method.getEntityInformation();
|
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());
|
metadata.getCollectionName());
|
||||||
|
|
||||||
return new PageImpl(result, pageable, count);
|
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 +207,19 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
|||||||
Object execute(Query query) {
|
Object execute(Query query) {
|
||||||
|
|
||||||
MongoEntityInformation<?, ?> entityInformation = method.getEntityInformation();
|
MongoEntityInformation<?, ?> entityInformation = method.getEntityInformation();
|
||||||
return mongoOperations.findOne(query, entityInformation.getJavaType());
|
return operations.findOne(query, entityInformation.getJavaType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Execution} to execute geo-near queries.
|
* {@link Execution} to execute geo-near queries.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
class GeoNearExecution extends Execution {
|
class GeoNearExecution extends Execution {
|
||||||
|
|
||||||
private final MongoParameterAccessor accessor;
|
private final MongoParameterAccessor accessor;
|
||||||
|
|
||||||
public GeoNearExecution(MongoParameterAccessor accessor) {
|
public GeoNearExecution(MongoParameterAccessor accessor) {
|
||||||
this.accessor = accessor;
|
this.accessor = accessor;
|
||||||
}
|
}
|
||||||
@@ -220,27 +230,48 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
Object execute(Query query) {
|
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();
|
Point nearLocation = accessor.getGeoNearLocation();
|
||||||
NearQuery nearQuery = NearQuery.near(nearLocation);
|
NearQuery nearQuery = NearQuery.near(nearLocation);
|
||||||
|
|
||||||
if (query != null) {
|
if (query != null) {
|
||||||
nearQuery.query(query);
|
nearQuery.query(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
Distance maxDistance = accessor.getMaxDistance();
|
Distance maxDistance = accessor.getMaxDistance();
|
||||||
if (maxDistance != null) {
|
if (maxDistance != null) {
|
||||||
nearQuery.maxDistance(maxDistance);
|
nearQuery.maxDistance(maxDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
MongoEntityInformation<?,?> entityInformation = method.getEntityInformation();
|
MongoEntityInformation<?, ?> entityInformation = method.getEntityInformation();
|
||||||
GeoResults<?> results = mongoOperations.geoNear(nearQuery, entityInformation.getJavaType(), entityInformation.getCollectionName());
|
return (GeoResults<Object>) operations.geoNear(nearQuery, entityInformation.getJavaType(),
|
||||||
|
entityInformation.getCollectionName());
|
||||||
return isListOfGeoResult() ? results.getContent() : results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isListOfGeoResult() {
|
private boolean isListOfGeoResult() {
|
||||||
|
|
||||||
TypeInformation<?> returnType = method.getReturnType();
|
TypeInformation<?> returnType = method.getReturnType();
|
||||||
return returnType.getType().equals(List.class) && GeoResult.class.equals(returnType.getComponentType());
|
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}.
|
* @param delegate must not be {@literal null}.
|
||||||
*/
|
*/
|
||||||
public ConvertingParameterAccessor(MongoWriter<?> writer, MongoParameterAccessor delegate) {
|
public ConvertingParameterAccessor(MongoWriter<?> writer, MongoParameterAccessor delegate) {
|
||||||
|
|
||||||
Assert.notNull(writer);
|
Assert.notNull(writer);
|
||||||
Assert.notNull(delegate);
|
Assert.notNull(delegate);
|
||||||
|
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
|
|||||||
public Distance getMaxDistance() {
|
public Distance getMaxDistance() {
|
||||||
return delegate.getMaxDistance();
|
return delegate.getMaxDistance();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getGeoNearLocation()
|
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getGeoNearLocation()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,10 +17,9 @@ package org.springframework.data.mongodb.repository.query;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for components being able to provide {@link EntityInformationCreator} for a given {@link Class}.
|
* Interface for components being able to provide {@link EntityInformationCreator} for a given {@link Class}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public interface EntityInformationCreator {
|
public interface EntityInformationCreator {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public interface MongoParameterAccessor extends ParameterAccessor {
|
|||||||
* at all or the given value for it was {@literal null}.
|
* at all or the given value for it was {@literal null}.
|
||||||
*/
|
*/
|
||||||
Distance getMaxDistance();
|
Distance getMaxDistance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link Point} to use for a geo-near query.
|
* 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 final Integer distanceIndex;
|
||||||
private Integer nearIndex;
|
private Integer nearIndex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link MongoParameters} instance from the given {@link Method} and {@link MongoQueryMethod}.
|
* 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}.
|
* @param queryMethod must not be {@literal null}.
|
||||||
*/
|
*/
|
||||||
public MongoParameters(Method method, boolean isGeoNearMethod) {
|
public MongoParameters(Method method, boolean isGeoNearMethod) {
|
||||||
|
|
||||||
super(method);
|
super(method);
|
||||||
List<Class<?>> parameterTypes = Arrays.asList(method.getParameterTypes());
|
List<Class<?>> parameterTypes = Arrays.asList(method.getParameterTypes());
|
||||||
this.distanceIndex = parameterTypes.indexOf(Distance.class);
|
this.distanceIndex = parameterTypes.indexOf(Distance.class);
|
||||||
|
|
||||||
if (this.nearIndex == null && isGeoNearMethod) {
|
if (this.nearIndex == null && isGeoNearMethod) {
|
||||||
this.nearIndex = getNearIndex(parameterTypes);
|
this.nearIndex = getNearIndex(parameterTypes);
|
||||||
} else if (this.nearIndex == null) {
|
} else if (this.nearIndex == null) {
|
||||||
this.nearIndex = -1;
|
this.nearIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private final int getNearIndex(List<Class<?>> parameterTypes) {
|
private final int getNearIndex(List<Class<?>> parameterTypes) {
|
||||||
|
|
||||||
for (Class<?> reference : Arrays.asList(Point.class, double[].class)) {
|
for (Class<?> reference : Arrays.asList(Point.class, double[].class)) {
|
||||||
|
|
||||||
int nearIndex = parameterTypes.indexOf(reference);
|
int nearIndex = parameterTypes.indexOf(reference);
|
||||||
|
|
||||||
if (nearIndex == -1) {
|
if (nearIndex == -1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nearIndex == parameterTypes.lastIndexOf(reference)) {
|
if (nearIndex == parameterTypes.lastIndexOf(reference)) {
|
||||||
return nearIndex;
|
return nearIndex;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Multiple Point parameters found but none annotated with @Near!");
|
throw new IllegalStateException("Multiple Point parameters found but none annotated with @Near!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.repository.query.Parameters#createParameter(org.springframework.core.MethodParameter)
|
* @see org.springframework.data.repository.query.Parameters#createParameter(org.springframework.core.MethodParameter)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Parameter createParameter(MethodParameter parameter) {
|
protected Parameter createParameter(MethodParameter parameter) {
|
||||||
|
|
||||||
MongoParameter mongoParameter = new MongoParameter(parameter);
|
MongoParameter mongoParameter = new MongoParameter(parameter);
|
||||||
|
|
||||||
// Detect manually annotated @Near Point and reject multiple annotated ones
|
// Detect manually annotated @Near Point and reject multiple annotated ones
|
||||||
if (this.nearIndex == null && mongoParameter.isManuallyAnnotatedNearParameter()) {
|
if (this.nearIndex == null && mongoParameter.isManuallyAnnotatedNearParameter()) {
|
||||||
this.nearIndex = mongoParameter.getIndex();
|
this.nearIndex = mongoParameter.getIndex();
|
||||||
} else if (mongoParameter.isManuallyAnnotatedNearParameter()) {
|
} 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;
|
return mongoParameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +104,7 @@ public class MongoParameters extends Parameters {
|
|||||||
public int getDistanceIndex() {
|
public int getDistanceIndex() {
|
||||||
return distanceIndex;
|
return distanceIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the index of the parameter to be used to start a geo-near query from.
|
* 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() {
|
public int getNearIndex() {
|
||||||
return nearIndex;
|
return nearIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom {@link Parameter} implementation adding parameters of type {@link Distance} to the special ones.
|
* Custom {@link Parameter} implementation adding parameters of type {@link Distance} to the special ones.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
class MongoParameter extends Parameter {
|
class MongoParameter extends Parameter {
|
||||||
|
|
||||||
private final MethodParameter parameter;
|
private final MethodParameter parameter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link MongoParameter}.
|
* Creates a new {@link MongoParameter}.
|
||||||
*
|
*
|
||||||
@@ -130,7 +131,7 @@ public class MongoParameters extends Parameters {
|
|||||||
MongoParameter(MethodParameter parameter) {
|
MongoParameter(MethodParameter parameter) {
|
||||||
super(parameter);
|
super(parameter);
|
||||||
this.parameter = parameter;
|
this.parameter = parameter;
|
||||||
|
|
||||||
if (!isPoint() && hasNearAnnotation()) {
|
if (!isPoint() && hasNearAnnotation()) {
|
||||||
throw new IllegalArgumentException("Near annotation is only allowed at Point parameter!");
|
throw new IllegalArgumentException("Near annotation is only allowed at Point parameter!");
|
||||||
}
|
}
|
||||||
@@ -142,23 +143,22 @@ public class MongoParameters extends Parameters {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isSpecialParameter() {
|
public boolean isSpecialParameter() {
|
||||||
return super.isSpecialParameter() || getType().equals(Distance.class)
|
return super.isSpecialParameter() || getType().equals(Distance.class) || isNearParameter();
|
||||||
|| isNearParameter();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isNearParameter() {
|
private boolean isNearParameter() {
|
||||||
Integer nearIndex = MongoParameters.this.nearIndex;
|
Integer nearIndex = MongoParameters.this.nearIndex;
|
||||||
return nearIndex != null && nearIndex.equals(getIndex());
|
return nearIndex != null && nearIndex.equals(getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isManuallyAnnotatedNearParameter() {
|
private boolean isManuallyAnnotatedNearParameter() {
|
||||||
return isPoint() && hasNearAnnotation();
|
return isPoint() && hasNearAnnotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPoint() {
|
private boolean isPoint() {
|
||||||
return getType().equals(Point.class) || getType().equals(double[].class);
|
return getType().equals(Point.class) || getType().equals(double[].class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasNearAnnotation() {
|
private boolean hasNearAnnotation() {
|
||||||
return parameter.getParameterAnnotation(Near.class) != null;
|
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.
|
* Mongo-specific {@link ParametersParameterAccessor} to allow access to the {@link Distance} parameter.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class MongoParametersParameterAccessor extends ParametersParameterAccessor implements MongoParameterAccessor {
|
public class MongoParametersParameterAccessor extends ParametersParameterAccessor implements MongoParameterAccessor {
|
||||||
|
|
||||||
private final MongoQueryMethod method;
|
private final MongoQueryMethod method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link MongoParametersParameterAccessor}.
|
* Creates a new {@link MongoParametersParameterAccessor}.
|
||||||
*
|
*
|
||||||
@@ -47,25 +47,25 @@ public class MongoParametersParameterAccessor extends ParametersParameterAccesso
|
|||||||
int index = method.getParameters().getDistanceIndex();
|
int index = method.getParameters().getDistanceIndex();
|
||||||
return index == -1 ? null : (Distance) getValue(index);
|
return index == -1 ? null : (Distance) getValue(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getGeoNearLocation()
|
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getGeoNearLocation()
|
||||||
*/
|
*/
|
||||||
public Point getGeoNearLocation() {
|
public Point getGeoNearLocation() {
|
||||||
|
|
||||||
int nearIndex = method.getParameters().getNearIndex();
|
int nearIndex = method.getParameters().getNearIndex();
|
||||||
|
|
||||||
if (nearIndex == -1) {
|
if (nearIndex == -1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object value = getValue(nearIndex);
|
Object value = getValue(nearIndex);
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof double[]) {
|
if (value instanceof double[]) {
|
||||||
double[] typedValue = (double[]) value;
|
double[] typedValue = (double[]) value;
|
||||||
if (typedValue.length != 2) {
|
if (typedValue.length != 2) {
|
||||||
@@ -74,7 +74,7 @@ public class MongoParametersParameterAccessor extends ParametersParameterAccesso
|
|||||||
return new Point(typedValue[0], typedValue[1]);
|
return new Point(typedValue[0], typedValue[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (Point) value;
|
return (Point) value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import org.springframework.data.mongodb.core.geo.Shape;
|
|||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
import org.springframework.data.mongodb.core.query.Criteria;
|
import org.springframework.data.mongodb.core.query.Criteria;
|
||||||
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
|
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
|
||||||
import org.springframework.data.mongodb.core.query.OrQuery;
|
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
import org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor.PotentiallyConvertingIterator;
|
import org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor.PotentiallyConvertingIterator;
|
||||||
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||||
@@ -45,7 +44,7 @@ import org.springframework.util.Assert;
|
|||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
||||||
|
|
||||||
private static final Log LOG = LogFactory.getLog(MongoQueryCreator.class);
|
private static final Log LOG = LogFactory.getLog(MongoQueryCreator.class);
|
||||||
private final MongoParameterAccessor accessor;
|
private final MongoParameterAccessor accessor;
|
||||||
@@ -92,7 +91,7 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
|||||||
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#create(org.springframework.data.repository.query.parser.Part, java.util.Iterator)
|
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#create(org.springframework.data.repository.query.parser.Part, java.util.Iterator)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Query create(Part part, Iterator<Object> iterator) {
|
protected Criteria create(Part part, Iterator<Object> iterator) {
|
||||||
|
|
||||||
if (isGeoNearQuery && part.getType().equals(Type.NEAR)) {
|
if (isGeoNearQuery && part.getType().equals(Type.NEAR)) {
|
||||||
return null;
|
return null;
|
||||||
@@ -103,7 +102,7 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
|||||||
where(path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)),
|
where(path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)),
|
||||||
(PotentiallyConvertingIterator) iterator);
|
(PotentiallyConvertingIterator) iterator);
|
||||||
|
|
||||||
return new Query(criteria);
|
return criteria;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -111,18 +110,18 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
|||||||
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#and(org.springframework.data.repository.query.parser.Part, java.lang.Object, java.util.Iterator)
|
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#and(org.springframework.data.repository.query.parser.Part, java.lang.Object, java.util.Iterator)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Query and(Part part, Query base, Iterator<Object> iterator) {
|
protected Criteria and(Part part, Criteria base, Iterator<Object> iterator) {
|
||||||
|
|
||||||
if (base == null) {
|
if (base == null) {
|
||||||
return create(part, iterator);
|
return create(part, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
PersistentPropertyPath<MongoPersistentProperty> path2 = context.getPersistentPropertyPath(part.getProperty());
|
PersistentPropertyPath<MongoPersistentProperty> path = context.getPersistentPropertyPath(part.getProperty());
|
||||||
|
|
||||||
Criteria criteria = from(part.getType(),
|
return new Criteria().andOperator(
|
||||||
where(path2.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)),
|
base,
|
||||||
(PotentiallyConvertingIterator) iterator);
|
from(part.getType(), where(path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)),
|
||||||
return base.addCriteria(criteria);
|
(PotentiallyConvertingIterator) iterator));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -133,8 +132,10 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
|||||||
* #or(java.lang.Object, java.lang.Object)
|
* #or(java.lang.Object, java.lang.Object)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Query or(Query base, Query query) {
|
protected Criteria or(Criteria base, Criteria criteria) {
|
||||||
return new OrQuery(new Query[] { base, query });
|
|
||||||
|
Criteria result = new Criteria();
|
||||||
|
return result.orOperator(base, criteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -145,16 +146,17 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
|||||||
* #complete(java.lang.Object, org.springframework.data.domain.Sort)
|
* #complete(java.lang.Object, org.springframework.data.domain.Sort)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Query complete(Query query, Sort sort) {
|
protected Query complete(Criteria criteria, Sort sort) {
|
||||||
|
|
||||||
if (query == null) {
|
if (criteria == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Query query = new Query(criteria);
|
||||||
QueryUtils.applySorting(query, sort);
|
QueryUtils.applySorting(query, sort);
|
||||||
|
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("Created query " + query.getQueryObject());
|
LOG.debug("Created query " + query);
|
||||||
}
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
@@ -203,7 +205,8 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
|||||||
case NEAR:
|
case NEAR:
|
||||||
|
|
||||||
Distance distance = accessor.getMaxDistance();
|
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) {
|
if (distance == null) {
|
||||||
return criteria.near(point);
|
return criteria.near(point);
|
||||||
@@ -265,4 +268,4 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
|||||||
|
|
||||||
return source.replaceAll("\\*", ".*");
|
return source.replaceAll("\\*", ".*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ public class PartTreeMongoQuery extends AbstractMongoQuery {
|
|||||||
/**
|
/**
|
||||||
* Creates a new {@link PartTreeMongoQuery} from the given {@link QueryMethod} and {@link MongoTemplate}.
|
* Creates a new {@link PartTreeMongoQuery} from the given {@link QueryMethod} and {@link MongoTemplate}.
|
||||||
*
|
*
|
||||||
* @param method
|
* @param method must not be {@literal null}.
|
||||||
* @param template
|
* @param template must not be {@literal null}.
|
||||||
*/
|
*/
|
||||||
public PartTreeMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations) {
|
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
|
* @return the tree
|
||||||
*/
|
*/
|
||||||
public PartTree getTree() {
|
public PartTree getTree() {
|
||||||
@@ -57,16 +59,22 @@ public class PartTreeMongoQuery extends AbstractMongoQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery#createQuery(org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor, boolean)
|
||||||
* @see
|
*/
|
||||||
* org.springframework.data.mongodb.repository.AbstractMongoQuery#createQuery(org.springframework.data.
|
|
||||||
* document.mongodb.repository.ConvertingParameterAccessor)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected Query createQuery(ConvertingParameterAccessor accessor) {
|
protected Query createQuery(ConvertingParameterAccessor accessor) {
|
||||||
|
|
||||||
MongoQueryCreator creator = new MongoQueryCreator(tree, accessor, context, isGeoNearQuery);
|
MongoQueryCreator creator = new MongoQueryCreator(tree, accessor, context, isGeoNearQuery);
|
||||||
return creator.createQuery();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,12 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.bson.types.ObjectId;
|
|
||||||
import org.springframework.data.mongodb.core.MongoOperations;
|
import org.springframework.data.mongodb.core.MongoOperations;
|
||||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
|
|
||||||
|
import com.mongodb.util.JSON;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query to use a plain JSON String to create the {@link Query} to actually execute.
|
* Query to use a plain JSON String to create the {@link Query} to actually execute.
|
||||||
*
|
*
|
||||||
@@ -55,12 +56,9 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery#createQuery(org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor)
|
||||||
* @see
|
*/
|
||||||
* org.springframework.data.mongodb.repository.AbstractMongoQuery#createQuery(org.springframework.data.
|
|
||||||
* repository.query.SimpleParameterAccessor, org.springframework.data.mongodb.core.core.support.convert.MongoConverter)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected Query createQuery(ConvertingParameterAccessor accessor) {
|
protected Query createQuery(ConvertingParameterAccessor accessor) {
|
||||||
|
|
||||||
@@ -74,7 +72,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
|||||||
} else {
|
} else {
|
||||||
query = new BasicQuery(queryString);
|
query = new BasicQuery(queryString);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryUtils.applySorting(query, accessor.getSort());
|
QueryUtils.applySorting(query, accessor.getSort());
|
||||||
|
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
@@ -99,13 +97,6 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getParameterWithIndex(ConvertingParameterAccessor accessor, int index) {
|
private String getParameterWithIndex(ConvertingParameterAccessor accessor, int index) {
|
||||||
Object parameter = accessor.getBindableValue(index);
|
return JSON.serialize(accessor.getBindableValue(index));
|
||||||
if (parameter instanceof String || parameter.getClass().isEnum()) {
|
|
||||||
return String.format("\"%s\"", parameter);
|
|
||||||
} else if (parameter instanceof ObjectId) {
|
|
||||||
return String.format("{ '$oid' : '%s' }", parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameter.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
|||||||
import org.springframework.util.Assert;
|
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
|
* @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 Set<Type> GEOSPATIAL_TYPES = new HashSet<Type>(Arrays.asList(Type.NEAR, Type.WITHIN));
|
||||||
private static final Log LOG = LogFactory.getLog(IndexEnsuringQueryCreationListener.class);
|
private static final Log LOG = LogFactory.getLog(IndexEnsuringQueryCreationListener.class);
|
||||||
|
|
||||||
private final MongoOperations operations;
|
private final MongoOperations operations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ package org.springframework.data.mongodb.repository.support;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
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.mongodb.repository.MongoRepository;
|
||||||
import org.springframework.data.repository.Repository;
|
import org.springframework.data.repository.Repository;
|
||||||
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
|
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
|
public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends
|
||||||
RepositoryFactoryBeanSupport<T, S, ID> {
|
RepositoryFactoryBeanSupport<T, S, ID> {
|
||||||
|
|
||||||
private MongoTemplate template;
|
private MongoOperations operations;
|
||||||
private boolean createIndexesForQueryMethods = false;
|
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
|
@Override
|
||||||
protected final RepositoryFactorySupport createRepositoryFactory() {
|
protected final RepositoryFactorySupport createRepositoryFactory() {
|
||||||
|
|
||||||
RepositoryFactorySupport factory = getFactoryInstance(template);
|
RepositoryFactorySupport factory = getFactoryInstance(operations);
|
||||||
|
|
||||||
if (createIndexesForQueryMethods) {
|
if (createIndexesForQueryMethods) {
|
||||||
factory.addQueryCreationListener(new IndexEnsuringQueryCreationListener(template));
|
factory.addQueryCreationListener(new IndexEnsuringQueryCreationListener(operations));
|
||||||
}
|
}
|
||||||
|
|
||||||
return factory;
|
return factory;
|
||||||
@@ -76,11 +76,11 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
|
|||||||
/**
|
/**
|
||||||
* Creates and initializes a {@link RepositoryFactorySupport} instance.
|
* Creates and initializes a {@link RepositoryFactorySupport} instance.
|
||||||
*
|
*
|
||||||
* @param template
|
* @param operations
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected RepositoryFactorySupport getFactoryInstance(MongoTemplate template) {
|
protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {
|
||||||
return new MongoRepositoryFactory(template);
|
return new MongoRepositoryFactory(operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -94,6 +94,6 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
|
|||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
|
|
||||||
super.afterPropertiesSet();
|
super.afterPropertiesSet();
|
||||||
Assert.notNull(template, "MongoTemplate must not be null!");
|
Assert.notNull(operations, "MongoTemplate must not be null!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.springframework.data.domain.Sort.Order;
|
|||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.data.mongodb.core.MongoOperations;
|
import org.springframework.data.mongodb.core.MongoOperations;
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
|
import org.springframework.data.mongodb.core.QueryMapper;
|
||||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
@@ -235,6 +236,7 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
|||||||
|
|
||||||
private final MongoConverter converter;
|
private final MongoConverter converter;
|
||||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||||
|
private final QueryMapper mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link SpringDataMongodbSerializer} for the given {@link MappingContext}.
|
* Creates a new {@link SpringDataMongodbSerializer} for the given {@link MappingContext}.
|
||||||
@@ -244,6 +246,7 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
|||||||
public SpringDataMongodbSerializer(MongoConverter converter) {
|
public SpringDataMongodbSerializer(MongoConverter converter) {
|
||||||
this.mappingContext = converter.getMappingContext();
|
this.mappingContext = converter.getMappingContext();
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
|
this.mapper = new QueryMapper(converter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -252,12 +255,16 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
|||||||
Path<?> parent = metadata.getParent();
|
Path<?> parent = metadata.getParent();
|
||||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(parent.getType());
|
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(parent.getType());
|
||||||
MongoPersistentProperty property = entity.getPersistentProperty(metadata.getExpression().toString());
|
MongoPersistentProperty property = entity.getPersistentProperty(metadata.getExpression().toString());
|
||||||
return property.getFieldName();
|
return property == null ? super.getKeyForPath(expr, metadata) : property.getFieldName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DBObject asDBObject(String key, Object value) {
|
protected DBObject asDBObject(String key, Object value) {
|
||||||
|
|
||||||
|
if ("_id".equals(key)) {
|
||||||
|
return super.asDBObject(key, mapper.convertId(value));
|
||||||
|
}
|
||||||
|
|
||||||
return super.asDBObject(key, value instanceof Pattern ? value : converter.convertToMongoType(value));
|
return super.asDBObject(key, value instanceof Pattern ? value : converter.convertToMongoType(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,12 +61,10 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Object)
|
||||||
* @see
|
|
||||||
* org.springframework.data.repository.Repository#save(java.lang.Object)
|
|
||||||
*/
|
*/
|
||||||
public T save(T entity) {
|
public T save(T entity) {
|
||||||
|
|
||||||
Assert.notNull(entity, "Entity must not be null!");
|
Assert.notNull(entity, "Entity must not be null!");
|
||||||
|
|
||||||
mongoOperations.save(entity, entityInformation.getCollectionName());
|
mongoOperations.save(entity, entityInformation.getCollectionName());
|
||||||
@@ -75,14 +73,12 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
|
||||||
* @see
|
|
||||||
* org.springframework.data.repository.Repository#save(java.lang.Iterable)
|
|
||||||
*/
|
*/
|
||||||
public List<T> save(Iterable<? extends T> entities) {
|
public List<T> save(Iterable<? extends T> entities) {
|
||||||
|
|
||||||
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
||||||
|
|
||||||
List<T> result = new ArrayList<T>();
|
List<T> result = new ArrayList<T>();
|
||||||
|
|
||||||
for (T entity : entities) {
|
for (T entity : entities) {
|
||||||
@@ -95,10 +91,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable)
|
||||||
* @see
|
|
||||||
* org.springframework.data.repository.Repository#findById(java.io.Serializable
|
|
||||||
* )
|
|
||||||
*/
|
*/
|
||||||
public T findOne(ID id) {
|
public T findOne(ID id) {
|
||||||
Assert.notNull(id, "The given id must not be null!");
|
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)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.repository.CrudRepository#exists(java.io.Serializable)
|
||||||
* @see
|
|
||||||
* org.springframework.data.repository.Repository#exists(java.io.Serializable
|
|
||||||
* )
|
|
||||||
*/
|
*/
|
||||||
public boolean exists(ID id) {
|
public boolean exists(ID id) {
|
||||||
|
|
||||||
@@ -129,8 +119,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.repository.CrudRepository#count()
|
||||||
* @see org.springframework.data.repository.Repository#count()
|
|
||||||
*/
|
*/
|
||||||
public long count() {
|
public long count() {
|
||||||
|
|
||||||
@@ -139,7 +128,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (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) {
|
public void delete(ID id) {
|
||||||
Assert.notNull(id, "The given id must not be null!");
|
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)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.repository.CrudRepository#delete(java.lang.Object)
|
||||||
* @see
|
|
||||||
* org.springframework.data.repository.Repository#delete(java.lang.Object)
|
|
||||||
*/
|
*/
|
||||||
public void delete(T entity) {
|
public void delete(T entity) {
|
||||||
Assert.notNull(entity, "The given entity must not be null!");
|
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)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.repository.CrudRepository#delete(java.lang.Iterable)
|
||||||
* @see
|
|
||||||
* org.springframework.data.repository.Repository#delete(java.lang.Iterable)
|
|
||||||
*/
|
*/
|
||||||
public void delete(Iterable<? extends T> entities) {
|
public void delete(Iterable<? extends T> entities) {
|
||||||
|
|
||||||
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
||||||
|
|
||||||
for (T entity : entities) {
|
for (T entity : entities) {
|
||||||
delete(entity);
|
delete(entity);
|
||||||
}
|
}
|
||||||
@@ -174,8 +159,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.repository.CrudRepository#deleteAll()
|
||||||
* @see org.springframework.data.repository.Repository#deleteAll()
|
|
||||||
*/
|
*/
|
||||||
public void deleteAll() {
|
public void deleteAll() {
|
||||||
|
|
||||||
@@ -184,8 +168,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.data.repository.CrudRepository#findAll()
|
||||||
* @see org.springframework.data.repository.Repository#findAll()
|
|
||||||
*/
|
*/
|
||||||
public List<T> findAll() {
|
public List<T> findAll() {
|
||||||
|
|
||||||
@@ -194,10 +177,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (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) {
|
public Page<T> findAll(final Pageable pageable) {
|
||||||
|
|
||||||
@@ -209,43 +189,13 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (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) {
|
public List<T> findAll(final Sort sort) {
|
||||||
|
|
||||||
return findAll(QueryUtils.applySorting(new Query(), 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) {
|
private List<T> findAll(Query query) {
|
||||||
|
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
|
|||||||
@@ -7,16 +7,14 @@
|
|||||||
xmlns:context="http://www.springframework.org/schema/context"
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
xmlns:repository="http://www.springframework.org/schema/data/repository"
|
xmlns:repository="http://www.springframework.org/schema/data/repository"
|
||||||
targetNamespace="http://www.springframework.org/schema/data/mongo"
|
targetNamespace="http://www.springframework.org/schema/data/mongo"
|
||||||
elementFormDefault="qualified" attributeFormDefault="unqualified"
|
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
||||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
|
||||||
|
|
||||||
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
|
<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/tool" />
|
||||||
<xsd:import namespace="http://www.springframework.org/schema/context"
|
<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"
|
<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-1.0.xsd" />
|
||||||
|
|
||||||
<xsd:element name="mongo" type="mongoType">
|
<xsd:element name="mongo" type="mongoType">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
@@ -46,8 +44,9 @@ The name of the mongo definition (by default "mongoDbFactory").]]></xsd:document
|
|||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
|
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation>
|
<xsd:documentation><![CDATA[
|
||||||
The reference to a Mongo. Will default to 'mongo'.
|
The reference to a Mongo instance. If not configured a default com.mongodb.Mongo instance will be created.
|
||||||
|
]]>
|
||||||
</xsd:documentation>
|
</xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
|||||||
@@ -42,10 +42,9 @@ import com.mongodb.DBObject;
|
|||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class MappingMongoConverterParserIntegrationTests {
|
public class MappingMongoConverterParserIntegrationTests {
|
||||||
|
|
||||||
DefaultListableBeanFactory factory;
|
DefaultListableBeanFactory factory;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
factory = new DefaultListableBeanFactory();
|
factory = new DefaultListableBeanFactory();
|
||||||
@@ -55,26 +54,26 @@ public class MappingMongoConverterParserIntegrationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void allowsDbFactoryRefAttribute() {
|
public void allowsDbFactoryRefAttribute() {
|
||||||
|
|
||||||
factory.getBeanDefinition("converter");
|
factory.getBeanDefinition("converter");
|
||||||
factory.getBean("converter");
|
factory.getBean("converter");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void scansForConverterAndSetsUpCustomConversionsAccordingly() {
|
public void scansForConverterAndSetsUpCustomConversionsAccordingly() {
|
||||||
|
|
||||||
CustomConversions conversions = factory.getBean(CustomConversions.class);
|
CustomConversions conversions = factory.getBean(CustomConversions.class);
|
||||||
assertThat(conversions.hasCustomWriteTarget(Person.class), is(true));
|
assertThat(conversions.hasCustomWriteTarget(Person.class), is(true));
|
||||||
assertThat(conversions.hasCustomWriteTarget(Account.class), is(true));
|
assertThat(conversions.hasCustomWriteTarget(Account.class), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public static class SampleConverter implements Converter<Person, DBObject> {
|
public static class SampleConverter implements Converter<Person, DBObject> {
|
||||||
public DBObject convert(Person source) {
|
public DBObject convert(Person source) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public static class SampleConverterFactory implements GenericConverter {
|
public static class SampleConverterFactory implements GenericConverter {
|
||||||
|
|
||||||
|
|||||||
@@ -29,17 +29,17 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration tests for {@link MongoDbFactory}.
|
* Integration tests for {@link MongoDbFactory}.
|
||||||
*
|
*
|
||||||
* @author Thomas Risbergf
|
* @author Thomas Risbergf
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration
|
@ContextConfiguration
|
||||||
public class MongoDbFactoryNoDatabaseRunningTests {
|
public class MongoDbFactoryNoDatabaseRunningTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
MongoTemplate mongoTemplate;
|
MongoTemplate mongoTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DATADOC-139
|
* @see DATADOC-139
|
||||||
*/
|
*/
|
||||||
@@ -47,7 +47,7 @@ public class MongoDbFactoryNoDatabaseRunningTests {
|
|||||||
public void startsUpWithoutADatabaseRunning() {
|
public void startsUpWithoutADatabaseRunning() {
|
||||||
assertThat(mongoTemplate.getClass().getName(), is("org.springframework.data.mongodb.core.MongoTemplate"));
|
assertThat(mongoTemplate.getClass().getName(), is("org.springframework.data.mongodb.core.MongoTemplate"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DataAccessResourceFailureException.class)
|
@Test(expected = DataAccessResourceFailureException.class)
|
||||||
public void failsDataAccessWithoutADatabaseRunning() {
|
public void failsDataAccessWithoutADatabaseRunning() {
|
||||||
mongoTemplate.getCollectionNames();
|
mongoTemplate.getCollectionNames();
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
|||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.data.mongodb.MongoDbFactory;
|
import org.springframework.data.mongodb.MongoDbFactory;
|
||||||
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
import com.mongodb.DB;
|
import com.mongodb.DB;
|
||||||
import com.mongodb.Mongo;
|
import com.mongodb.Mongo;
|
||||||
@@ -40,14 +41,14 @@ import com.mongodb.WriteConcern;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration tests for {@link MongoDbFactoryParser}.
|
* Integration tests for {@link MongoDbFactoryParser}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class MongoDbFactoryParserIntegrationTests {
|
public class MongoDbFactoryParserIntegrationTests {
|
||||||
|
|
||||||
DefaultListableBeanFactory factory;
|
DefaultListableBeanFactory factory;
|
||||||
BeanDefinitionReader reader;
|
BeanDefinitionReader reader;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
factory = new DefaultListableBeanFactory();
|
factory = new DefaultListableBeanFactory();
|
||||||
@@ -59,112 +60,112 @@ public class MongoDbFactoryParserIntegrationTests {
|
|||||||
SimpleMongoDbFactory dbFactory = new SimpleMongoDbFactory(new Mongo("localhost"), "database");
|
SimpleMongoDbFactory dbFactory = new SimpleMongoDbFactory(new Mongo("localhost"), "database");
|
||||||
dbFactory.setWriteConcern(WriteConcern.SAFE);
|
dbFactory.setWriteConcern(WriteConcern.SAFE);
|
||||||
dbFactory.getDb();
|
dbFactory.getDb();
|
||||||
assertThat(WriteConcern.SAFE, is(dbFactory.getWriteConcern()));
|
assertThat(ReflectionTestUtils.getField(dbFactory, "writeConcern"), is((Object) WriteConcern.SAFE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parsesWriteConcern() {
|
public void parsesWriteConcern() {
|
||||||
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("namespace/db-factory-bean.xml");
|
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("namespace/db-factory-bean.xml");
|
||||||
assertWriteConcern(ctx, WriteConcern.SAFE);
|
assertWriteConcern(ctx, WriteConcern.SAFE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parsesCustomWriteConcern() {
|
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"));
|
assertWriteConcern(ctx, new WriteConcern("rack1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DATAMONGO-331
|
* @see DATAMONGO-331
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void readsReplicasWriteConcernCorrectly() {
|
public void readsReplicasWriteConcernCorrectly() {
|
||||||
|
|
||||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("namespace/db-factory-bean-custom-write-concern.xml");
|
ApplicationContext ctx = new ClassPathXmlApplicationContext("namespace/db-factory-bean-custom-write-concern.xml");
|
||||||
MongoDbFactory factory = ctx.getBean("second", MongoDbFactory.class);
|
MongoDbFactory factory = ctx.getBean("second", MongoDbFactory.class);
|
||||||
DB db = factory.getDb();
|
DB db = factory.getDb();
|
||||||
|
|
||||||
assertThat(db.getWriteConcern(), is(WriteConcern.REPLICAS_SAFE));
|
assertThat(db.getWriteConcern(), is(WriteConcern.REPLICAS_SAFE));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertWriteConcern(ClassPathXmlApplicationContext ctx, WriteConcern expectedWriteConcern) {
|
private void assertWriteConcern(ClassPathXmlApplicationContext ctx, WriteConcern expectedWriteConcern) {
|
||||||
SimpleMongoDbFactory dbFactory = ctx.getBean("first", SimpleMongoDbFactory.class);
|
SimpleMongoDbFactory dbFactory = ctx.getBean("first", SimpleMongoDbFactory.class);
|
||||||
DB db = dbFactory.getDb();
|
DB db = dbFactory.getDb();
|
||||||
assertThat("db", is(db.getName()));
|
assertThat(db.getName(), is("db"));
|
||||||
|
|
||||||
MyWriteConcern myDbFactoryWriteConcern = new MyWriteConcern(dbFactory.getWriteConcern());
|
WriteConcern configuredConcern = (WriteConcern) ReflectionTestUtils.getField(dbFactory, "writeConcern");
|
||||||
|
|
||||||
|
MyWriteConcern myDbFactoryWriteConcern = new MyWriteConcern(configuredConcern);
|
||||||
MyWriteConcern myDbWriteConcern = new MyWriteConcern(db.getWriteConcern());
|
MyWriteConcern myDbWriteConcern = new MyWriteConcern(db.getWriteConcern());
|
||||||
MyWriteConcern myExpectedWriteConcern = new MyWriteConcern(expectedWriteConcern);
|
MyWriteConcern myExpectedWriteConcern = new MyWriteConcern(expectedWriteConcern);
|
||||||
|
|
||||||
|
assertThat(myDbFactoryWriteConcern, is(myExpectedWriteConcern));
|
||||||
assertThat(myDbFactoryWriteConcern, equalTo(myExpectedWriteConcern));
|
assertThat(myDbWriteConcern, is(myExpectedWriteConcern));
|
||||||
assertThat(myDbWriteConcern, equalTo(myExpectedWriteConcern));
|
assertThat(myDbWriteConcern, is(myDbFactoryWriteConcern));
|
||||||
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() {
|
public void testWriteConcernEquality() {
|
||||||
String s1 = new String("rack1");
|
String s1 = new String("rack1");
|
||||||
String s2 = new String("rack1");
|
String s2 = new String("rack1");
|
||||||
WriteConcern wc1 = new WriteConcern(s1);
|
WriteConcern wc1 = new WriteConcern(s1);
|
||||||
WriteConcern wc2 = new WriteConcern(s2);
|
WriteConcern wc2 = new WriteConcern(s2);
|
||||||
assertThat(wc1, equalTo(wc2));
|
assertThat(wc1, is(wc2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createsDbFactoryBean() {
|
public void createsDbFactoryBean() {
|
||||||
|
|
||||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/db-factory-bean.xml"));
|
reader.loadBeanDefinitions(new ClassPathResource("namespace/db-factory-bean.xml"));
|
||||||
factory.getBean("first");
|
factory.getBean("first");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DATADOC-280
|
* @see DATADOC-280
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void parsesMaxAutoConnectRetryTimeCorrectly() {
|
public void parsesMaxAutoConnectRetryTimeCorrectly() {
|
||||||
|
|
||||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/db-factory-bean.xml"));
|
reader.loadBeanDefinitions(new ClassPathResource("namespace/db-factory-bean.xml"));
|
||||||
Mongo mongo = factory.getBean(Mongo.class);
|
Mongo mongo = factory.getBean(Mongo.class);
|
||||||
assertThat(mongo.getMongoOptions().maxAutoConnectRetryTime, is(27L));
|
assertThat(mongo.getMongoOptions().maxAutoConnectRetryTime, is(27L));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DATADOC-295
|
* @see DATADOC-295
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void setsUpMongoDbFactoryUsingAMongoUri() {
|
public void setsUpMongoDbFactoryUsingAMongoUri() {
|
||||||
|
|
||||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/mongo-uri.xml"));
|
reader.loadBeanDefinitions(new ClassPathResource("namespace/mongo-uri.xml"));
|
||||||
BeanDefinition definition = factory.getBeanDefinition("mongoDbFactory");
|
BeanDefinition definition = factory.getBeanDefinition("mongoDbFactory");
|
||||||
ConstructorArgumentValues constructorArguments = definition.getConstructorArgumentValues();
|
ConstructorArgumentValues constructorArguments = definition.getConstructorArgumentValues();
|
||||||
|
|
||||||
assertThat(constructorArguments.getArgumentCount(), is(1));
|
assertThat(constructorArguments.getArgumentCount(), is(1));
|
||||||
ValueHolder argument = constructorArguments.getArgumentValue(0, MongoURI.class);
|
ValueHolder argument = constructorArguments.getArgumentValue(0, MongoURI.class);
|
||||||
assertThat(argument, is(notNullValue()));
|
assertThat(argument, is(notNullValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DATADOC-306
|
* @see DATADOC-306
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void setsUpMongoDbFactoryUsingAMongoUriWithoutCredentials() {
|
public void setsUpMongoDbFactoryUsingAMongoUriWithoutCredentials() {
|
||||||
|
|
||||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/mongo-uri-no-credentials.xml"));
|
reader.loadBeanDefinitions(new ClassPathResource("namespace/mongo-uri-no-credentials.xml"));
|
||||||
BeanDefinition definition = factory.getBeanDefinition("mongoDbFactory");
|
BeanDefinition definition = factory.getBeanDefinition("mongoDbFactory");
|
||||||
ConstructorArgumentValues constructorArguments = definition.getConstructorArgumentValues();
|
ConstructorArgumentValues constructorArguments = definition.getConstructorArgumentValues();
|
||||||
|
|
||||||
assertThat(constructorArguments.getArgumentCount(), is(1));
|
assertThat(constructorArguments.getArgumentCount(), is(1));
|
||||||
ValueHolder argument = constructorArguments.getArgumentValue(0, MongoURI.class);
|
ValueHolder argument = constructorArguments.getArgumentValue(0, MongoURI.class);
|
||||||
assertThat(argument, is(notNullValue()));
|
assertThat(argument, is(notNullValue()));
|
||||||
|
|
||||||
MongoDbFactory dbFactory = factory.getBean("mongoDbFactory", MongoDbFactory.class);
|
MongoDbFactory dbFactory = factory.getBean("mongoDbFactory", MongoDbFactory.class);
|
||||||
DB db = dbFactory.getDb();
|
DB db = dbFactory.getDb();
|
||||||
assertThat(db.getName(), is("database"));
|
assertThat(db.getName(), is("database"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DATADOC-295
|
* @see DATADOC-295
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 the original author or authors.
|
* Copyright 2011-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.springframework.data.mongodb.config;
|
package org.springframework.data.mongodb.config;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -29,6 +30,7 @@ import org.springframework.data.mongodb.core.MongoFactoryBean;
|
|||||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
import com.mongodb.CommandResult;
|
import com.mongodb.CommandResult;
|
||||||
import com.mongodb.Mongo;
|
import com.mongodb.Mongo;
|
||||||
@@ -36,47 +38,45 @@ import com.mongodb.ServerAddress;
|
|||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration
|
@ContextConfiguration
|
||||||
public class MongoNamespaceReplicaSetTests extends NamespaceTestSupport {
|
public class MongoNamespaceReplicaSetTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApplicationContext ctx;
|
private ApplicationContext ctx;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public void testParsingMongoWithReplicaSets() throws Exception {
|
public void testParsingMongoWithReplicaSets() throws Exception {
|
||||||
|
|
||||||
assertTrue(ctx.containsBean("replicaSetMongo"));
|
assertTrue(ctx.containsBean("replicaSetMongo"));
|
||||||
MongoFactoryBean mfb = (MongoFactoryBean) ctx.getBean("&replicaSetMongo");
|
MongoFactoryBean mfb = (MongoFactoryBean) ctx.getBean("&replicaSetMongo");
|
||||||
|
|
||||||
List<ServerAddress> replicaSetSeeds = readField("replicaSetSeeds", mfb);
|
List<ServerAddress> replicaSetSeeds = (List<ServerAddress>) ReflectionTestUtils.getField(mfb, "replicaSetSeeds");
|
||||||
assertNotNull(replicaSetSeeds);
|
|
||||||
|
|
||||||
assertEquals("127.0.0.1", replicaSetSeeds.get(0).getHost());
|
|
||||||
assertEquals(10001, replicaSetSeeds.get(0).getPort());
|
|
||||||
|
|
||||||
assertEquals("localhost", replicaSetSeeds.get(1).getHost());
|
|
||||||
assertEquals(10002, replicaSetSeeds.get(1).getPort());
|
|
||||||
|
|
||||||
|
assertThat(replicaSetSeeds, is(notNullValue()));
|
||||||
|
assertThat(replicaSetSeeds, hasItems(new ServerAddress("127.0.0.1", 10001), new ServerAddress("localhost", 10002)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public void testParsingWithPropertyPlaceHolder() throws Exception {
|
public void testParsingWithPropertyPlaceHolder() throws Exception {
|
||||||
|
|
||||||
assertTrue(ctx.containsBean("manyReplicaSetMongo"));
|
assertTrue(ctx.containsBean("manyReplicaSetMongo"));
|
||||||
MongoFactoryBean mfb = (MongoFactoryBean) ctx.getBean("&manyReplicaSetMongo");
|
MongoFactoryBean mfb = (MongoFactoryBean) ctx.getBean("&manyReplicaSetMongo");
|
||||||
|
|
||||||
List<ServerAddress> replicaSetSeeds = readField("replicaSetSeeds", mfb);
|
List<ServerAddress> replicaSetSeeds = (List<ServerAddress>) ReflectionTestUtils.getField(mfb, "replicaSetSeeds");
|
||||||
assertNotNull(replicaSetSeeds);
|
|
||||||
|
|
||||||
assertEquals("192.168.174.130", replicaSetSeeds.get(0).getHost());
|
|
||||||
assertEquals(27017, replicaSetSeeds.get(0).getPort());
|
|
||||||
assertEquals("192.168.174.130", replicaSetSeeds.get(1).getHost());
|
|
||||||
assertEquals(27018, replicaSetSeeds.get(1).getPort());
|
|
||||||
assertEquals("192.168.174.130", replicaSetSeeds.get(2).getHost());
|
|
||||||
assertEquals(27019, replicaSetSeeds.get(2).getPort());
|
|
||||||
|
|
||||||
|
assertThat(replicaSetSeeds, is(notNullValue()));
|
||||||
|
assertThat(replicaSetSeeds, hasSize(3));
|
||||||
|
assertThat(
|
||||||
|
replicaSetSeeds,
|
||||||
|
hasItems(new ServerAddress("192.168.174.130", 27017), new ServerAddress("192.168.174.130", 27018),
|
||||||
|
new ServerAddress("192.168.174.130", 27019)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore("CI infrastructure does not yet support replica sets")
|
@Ignore("CI infrastructure does not yet support replica sets")
|
||||||
public void testMongoWithReplicaSets() {
|
public void testMongoWithReplicaSets() {
|
||||||
|
|
||||||
Mongo mongo = ctx.getBean(Mongo.class);
|
Mongo mongo = ctx.getBean(Mongo.class);
|
||||||
assertEquals(2, mongo.getAllAddress().size());
|
assertEquals(2, mongo.getAllAddress().size());
|
||||||
List<ServerAddress> servers = mongo.getAllAddress();
|
List<ServerAddress> servers = mongo.getAllAddress();
|
||||||
@@ -88,6 +88,5 @@ public class MongoNamespaceReplicaSetTests extends NamespaceTestSupport {
|
|||||||
MongoTemplate template = new MongoTemplate(mongo, "admin");
|
MongoTemplate template = new MongoTemplate(mongo, "admin");
|
||||||
CommandResult result = template.executeCommand("{replSetGetStatus : 1}");
|
CommandResult result = template.executeCommand("{replSetGetStatus : 1}");
|
||||||
assertEquals("blort", result.getString("set"));
|
assertEquals("blort", result.getString("set"));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,17 +16,19 @@
|
|||||||
|
|
||||||
package org.springframework.data.mongodb.config;
|
package org.springframework.data.mongodb.config;
|
||||||
|
|
||||||
import static org.springframework.test.util.ReflectionTestUtils.*;
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import static org.springframework.test.util.ReflectionTestUtils.*;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.data.authentication.UserCredentials;
|
||||||
import org.springframework.data.mongodb.MongoDbFactory;
|
import org.springframework.data.mongodb.MongoDbFactory;
|
||||||
import org.springframework.data.mongodb.core.MongoFactoryBean;
|
import org.springframework.data.mongodb.core.MongoFactoryBean;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
import com.mongodb.Mongo;
|
import com.mongodb.Mongo;
|
||||||
import com.mongodb.MongoOptions;
|
import com.mongodb.MongoOptions;
|
||||||
|
|
||||||
@@ -62,8 +64,7 @@ public class MongoNamespaceTests {
|
|||||||
Mongo mongo = (Mongo) getField(dbf, "mongo");
|
Mongo mongo = (Mongo) getField(dbf, "mongo");
|
||||||
assertEquals("localhost", mongo.getAddress().getHost());
|
assertEquals("localhost", mongo.getAddress().getHost());
|
||||||
assertEquals(27017, mongo.getAddress().getPort());
|
assertEquals(27017, mongo.getAddress().getPort());
|
||||||
assertEquals("joe", getField(dbf, "username"));
|
assertEquals(new UserCredentials("joe", "secret"), getField(dbf, "credentials"));
|
||||||
assertEquals("secret", getField(dbf, "password"));
|
|
||||||
assertEquals("database", getField(dbf, "databaseName"));
|
assertEquals("database", getField(dbf, "databaseName"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package org.springframework.data.mongodb.config;
|
|||||||
import com.mongodb.WriteConcern;
|
import com.mongodb.WriteConcern;
|
||||||
|
|
||||||
public class MyWriteConcern {
|
public class MyWriteConcern {
|
||||||
|
|
||||||
public MyWriteConcern(WriteConcern wc) {
|
public MyWriteConcern(WriteConcern wc) {
|
||||||
this._w = wc.getWObject();
|
this._w = wc.getWObject();
|
||||||
this._continueOnErrorForInsert = wc.getContinueOnErrorForInsert();
|
this._continueOnErrorForInsert = wc.getContinueOnErrorForInsert();
|
||||||
@@ -12,11 +12,12 @@ public class MyWriteConcern {
|
|||||||
this._wtimeout = wc.getWtimeout();
|
this._wtimeout = wc.getWtimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
Object _w = 0;
|
Object _w = 0;
|
||||||
int _wtimeout = 0;
|
int _wtimeout = 0;
|
||||||
boolean _fsync = false;
|
boolean _fsync = false;
|
||||||
boolean _j = false;
|
boolean _j = false;
|
||||||
boolean _continueOnErrorForInsert = false;
|
boolean _continueOnErrorForInsert = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
@@ -28,6 +29,7 @@ public class MyWriteConcern {
|
|||||||
result = prime * result + _wtimeout;
|
result = prime * result + _wtimeout;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
@@ -52,5 +54,5 @@ public class MyWriteConcern {
|
|||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 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.config;
|
|
||||||
|
|
||||||
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) {
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.mongodb.config;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.mongodb.ServerAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link ServerAddressPropertyEditor}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public class ServerAddressPropertyEditorUnitTests {
|
||||||
|
|
||||||
|
ServerAddressPropertyEditor editor;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
editor = new ServerAddressPropertyEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-454
|
||||||
|
*/
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void rejectsAddressConfigWithoutASingleParsableServerAddress() {
|
||||||
|
|
||||||
|
editor.setAsText("foo, bar");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-454
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void skipsUnparsableAddressIfAtLeastOneIsParsable() throws UnknownHostException {
|
||||||
|
|
||||||
|
editor.setAsText("foo, localhost");
|
||||||
|
assertSingleAddressOfLocalhost(editor.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-454
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void handlesEmptyAddressAsParseError() throws UnknownHostException {
|
||||||
|
|
||||||
|
editor.setAsText(", localhost");
|
||||||
|
assertSingleAddressOfLocalhost(editor.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertSingleAddressOfLocalhost(Object result) throws UnknownHostException {
|
||||||
|
|
||||||
|
assertThat(result, is(instanceOf(ServerAddress[].class)));
|
||||||
|
Collection<ServerAddress> addresses = Arrays.asList((ServerAddress[]) result);
|
||||||
|
assertThat(addresses, hasSize(1));
|
||||||
|
assertThat(addresses, hasItem(new ServerAddress("localhost")));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* 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.config;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.mongodb.WriteConcern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link StringToWriteConcernConverter}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public class StringToWriteConcernConverterUnitTest {
|
||||||
|
|
||||||
|
StringToWriteConcernConverter converter = new StringToWriteConcernConverter();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createsWellKnownConstantsCorrectly() {
|
||||||
|
assertThat(converter.convert("SAFE"), is(WriteConcern.SAFE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createsWriteConcernForUnknownValue() {
|
||||||
|
assertThat(converter.convert("-1"), is(new WriteConcern("-1")));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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.config;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.mongodb.WriteConcern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link WriteConcernPropertyEditor}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public class WriteConcernPropertyEditorUnitTests {
|
||||||
|
|
||||||
|
WriteConcernPropertyEditor editor;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
editor = new WriteConcernPropertyEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createsWriteConcernForWellKnownConstants() {
|
||||||
|
|
||||||
|
editor.setAsText("SAFE");
|
||||||
|
assertThat(editor.getValue(), is((Object) WriteConcern.SAFE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createsWriteConcernForUnknownConstants() {
|
||||||
|
|
||||||
|
editor.setAsText("-1");
|
||||||
|
assertThat(editor.getValue(), is((Object) new WriteConcern("-1")));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import com.mongodb.BasicDBList;
|
||||||
|
import com.mongodb.DBObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper classes to ease assertions on {@link DBObject}s.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public abstract class DBObjectUtils {
|
||||||
|
|
||||||
|
private DBObjectUtils() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expects the field with the given key to be not {@literal null} and a {@link DBObject} in turn and returns it.
|
||||||
|
*
|
||||||
|
* @param source the {@link DBObject} to lookup the nested one
|
||||||
|
* @param key the key of the field to lokup the nested {@link DBObject}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static DBObject getAsDBObject(DBObject source, String key) {
|
||||||
|
return getTypedValue(source, key, DBObject.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expects the field with the given key to be not {@literal null} and a {@link BasicDBList}.
|
||||||
|
*
|
||||||
|
* @param source the {@link DBObject} to lookup the {@link BasicDBList} in
|
||||||
|
* @param key the key of the field to find the {@link BasicDBList} in
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static BasicDBList getAsDBList(DBObject source, String key) {
|
||||||
|
return getTypedValue(source, key, BasicDBList.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expects the list element with the given index to be a non-{@literal null} {@link DBObject} and returns it.
|
||||||
|
*
|
||||||
|
* @param source the {@link BasicDBList} to look up the {@link DBObject} element in
|
||||||
|
* @param index the index of the element expected to contain a {@link DBObject}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static DBObject getAsDBObject(BasicDBList source, int index) {
|
||||||
|
|
||||||
|
assertThat(source.size(), greaterThanOrEqualTo(index + 1));
|
||||||
|
Object value = source.get(index);
|
||||||
|
assertThat(value, is(instanceOf(DBObject.class)));
|
||||||
|
return (DBObject) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <T> T getTypedValue(DBObject source, String key, Class<T> type) {
|
||||||
|
|
||||||
|
Object value = source.get(key);
|
||||||
|
assertThat(value, is(notNullValue()));
|
||||||
|
assertThat(value, is(instanceOf(type)));
|
||||||
|
|
||||||
|
return (T) value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
|
||||||
public class Friend {
|
public class Friend {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
|
|
||||||
|
import com.mongodb.DB;
|
||||||
|
import com.mongodb.Mongo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link MongoDbUtils}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public class MongoDbUtilsUnitTests {
|
||||||
|
|
||||||
|
Mongo mongo;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
this.mongo = new Mongo();
|
||||||
|
TransactionSynchronizationManager.initSynchronization();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
|
||||||
|
for (Object key : TransactionSynchronizationManager.getResourceMap().keySet()) {
|
||||||
|
TransactionSynchronizationManager.unbindResource(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionSynchronizationManager.clearSynchronization();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void returnsNewInstanceForDifferentDatabaseName() {
|
||||||
|
|
||||||
|
DB first = MongoDbUtils.getDB(mongo, "first");
|
||||||
|
assertThat(first, is(notNullValue()));
|
||||||
|
assertThat(MongoDbUtils.getDB(mongo, "first"), is(first));
|
||||||
|
|
||||||
|
DB second = MongoDbUtils.getDB(mongo, "second");
|
||||||
|
assertThat(second, is(not(first)));
|
||||||
|
assertThat(MongoDbUtils.getDB(mongo, "second"), is(second));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||||
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
|
import org.springframework.data.mongodb.config.WriteConcernPropertyEditor;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
import com.mongodb.WriteConcern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for {@link MongoFactoryBean}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public class MongoFactoryBeanIntegrationTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-408
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void convertsWriteConcernCorrectly() {
|
||||||
|
|
||||||
|
RootBeanDefinition definition = new RootBeanDefinition(MongoFactoryBean.class);
|
||||||
|
definition.getPropertyValues().addPropertyValue("writeConcern", "SAFE");
|
||||||
|
|
||||||
|
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||||
|
factory.registerCustomEditor(WriteConcern.class, WriteConcernPropertyEditor.class);
|
||||||
|
factory.registerBeanDefinition("factory", definition);
|
||||||
|
|
||||||
|
MongoFactoryBean bean = factory.getBean("&factory", MongoFactoryBean.class);
|
||||||
|
assertThat(ReflectionTestUtils.getField(bean, "writeConcern"), is((Object) WriteConcern.SAFE));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ import static org.junit.Assert.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link MongoOptionsFactoryBean}.
|
* Unit tests for {@link MongoOptionsFactoryBean}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class MongoOptionsFactoryBeanUnitTests {
|
public class MongoOptionsFactoryBeanUnitTests {
|
||||||
@@ -33,11 +33,11 @@ public class MongoOptionsFactoryBeanUnitTests {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void setsMaxConnectRetryTime() {
|
public void setsMaxConnectRetryTime() {
|
||||||
|
|
||||||
MongoOptionsFactoryBean bean = new MongoOptionsFactoryBean();
|
MongoOptionsFactoryBean bean = new MongoOptionsFactoryBean();
|
||||||
bean.setMaxAutoConnectRetryTime(27);
|
bean.setMaxAutoConnectRetryTime(27);
|
||||||
bean.afterPropertiesSet();
|
bean.afterPropertiesSet();
|
||||||
|
|
||||||
MongoOptions options = bean.getObject();
|
MongoOptions options = bean.getObject();
|
||||||
assertThat(options.maxAutoConnectRetryTime, is(27L));
|
assertThat(options.maxAutoConnectRetryTime, is(27L));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -39,6 +39,7 @@ import org.junit.runner.RunWith;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
import org.springframework.data.annotation.PersistenceConstructor;
|
import org.springframework.data.annotation.PersistenceConstructor;
|
||||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||||
@@ -71,6 +72,7 @@ import com.mongodb.WriteResult;
|
|||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
|
* @author Amol Nayak
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration("classpath:infrastructure.xml")
|
@ContextConfiguration("classpath:infrastructure.xml")
|
||||||
@@ -130,6 +132,7 @@ public class MongoTemplateTests {
|
|||||||
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfTypeLong.class));
|
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfTypeLong.class));
|
||||||
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfPrimitiveLong.class));
|
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfPrimitiveLong.class));
|
||||||
template.dropCollection(template.getCollectionName(TestClass.class));
|
template.dropCollection(template.getCollectionName(TestClass.class));
|
||||||
|
template.dropCollection(Sample.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -159,6 +162,112 @@ public class MongoTemplateTests {
|
|||||||
mongoTemplate.updateFirst(q, u, Person.class);
|
mongoTemplate.updateFirst(q, u, Person.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-480
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void throwsExceptionForDuplicateIds() {
|
||||||
|
|
||||||
|
MongoTemplate template = new MongoTemplate(factory);
|
||||||
|
template.setWriteResultChecking(WriteResultChecking.EXCEPTION);
|
||||||
|
|
||||||
|
Person person = new Person(new ObjectId(), "Amol");
|
||||||
|
person.setAge(28);
|
||||||
|
|
||||||
|
template.insert(person);
|
||||||
|
|
||||||
|
try {
|
||||||
|
template.insert(person);
|
||||||
|
fail("Expected DataIntegrityViolationException!");
|
||||||
|
} catch (DataIntegrityViolationException e) {
|
||||||
|
assertThat(e.getMessage(), containsString("E11000 duplicate key error index: database.person.$_id_ dup key:"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-480
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void throwsExceptionForUpdateWithInvalidPushOperator() {
|
||||||
|
|
||||||
|
MongoTemplate template = new MongoTemplate(factory);
|
||||||
|
template.setWriteResultChecking(WriteResultChecking.EXCEPTION);
|
||||||
|
|
||||||
|
ObjectId id = new ObjectId();
|
||||||
|
Person person = new Person(id, "Amol");
|
||||||
|
person.setAge(28);
|
||||||
|
|
||||||
|
template.insert(person);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
Query query = new Query(Criteria.where("firstName").is("Amol"));
|
||||||
|
Update upd = new Update().push("age", 29);
|
||||||
|
template.updateFirst(query, upd, Person.class);
|
||||||
|
fail("Expected DataIntegrityViolationException!");
|
||||||
|
|
||||||
|
} catch (DataIntegrityViolationException e) {
|
||||||
|
|
||||||
|
assertThat(e.getMessage(),
|
||||||
|
is("Execution of update with '{ \"$push\" : { \"age\" : 29}}'' using '{ \"firstName\" : \"Amol\"}' "
|
||||||
|
+ "query failed: Cannot apply $push/$pushAll modifier to non-array"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-480
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void throwsExceptionForIndexViolationIfConfigured() {
|
||||||
|
|
||||||
|
MongoTemplate template = new MongoTemplate(factory);
|
||||||
|
template.setWriteResultChecking(WriteResultChecking.EXCEPTION);
|
||||||
|
template.indexOps(Person.class).ensureIndex(new Index().on("firstName", Order.DESCENDING).unique());
|
||||||
|
|
||||||
|
Person person = new Person(new ObjectId(), "Amol");
|
||||||
|
person.setAge(28);
|
||||||
|
|
||||||
|
template.save(person);
|
||||||
|
|
||||||
|
person = new Person(new ObjectId(), "Amol");
|
||||||
|
person.setAge(28);
|
||||||
|
|
||||||
|
try {
|
||||||
|
template.save(person);
|
||||||
|
fail("Expected DataIntegrityViolationException!");
|
||||||
|
} catch (DataIntegrityViolationException e) {
|
||||||
|
assertThat(e.getMessage(),
|
||||||
|
containsString("E11000 duplicate key error index: database.person.$firstName_-1 dup key:"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-480
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void rejectsDuplicateIdInInsertAll() {
|
||||||
|
|
||||||
|
MongoTemplate template = new MongoTemplate(factory);
|
||||||
|
template.setWriteResultChecking(WriteResultChecking.EXCEPTION);
|
||||||
|
|
||||||
|
ObjectId id = new ObjectId();
|
||||||
|
Person person = new Person(id, "Amol");
|
||||||
|
person.setAge(28);
|
||||||
|
|
||||||
|
List<Person> records = new ArrayList<Person>();
|
||||||
|
records.add(person);
|
||||||
|
records.add(person);
|
||||||
|
|
||||||
|
try {
|
||||||
|
template.insertAll(records);
|
||||||
|
fail("Expected DataIntegrityViolationException!");
|
||||||
|
} catch (DataIntegrityViolationException e) {
|
||||||
|
assertThat(
|
||||||
|
e.getMessage(),
|
||||||
|
startsWith("Insert list failed: E11000 duplicate key error index: database.person.$_id_ dup key: { : ObjectId"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEnsureIndex() throws Exception {
|
public void testEnsureIndex() throws Exception {
|
||||||
|
|
||||||
@@ -189,7 +298,7 @@ public class MongoTemplateTests {
|
|||||||
assertThat(dropDupes, is(true));
|
assertThat(dropDupes, is(true));
|
||||||
|
|
||||||
List<IndexInfo> indexInfoList = template.indexOps(Person.class).getIndexInfo();
|
List<IndexInfo> indexInfoList = template.indexOps(Person.class).getIndexInfo();
|
||||||
System.out.println(indexInfoList);
|
|
||||||
assertThat(indexInfoList.size(), is(2));
|
assertThat(indexInfoList.size(), is(2));
|
||||||
IndexInfo ii = indexInfoList.get(1);
|
IndexInfo ii = indexInfoList.get(1);
|
||||||
assertThat(ii.isUnique(), is(true));
|
assertThat(ii.isUnique(), is(true));
|
||||||
@@ -906,8 +1015,6 @@ public class MongoTemplateTests {
|
|||||||
assertThat(lastMongoAction.getEntityClass().toString(), is(PersonWithIdPropertyOfTypeObjectId.class.toString()));
|
assertThat(lastMongoAction.getEntityClass().toString(), is(PersonWithIdPropertyOfTypeObjectId.class.toString()));
|
||||||
assertThat(lastMongoAction.getMongoActionOperation(), is(MongoActionOperation.UPDATE));
|
assertThat(lastMongoAction.getMongoActionOperation(), is(MongoActionOperation.UPDATE));
|
||||||
assertThat(lastMongoAction.getQuery(), equalTo(q.getQueryObject()));
|
assertThat(lastMongoAction.getQuery(), equalTo(q.getQueryObject()));
|
||||||
assertThat(lastMongoAction.getDocument(), equalTo(u.getUpdateObject()));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FsyncSafeWriteConcernResolver implements WriteConcernResolver {
|
private class FsyncSafeWriteConcernResolver implements WriteConcernResolver {
|
||||||
@@ -933,7 +1040,7 @@ public class MongoTemplateTests {
|
|||||||
DBRef first = new DBRef(factory.getDb(), "foo", new ObjectId());
|
DBRef first = new DBRef(factory.getDb(), "foo", new ObjectId());
|
||||||
DBRef second = new DBRef(factory.getDb(), "bar", new ObjectId());
|
DBRef second = new DBRef(factory.getDb(), "bar", new ObjectId());
|
||||||
|
|
||||||
template.updateFirst(null, Update.update("dbRefs", Arrays.asList(first, second)), ClassWithDBRefs.class);
|
template.updateFirst(null, update("dbRefs", Arrays.asList(first, second)), ClassWithDBRefs.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClassWithDBRefs {
|
class ClassWithDBRefs {
|
||||||
@@ -1041,7 +1148,7 @@ public class MongoTemplateTests {
|
|||||||
List<TestClass> testClassList = mappingTemplate.find(new Query(Criteria.where("myDate").is(dateTime.toDate())),
|
List<TestClass> testClassList = mappingTemplate.find(new Query(Criteria.where("myDate").is(dateTime.toDate())),
|
||||||
TestClass.class);
|
TestClass.class);
|
||||||
assertThat(testClassList.size(), is(1));
|
assertThat(testClassList.size(), is(1));
|
||||||
assertThat(testClassList.get(0).getMyDate(), is(testClass.getMyDate()));
|
assertThat(testClassList.get(0).myDate, is(testClass.myDate));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1080,24 +1187,96 @@ public class MongoTemplateTests {
|
|||||||
assertThat(template.findOne(query(where("id").is(id)), Sample.class), is(nullValue()));
|
assertThat(template.findOne(query(where("id").is(id)), Sample.class), is(nullValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Sample {
|
/**
|
||||||
|
* @see DATAMONGO-423
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void executesQueryWithNegatedRegexCorrectly() {
|
||||||
|
|
||||||
|
Sample first = new Sample();
|
||||||
|
first.field = "Matthews";
|
||||||
|
|
||||||
|
Sample second = new Sample();
|
||||||
|
second.field = "Beauford";
|
||||||
|
|
||||||
|
template.save(first);
|
||||||
|
template.save(second);
|
||||||
|
|
||||||
|
Query query = query(where("field").not().regex("Matthews"));
|
||||||
|
|
||||||
|
List<Sample> result = template.find(query, Sample.class);
|
||||||
|
assertThat(result.size(), is(1));
|
||||||
|
assertThat(result.get(0).field, is("Beauford"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-447
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void storesAndRemovesTypeWithComplexId() {
|
||||||
|
|
||||||
|
MyId id = new MyId();
|
||||||
|
id.first = "foo";
|
||||||
|
id.second = "bar";
|
||||||
|
|
||||||
|
TypeWithMyId source = new TypeWithMyId();
|
||||||
|
source.id = id;
|
||||||
|
|
||||||
|
template.save(source);
|
||||||
|
template.remove(query(where("id").is(id)), TypeWithMyId.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-539
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void removesObjectFromExplicitCollection() {
|
||||||
|
|
||||||
|
String collectionName = "explicit";
|
||||||
|
template.remove(new Query(), collectionName);
|
||||||
|
|
||||||
|
PersonWithConvertedId person = new PersonWithConvertedId();
|
||||||
|
person.name = "Dave";
|
||||||
|
template.save(person, collectionName);
|
||||||
|
assertThat(template.findAll(PersonWithConvertedId.class, collectionName).isEmpty(), is(false));
|
||||||
|
|
||||||
|
template.remove(person, collectionName);
|
||||||
|
assertThat(template.findAll(PersonWithConvertedId.class, collectionName).isEmpty(), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MyId {
|
||||||
|
|
||||||
|
String first;
|
||||||
|
String second;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TypeWithMyId {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
MyId id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Sample {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
String id;
|
String id;
|
||||||
|
String field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TestClass {
|
static class TestClass {
|
||||||
|
|
||||||
private DateTime myDate;
|
DateTime myDate;
|
||||||
|
|
||||||
@PersistenceConstructor
|
@PersistenceConstructor
|
||||||
public TestClass(DateTime date) {
|
TestClass(DateTime myDate) {
|
||||||
this.myDate = date;
|
this.myDate = myDate;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public DateTime getMyDate() {
|
static class PersonWithConvertedId {
|
||||||
return myDate;
|
|
||||||
}
|
String id;
|
||||||
|
String name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum DateTimeToDateConverter implements Converter<DateTime, Date> {
|
static enum DateTimeToDateConverter implements Converter<DateTime, Date> {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import static org.junit.Assert.*;
|
|||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -136,6 +137,31 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
|||||||
assertThat(entity.id, is(notNullValue()));
|
assertThat(entity.id, is(notNullValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-474
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void setsUnpopulatedIdField() {
|
||||||
|
|
||||||
|
NotAutogenerateableId entity = new NotAutogenerateableId();
|
||||||
|
|
||||||
|
template.populateIdIfNecessary(entity, 5);
|
||||||
|
assertThat(entity.id, is(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-474
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void doesNotSetAlreadyPopulatedId() {
|
||||||
|
|
||||||
|
NotAutogenerateableId entity = new NotAutogenerateableId();
|
||||||
|
entity.id = 5;
|
||||||
|
|
||||||
|
template.populateIdIfNecessary(entity, 7);
|
||||||
|
assertThat(entity.id, is(5));
|
||||||
|
}
|
||||||
|
|
||||||
class AutogenerateableId {
|
class AutogenerateableId {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@@ -146,6 +172,10 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
|||||||
|
|
||||||
@Id
|
@Id
|
||||||
Integer id;
|
Integer id;
|
||||||
|
|
||||||
|
public Pattern getId() {
|
||||||
|
return Pattern.compile(".");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -161,9 +191,10 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
|||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/*
|
||||||
* @see org.springframework.data.mongodb.core.core.MongoOperationsUnitTests#getOperations()
|
* (non-Javadoc)
|
||||||
*/
|
* @see org.springframework.data.mongodb.core.MongoOperationsUnitTests#getOperationsForExceptionHandling()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected MongoOperations getOperationsForExceptionHandling() {
|
protected MongoOperations getOperationsForExceptionHandling() {
|
||||||
MongoTemplate template = spy(this.template);
|
MongoTemplate template = spy(this.template);
|
||||||
@@ -171,9 +202,10 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
|||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/*
|
||||||
* @see org.springframework.data.mongodb.core.core.MongoOperationsUnitTests#getOperations()
|
* (non-Javadoc)
|
||||||
*/
|
* @see org.springframework.data.mongodb.core.MongoOperationsUnitTests#getOperations()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected MongoOperations getOperations() {
|
protected MongoOperations getOperations() {
|
||||||
return this.template;
|
return this.template;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import com.mongodb.DBCursor;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link QueryCursorPreparer}.
|
* Unit tests for {@link QueryCursorPreparer}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
@@ -41,18 +41,18 @@ public class QueryCursorPreparerUnitTests {
|
|||||||
MongoDbFactory factory;
|
MongoDbFactory factory;
|
||||||
@Mock
|
@Mock
|
||||||
DBCursor cursor;
|
DBCursor cursor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DATAMONGO-185
|
* @see DATAMONGO-185
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void appliesHintsCorrectly() {
|
public void appliesHintsCorrectly() {
|
||||||
|
|
||||||
Query query = query(where("foo").is("bar")).withHint("hint");
|
Query query = query(where("foo").is("bar")).withHint("hint");
|
||||||
|
|
||||||
CursorPreparer preparer = new MongoTemplate(factory).new QueryCursorPreparer(query);
|
CursorPreparer preparer = new MongoTemplate(factory).new QueryCursorPreparer(query);
|
||||||
preparer.prepare(cursor);
|
preparer.prepare(cursor);
|
||||||
|
|
||||||
verify(cursor).hint("hint");
|
verify(cursor).hint("hint");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.hamcrest.Matcher;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.data.mongodb.core.query.SerializationUtils;
|
||||||
|
|
||||||
|
import com.mongodb.BasicDBObject;
|
||||||
|
import com.mongodb.DBObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link SerializationUtils}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public class SerializationUtilsUnitTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void writesSimpleDBObject() {
|
||||||
|
|
||||||
|
DBObject dbObject = new BasicDBObject("foo", "bar");
|
||||||
|
assertThat(serializeToJsonSafely(dbObject), is("{ \"foo\" : \"bar\"}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void writesComplexObjectAsPlainToString() {
|
||||||
|
|
||||||
|
DBObject dbObject = new BasicDBObject("foo", new Complex());
|
||||||
|
assertThat(serializeToJsonSafely(dbObject),
|
||||||
|
startsWith("{ \"foo\" : { $java : org.springframework.data.mongodb.core.SerializationUtilsUnitTests$Complex"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void writesCollection() {
|
||||||
|
|
||||||
|
DBObject dbObject = new BasicDBObject("foo", Arrays.asList("bar", new Complex()));
|
||||||
|
Matcher<String> expectedOutput = allOf(
|
||||||
|
startsWith("{ \"foo\" : [ \"bar\", { $java : org.springframework.data.mongodb.core.SerializationUtilsUnitTests$Complex"),
|
||||||
|
endsWith(" } ] }"));
|
||||||
|
assertThat(serializeToJsonSafely(dbObject), is(expectedOutput));
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Complex {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
import org.springframework.data.authentication.UserCredentials;
|
||||||
import org.springframework.data.mongodb.MongoDbFactory;
|
import org.springframework.data.mongodb.MongoDbFactory;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ public class SimpleMongoDbFactoryUnitTests {
|
|||||||
rejectsDatabaseName("foo.bar");
|
rejectsDatabaseName("foo.bar");
|
||||||
rejectsDatabaseName("foo!bar");
|
rejectsDatabaseName("foo!bar");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DATADOC-254
|
* @see DATADOC-254
|
||||||
*/
|
*/
|
||||||
@@ -66,16 +67,16 @@ public class SimpleMongoDbFactoryUnitTests {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void mongoUriConstructor() throws UnknownHostException {
|
public void mongoUriConstructor() throws UnknownHostException {
|
||||||
|
|
||||||
MongoURI mongoURI = new MongoURI("mongodb://myUsername:myPassword@localhost/myDatabase.myCollection");
|
MongoURI mongoURI = new MongoURI("mongodb://myUsername:myPassword@localhost/myDatabase.myCollection");
|
||||||
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoURI);
|
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoURI);
|
||||||
|
|
||||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "username").toString(), is("myUsername"));
|
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "credentials"), is((Object) new UserCredentials(
|
||||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "password").toString(), is("myPassword"));
|
"myUsername", "myPassword")));
|
||||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
|
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
|
||||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
|
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rejectsDatabaseName(String databaseName) {
|
private void rejectsDatabaseName(String databaseName) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -35,5 +35,4 @@ public class TestMongoConfiguration extends AbstractMongoConfiguration {
|
|||||||
converter.setCustomConversions(new CustomConversions(converters));
|
converter.setCustomConversions(new CustomConversions(converters));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,18 @@ package org.springframework.data.mongodb.core.convert;
|
|||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.Format;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bson.types.Binary;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
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.core.convert.support.GenericConversionService;
|
||||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
|
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
|
||||||
|
|
||||||
@@ -27,13 +31,13 @@ public class CustomConversionsUnitTests {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void findsBasicReadAndWriteConversions() {
|
public void findsBasicReadAndWriteConversions() {
|
||||||
|
|
||||||
CustomConversions conversions = new CustomConversions(Arrays.asList(UuidToStringConverter.INSTANCE,
|
CustomConversions conversions = new CustomConversions(Arrays.asList(FormatToStringConverter.INSTANCE,
|
||||||
StringToUUIDConverter.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.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));
|
assertThat(conversions.hasCustomReadTarget(String.class, Locale.class), is(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +55,7 @@ public class CustomConversionsUnitTests {
|
|||||||
@Test
|
@Test
|
||||||
public void considersTypesWeRegisteredConvertersForAsSimple() {
|
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));
|
assertThat(conversions.isSimpleType(UUID.class), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,14 +99,13 @@ public class CustomConversionsUnitTests {
|
|||||||
@Test
|
@Test
|
||||||
public void populatesConversionServiceCorrectly() {
|
public void populatesConversionServiceCorrectly() {
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
GenericConversionService conversionService = new DefaultConversionService();
|
||||||
GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
|
|
||||||
assertThat(conversionService.canConvert(String.class, UUID.class), is(false));
|
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);
|
conversions.registerConvertersIn(conversionService);
|
||||||
|
|
||||||
assertThat(conversionService.canConvert(String.class, UUID.class), is(true));
|
assertThat(conversionService.canConvert(String.class, Format.class), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,8 +113,8 @@ public class CustomConversionsUnitTests {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void doesNotConsiderTypeSimpleIfOnlyReadConverterIsRegistered() {
|
public void doesNotConsiderTypeSimpleIfOnlyReadConverterIsRegistered() {
|
||||||
CustomConversions conversions = new CustomConversions(Arrays.asList(StringToUUIDConverter.INSTANCE));
|
CustomConversions conversions = new CustomConversions(Arrays.asList(StringToFormatConverter.INSTANCE));
|
||||||
assertThat(conversions.isSimpleType(UUID.class), is(false));
|
assertThat(conversions.isSimpleType(Format.class), is(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,18 +143,47 @@ public class CustomConversionsUnitTests {
|
|||||||
assertThat(conversions.getCustomWriteTarget(String.class), is(nullValue()));
|
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-462
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void hasWriteConverterForURL() {
|
||||||
|
|
||||||
|
CustomConversions conversions = new CustomConversions();
|
||||||
|
assertThat(conversions.hasCustomWriteTarget(URL.class), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-462
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void readTargetForURL() {
|
||||||
|
CustomConversions conversions = new CustomConversions();
|
||||||
|
assertThat(conversions.hasCustomReadTarget(String.class, URL.class), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum FormatToStringConverter implements Converter<Format, String> {
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
|
||||||
public String convert(UUID source) {
|
public String convert(Format source) {
|
||||||
return source.toString();
|
return source.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum StringToUUIDConverter implements Converter<String, UUID> {
|
enum StringToFormatConverter implements Converter<String, Format> {
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
public UUID convert(String source) {
|
public Format convert(String source) {
|
||||||
return UUID.fromString(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.
|
* Test case to verify correct usage of custom {@link Converter} implementations to be used.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
* @see DATADOC-101
|
* @see DATADOC-101
|
||||||
*/
|
*/
|
||||||
@@ -65,9 +65,9 @@ public class CustomConvertersUnitTests {
|
|||||||
|
|
||||||
when(barToDBObjectConverter.convert(any(Bar.class))).thenReturn(new BasicDBObject());
|
when(barToDBObjectConverter.convert(any(Bar.class))).thenReturn(new BasicDBObject());
|
||||||
when(dbObjectToBarConverter.convert(any(DBObject.class))).thenReturn(new Bar());
|
when(dbObjectToBarConverter.convert(any(DBObject.class))).thenReturn(new Bar());
|
||||||
|
|
||||||
CustomConversions conversions = new CustomConversions(Arrays.asList(barToDBObjectConverter, dbObjectToBarConverter));
|
CustomConversions conversions = new CustomConversions(Arrays.asList(barToDBObjectConverter, dbObjectToBarConverter));
|
||||||
|
|
||||||
context = new MongoMappingContext();
|
context = new MongoMappingContext();
|
||||||
context.setInitialEntitySet(new HashSet<Class<?>>(Arrays.asList(Foo.class, Bar.class)));
|
context.setInitialEntitySet(new HashSet<Class<?>>(Arrays.asList(Foo.class, Bar.class)));
|
||||||
context.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
|
context.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 by the original author(s).
|
* Copyright 2011-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
@@ -33,11 +33,12 @@ import com.mongodb.BasicDBObject;
|
|||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit test to reproduce DATADOC-273.
|
* Unit test to reproduce DATAMONGO-273.
|
||||||
*
|
*
|
||||||
* @author Harlan Iverson
|
* @author Harlan Iverson
|
||||||
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class DataDoc273Test {
|
public class DataMongo273Tests {
|
||||||
|
|
||||||
MappingMongoConverter converter;
|
MappingMongoConverter converter;
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ public class DataDoc273Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DATADOC-273
|
* @see DATAMONGO-273
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void convertMapOfThings() {
|
public void convertMapOfThings() {
|
||||||
@@ -80,7 +81,7 @@ public class DataDoc273Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DATADOC-294
|
* @see DATAMONGO-294
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
@@ -96,7 +97,6 @@ public class DataDoc273Test {
|
|||||||
|
|
||||||
DBObject result = new BasicDBList();
|
DBObject result = new BasicDBList();
|
||||||
converter.write(listOfThings, result);
|
converter.write(listOfThings, result);
|
||||||
System.out.println(result.toString());
|
|
||||||
|
|
||||||
List listOfThings2 = converter.read(List.class, result);
|
List listOfThings2 = converter.read(List.class, result);
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ public class DataDoc273Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DATADOC-294
|
* @see DATAMONGO-294
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
@@ -121,7 +121,7 @@ public class DataDoc273Test {
|
|||||||
listOfThings.add(train);
|
listOfThings.add(train);
|
||||||
listOfThings.add(automobile);
|
listOfThings.add(automobile);
|
||||||
|
|
||||||
Map box = new HashMap();
|
Map<String, Object> box = new HashMap<String, Object>();
|
||||||
box.put("one", listOfThings);
|
box.put("one", listOfThings);
|
||||||
|
|
||||||
Shipment shipment = new Shipment(box);
|
Shipment shipment = new Shipment(box);
|
||||||
@@ -138,7 +138,7 @@ public class DataDoc273Test {
|
|||||||
assertTrue(listOfThings2.get(2) instanceof Automobile);
|
assertTrue(listOfThings2.get(2) instanceof Automobile);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Plane {
|
static class Plane {
|
||||||
|
|
||||||
String maker;
|
String maker;
|
||||||
int numberOfPropellers;
|
int numberOfPropellers;
|
||||||
@@ -149,7 +149,7 @@ public class DataDoc273Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Train {
|
static class Train {
|
||||||
|
|
||||||
String railLine;
|
String railLine;
|
||||||
int numberOfCars;
|
int numberOfCars;
|
||||||
@@ -160,7 +160,7 @@ public class DataDoc273Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Automobile {
|
static class Automobile {
|
||||||
|
|
||||||
String make;
|
String make;
|
||||||
String model;
|
String model;
|
||||||
@@ -174,11 +174,11 @@ public class DataDoc273Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
public class Shipment {
|
static class Shipment {
|
||||||
|
|
||||||
Map boxes = new HashMap();
|
|
||||||
|
|
||||||
public Shipment(Map boxes) {
|
Map<String, Object> boxes;
|
||||||
|
|
||||||
|
public Shipment(Map<String, Object> boxes) {
|
||||||
this.boxes = boxes;
|
this.boxes = boxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,27 +38,27 @@ public class DefaultMongoTypeMapperUnitTests {
|
|||||||
|
|
||||||
ConfigurableTypeInformationMapper configurableTypeInformationMapper;
|
ConfigurableTypeInformationMapper configurableTypeInformationMapper;
|
||||||
SimpleTypeInformationMapper simpleTypeInformationMapper;
|
SimpleTypeInformationMapper simpleTypeInformationMapper;
|
||||||
|
|
||||||
|
|
||||||
DefaultMongoTypeMapper typeMapper;
|
DefaultMongoTypeMapper typeMapper;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
|
|
||||||
configurableTypeInformationMapper = new ConfigurableTypeInformationMapper(Collections.singletonMap(String.class, "1"));
|
configurableTypeInformationMapper = new ConfigurableTypeInformationMapper(Collections.singletonMap(String.class,
|
||||||
|
"1"));
|
||||||
simpleTypeInformationMapper = SimpleTypeInformationMapper.INSTANCE;
|
simpleTypeInformationMapper = SimpleTypeInformationMapper.INSTANCE;
|
||||||
|
|
||||||
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(
|
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY,
|
||||||
configurableTypeInformationMapper));
|
Arrays.asList(configurableTypeInformationMapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void defaultInstanceWritesClasses() {
|
public void defaultInstanceWritesClasses() {
|
||||||
|
|
||||||
typeMapper = new DefaultMongoTypeMapper();
|
typeMapper = new DefaultMongoTypeMapper();
|
||||||
writesTypeToField(new BasicDBObject(), String.class, String.class.getName());
|
writesTypeToField(new BasicDBObject(), String.class, String.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void defaultInstanceReadsClasses() {
|
public void defaultInstanceReadsClasses() {
|
||||||
typeMapper = new DefaultMongoTypeMapper();
|
typeMapper = new DefaultMongoTypeMapper();
|
||||||
@@ -74,10 +74,10 @@ public class DefaultMongoTypeMapperUnitTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void writesClassNamesForUnmappedValuesIfConfigured() {
|
public void writesClassNamesForUnmappedValuesIfConfigured() {
|
||||||
|
|
||||||
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(
|
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(
|
||||||
configurableTypeInformationMapper, simpleTypeInformationMapper));
|
configurableTypeInformationMapper, simpleTypeInformationMapper));
|
||||||
|
|
||||||
writesTypeToField(new BasicDBObject(), String.class, "1");
|
writesTypeToField(new BasicDBObject(), String.class, "1");
|
||||||
writesTypeToField(new BasicDBObject(), Object.class, Object.class.getName());
|
writesTypeToField(new BasicDBObject(), Object.class, Object.class.getName());
|
||||||
}
|
}
|
||||||
@@ -90,10 +90,10 @@ public class DefaultMongoTypeMapperUnitTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void readsTypeLoadingClassesForUnmappedTypesIfConfigured() {
|
public void readsTypeLoadingClassesForUnmappedTypesIfConfigured() {
|
||||||
|
|
||||||
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(
|
typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(
|
||||||
configurableTypeInformationMapper, simpleTypeInformationMapper));
|
configurableTypeInformationMapper, simpleTypeInformationMapper));
|
||||||
|
|
||||||
readsTypeFromField(new BasicDBObject(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, "1"), String.class);
|
readsTypeFromField(new BasicDBObject(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, "1"), String.class);
|
||||||
readsTypeFromField(new BasicDBObject(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Object.class.getName()), Object.class);
|
readsTypeFromField(new BasicDBObject(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Object.class.getName()), Object.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
|
import org.springframework.data.mapping.model.MappingException;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link MappedConstructor}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class MappedConstructorUnitTests {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
MongoPersistentEntity<?> entity;
|
||||||
|
@Mock
|
||||||
|
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||||
|
|
||||||
|
@Test(expected = MappingException.class)
|
||||||
|
public void rejectsEntityWithoutPersistenceConstructor() {
|
||||||
|
new MappedConstructor(entity, mappingContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* 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 static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.mongodb.core.MongoOperations;
|
||||||
|
import org.springframework.data.mongodb.core.query.Criteria;
|
||||||
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for {@link MongoConverters}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration("classpath:infrastructure.xml")
|
||||||
|
public class MongoConvertersIntegrationTests {
|
||||||
|
|
||||||
|
static final String COLLECTION = "_sample";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
MongoOperations template;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
template.dropCollection(COLLECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void writesUUIDBinaryCorrectly() {
|
||||||
|
|
||||||
|
Wrapper wrapper = new Wrapper();
|
||||||
|
wrapper.uuid = UUID.randomUUID();
|
||||||
|
template.save(wrapper);
|
||||||
|
|
||||||
|
assertThat(wrapper.id, is(notNullValue()));
|
||||||
|
|
||||||
|
Wrapper result = template.findOne(Query.query(Criteria.where("id").is(wrapper.id)), Wrapper.class);
|
||||||
|
assertThat(result.uuid, is(wrapper.uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Wrapper {
|
||||||
|
|
||||||
|
String id;
|
||||||
|
UUID uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,24 +21,23 @@ import static org.junit.Assert.*;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
import org.junit.Test;
|
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.BigDecimalToStringConverter;
|
||||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
|
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link MongoConverters}.
|
* Unit tests for {@link MongoConverters}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class MongoConvertersUnitTests {
|
public class MongoConvertersUnitTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void convertsBigDecimalToStringAndBackCorrectly() {
|
public void convertsBigDecimalToStringAndBackCorrectly() {
|
||||||
|
|
||||||
BigDecimal bigDecimal = BigDecimal.valueOf(254, 1);
|
BigDecimal bigDecimal = BigDecimal.valueOf(254, 1);
|
||||||
String value = BigDecimalToStringConverter.INSTANCE.convert(bigDecimal);
|
String value = BigDecimalToStringConverter.INSTANCE.convert(bigDecimal);
|
||||||
assertThat(value, is("25.4"));
|
assertThat(value, is("25.4"));
|
||||||
|
|
||||||
BigDecimal reference = StringToBigDecimalConverter.INSTANCE.convert(value);
|
BigDecimal reference = StringToBigDecimalConverter.INSTANCE.convert(value);
|
||||||
assertThat(reference, is(bigDecimal));
|
assertThat(reference, is(bigDecimal));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,26 +24,26 @@ import org.springframework.data.mongodb.core.geo.Point;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link Box}.
|
* Unit tests for {@link Box}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class BoxUnitTests {
|
public class BoxUnitTests {
|
||||||
|
|
||||||
Box first = new Box(new Point(1d, 1d), new Point(2d, 2d));
|
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 second = new Box(new Point(1d, 1d), new Point(2d, 2d));
|
||||||
Box third = new Box(new Point(3d, 3d), new Point(1d, 1d));
|
Box third = new Box(new Point(3d, 3d), new Point(1d, 1d));
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void equalsWorksCorrectly() {
|
public void equalsWorksCorrectly() {
|
||||||
|
|
||||||
assertThat(first.equals(second), is(true));
|
assertThat(first.equals(second), is(true));
|
||||||
assertThat(second.equals(first), is(true));
|
assertThat(second.equals(first), is(true));
|
||||||
assertThat(first.equals(third), is(false));
|
assertThat(first.equals(third), is(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hashCodeWorksCorrectly() {
|
public void hashCodeWorksCorrectly() {
|
||||||
|
|
||||||
assertThat(first.hashCode(), is(second.hashCode()));
|
assertThat(first.hashCode(), is(second.hashCode()));
|
||||||
assertThat(first.hashCode(), is(not(third.hashCode())));
|
assertThat(first.hashCode(), is(not(third.hashCode())));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import org.junit.Test;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link Circle}.
|
* Unit tests for {@link Circle}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class CircleUnitTests {
|
public class CircleUnitTests {
|
||||||
@@ -31,23 +31,23 @@ public class CircleUnitTests {
|
|||||||
public void rejectsNullOrigin() {
|
public void rejectsNullOrigin() {
|
||||||
new Circle(null, 0);
|
new Circle(null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void rejectsNegativeRadius() {
|
public void rejectsNegativeRadius() {
|
||||||
new Circle(1, 1, -1);
|
new Circle(1, 1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void considersTwoCirclesEqualCorrectly() {
|
public void considersTwoCirclesEqualCorrectly() {
|
||||||
|
|
||||||
Circle left = new Circle(1, 1, 1);
|
Circle left = new Circle(1, 1, 1);
|
||||||
Circle right = new Circle(1, 1, 1);
|
Circle right = new Circle(1, 1, 1);
|
||||||
|
|
||||||
assertThat(left, is(right));
|
assertThat(left, is(right));
|
||||||
assertThat(right, is(left));
|
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(left, is(right));
|
||||||
assertThat(right, is(left));
|
assertThat(right, is(left));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import org.junit.Test;
|
|||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class DistanceUnitTests {
|
public class DistanceUnitTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void defaultsMetricToNeutralOne() {
|
public void defaultsMetricToNeutralOne() {
|
||||||
assertThat(new Distance(2.5).getMetric(), is((Metric) Metrics.NEUTRAL));
|
assertThat(new Distance(2.5).getMetric(), is((Metric) Metrics.NEUTRAL));
|
||||||
@@ -40,7 +40,7 @@ public class DistanceUnitTests {
|
|||||||
Distance right = new Distance(2.5, KILOMETERS);
|
Distance right = new Distance(2.5, KILOMETERS);
|
||||||
assertThat(left.add(right), is(new Distance(5.0, KILOMETERS)));
|
assertThat(left.add(right), is(new Distance(5.0, KILOMETERS)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addsDistancesWithExplicitMetric() {
|
public void addsDistancesWithExplicitMetric() {
|
||||||
Distance left = new Distance(2.5, KILOMETERS);
|
Distance left = new Distance(2.5, KILOMETERS);
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ import org.junit.Test;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link GeoResult}.
|
* Unit tests for {@link GeoResult}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class GeoResultUnitTests {
|
public class GeoResultUnitTests {
|
||||||
|
|
||||||
GeoResult<String> first = new GeoResult<String>("Foo", new Distance(2.5));
|
GeoResult<String> first = new GeoResult<String>("Foo", new Distance(2.5));
|
||||||
GeoResult<String> second = 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));
|
GeoResult<String> third = new GeoResult<String>("Bar", new Distance(2.5));
|
||||||
@@ -33,10 +33,10 @@ public class GeoResultUnitTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void considersSameInstanceEqual() {
|
public void considersSameInstanceEqual() {
|
||||||
|
|
||||||
assertThat(first.equals(first), is(true));
|
assertThat(first.equals(first), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void considersSameValuesAsEqual() {
|
public void considersSameValuesAsEqual() {
|
||||||
assertThat(first.equals(second), is(true));
|
assertThat(first.equals(second), is(true));
|
||||||
@@ -46,7 +46,7 @@ public class GeoResultUnitTests {
|
|||||||
assertThat(first.equals(fourth), is(false));
|
assertThat(first.equals(fourth), is(false));
|
||||||
assertThat(fourth.equals(first), is(false));
|
assertThat(fourth.equals(first), is(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void rejectsNullContent() {
|
public void rejectsNullContent() {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import org.junit.Test;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link GeoResults}.
|
* Unit tests for {@link GeoResults}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class GeoResultsUnitTests {
|
public class GeoResultsUnitTests {
|
||||||
@@ -32,11 +32,11 @@ public class GeoResultsUnitTests {
|
|||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void calculatesAverageForGivenGeoResults() {
|
public void calculatesAverageForGivenGeoResults() {
|
||||||
|
|
||||||
GeoResult<Object> first = new GeoResult<Object>(new Object(), new Distance(2));
|
GeoResult<Object> first = new GeoResult<Object>(new Object(), new Distance(2));
|
||||||
GeoResult<Object> second = new GeoResult<Object>(new Object(), new Distance(5));
|
GeoResult<Object> second = new GeoResult<Object>(new Object(), new Distance(5));
|
||||||
GeoResults<Object> geoResults = new GeoResults<Object>(Arrays.asList(first, second));
|
GeoResults<Object> geoResults = new GeoResults<Object>(Arrays.asList(first, second));
|
||||||
|
|
||||||
assertThat(geoResults.getAverageDistance(), is(new Distance(3.5)));
|
assertThat(geoResults.getAverageDistance(), is(new Distance(3.5)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,10 +34,14 @@ import org.springframework.context.ApplicationContext;
|
|||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||||
|
import org.springframework.data.mongodb.core.IndexOperations;
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
import org.springframework.data.mongodb.core.Venue;
|
import org.springframework.data.mongodb.core.Venue;
|
||||||
import org.springframework.data.mongodb.core.index.GeospatialIndex;
|
import org.springframework.data.mongodb.core.index.GeospatialIndex;
|
||||||
|
import org.springframework.data.mongodb.core.index.IndexField;
|
||||||
|
import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||||
|
import org.springframework.data.mongodb.core.query.Order;
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
import org.springframework.data.mongodb.monitor.ServerInfo;
|
import org.springframework.data.mongodb.monitor.ServerInfo;
|
||||||
import org.springframework.expression.ExpressionParser;
|
import org.springframework.expression.ExpressionParser;
|
||||||
@@ -54,7 +58,6 @@ import com.mongodb.WriteConcern;
|
|||||||
* Modified from https://github.com/deftlabs/mongo-java-geospatial-example
|
* Modified from https://github.com/deftlabs/mongo-java-geospatial-example
|
||||||
*
|
*
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class GeoSpatialTests {
|
public class GeoSpatialTests {
|
||||||
|
|
||||||
@@ -193,6 +196,26 @@ public class GeoSpatialTests {
|
|||||||
assertThat(indexInfo.get(1).get("ns").toString(), is("database.newyork"));
|
assertThat(indexInfo.get(1).get("ns").toString(), is("database.newyork"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-360
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void indexInfoIsCorrect() {
|
||||||
|
|
||||||
|
IndexOperations operations = template.indexOps(Venue.class);
|
||||||
|
List<IndexInfo> indexInfo = operations.getIndexInfo();
|
||||||
|
|
||||||
|
assertThat(indexInfo.size(), is(2));
|
||||||
|
|
||||||
|
List<IndexField> fields = indexInfo.get(0).getIndexFields();
|
||||||
|
assertThat(fields.size(), is(1));
|
||||||
|
assertThat(fields, hasItem(IndexField.create("_id", Order.ASCENDING)));
|
||||||
|
|
||||||
|
fields = indexInfo.get(1).getIndexFields();
|
||||||
|
assertThat(fields.size(), is(1));
|
||||||
|
assertThat(fields, hasItem(IndexField.geo("location")));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO move to MongoAdmin
|
// TODO move to MongoAdmin
|
||||||
public List<DBObject> getIndexInfo(Class<?> clazz) {
|
public List<DBObject> getIndexInfo(Class<?> clazz) {
|
||||||
return template.execute(clazz, new CollectionCallback<List<DBObject>>() {
|
return template.execute(clazz, new CollectionCallback<List<DBObject>>() {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user