Compare commits
28 Commits
1.0.1.RELE
...
1.0.2.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
4
pom.xml
4
pom.xml
@@ -6,7 +6,7 @@
|
||||
<name>Spring Data MongoDB Distribution</name>
|
||||
<description>Spring Data project for MongoDB</description>
|
||||
<url>http://www.springsource.org/spring-data/mongodb</url>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
<version>1.0.2.RELEASE</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>spring-data-mongodb</module>
|
||||
@@ -151,7 +151,7 @@
|
||||
<entities>
|
||||
<entity>
|
||||
<name>version</name>
|
||||
<value>${pom.version}</value>
|
||||
<value>${project.version}</value>
|
||||
</entity>
|
||||
</entities>
|
||||
<postProcess>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
<version>1.0.2.RELEASE</version>
|
||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb-cross-store</artifactId>
|
||||
@@ -68,24 +68,6 @@
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<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>
|
||||
</dependency>
|
||||
|
||||
@@ -95,17 +77,6 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
<version>1.0.2.RELEASE</version>
|
||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb-log4j</artifactId>
|
||||
@@ -27,47 +27,9 @@
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<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>
|
||||
</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>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
<name>Spring Data MongoDB Parent</name>
|
||||
<description>Spring Data project for MongoDB</description>
|
||||
<url>http://www.springsource.org/spring-data/mongodb</url>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
<version>1.0.2.RELEASE</version>
|
||||
<packaging>pom</packaging>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- versions for commonly-used dependencies -->
|
||||
<junit.version>4.8.1</junit.version>
|
||||
<log4j.version>1.2.15</log4j.version>
|
||||
<junit.version>4.10</junit.version>
|
||||
<log4j.version>1.2.16</log4j.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.codehaus.jackson.version>1.6.1</org.codehaus.jackson.version>
|
||||
<org.springframework.version.30>3.0.7.RELEASE</org.springframework.version.30>
|
||||
@@ -95,42 +96,6 @@
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>strict</id>
|
||||
<properties>
|
||||
<maven.test.failure.ignore>false</maven.test.failure.ignore>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>fast</id>
|
||||
<properties>
|
||||
<maven.test.skip>true</maven.test.skip>
|
||||
<maven.javadoc.skip>true</maven.javadoc.skip>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>staging</id>
|
||||
<distributionManagement>
|
||||
<site>
|
||||
<id>spring-site-staging</id>
|
||||
<url>file:///${java.io.tmpdir}/spring-data/mongodb/docs</url>
|
||||
</site>
|
||||
<repository>
|
||||
<id>spring-milestone-staging</id>
|
||||
<url>file:///${java.io.tmpdir}/spring-data/mongodb/milestone</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>spring-snapshot-staging</id>
|
||||
<url>file:///${java.io.tmpdir}/spring-data/mongodb/snapshot</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>bootstrap</id>
|
||||
<!-- TODO: move the repositories in here before release -->
|
||||
</profile>
|
||||
</profiles>
|
||||
<distributionManagement>
|
||||
<!-- see 'staging' profile for dry-run deployment settings -->
|
||||
<downloadUrl>http://www.springsource.com/download/community
|
||||
@@ -187,6 +152,11 @@
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
@@ -228,7 +198,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
<version>1.0.2.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
@@ -254,24 +224,6 @@
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<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>
|
||||
</dependency>
|
||||
|
||||
@@ -284,14 +236,14 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${org.mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<artifactId>junit-dep</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
@@ -299,19 +251,34 @@
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<dependencies>
|
||||
<!--
|
||||
dependency definitions to be inherited by child poms. any
|
||||
<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
|
||||
-->
|
||||
|
||||
<!-- Test dependencies -->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</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>
|
||||
|
||||
<build>
|
||||
@@ -326,48 +293,11 @@
|
||||
<version>3.1.0.RELEASE</version>
|
||||
</extension>
|
||||
</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>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
@@ -387,13 +317,13 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.8</version>
|
||||
<version>2.10</version>
|
||||
<configuration>
|
||||
<useFile>false</useFile>
|
||||
<includes>
|
||||
<include>**/*Tests.java</include>
|
||||
</includes>
|
||||
<junitArtifactName>junit:junit</junitArtifactName>
|
||||
<junitArtifactName>junit:junit-dep</junitArtifactName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.0.1.RELEASE</version>
|
||||
<version>1.0.2.RELEASE</version>
|
||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
@@ -18,10 +18,22 @@
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-expression</artifactId>
|
||||
@@ -79,25 +91,6 @@
|
||||
</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>
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
@@ -108,8 +101,8 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
|
||||
@@ -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");
|
||||
* 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.Set;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
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.StringUtils;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
|
||||
/**
|
||||
* Abstract base class to ease JavaConfig setup for Spring Data MongoDB.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Configuration
|
||||
public abstract class AbstractMongoConfiguration {
|
||||
|
||||
@@ -50,10 +57,11 @@ public abstract class AbstractMongoConfiguration {
|
||||
|
||||
@Bean
|
||||
public MongoDbFactory mongoDbFactory() throws Exception {
|
||||
if (getUserCredentials() == null) {
|
||||
UserCredentials credentials = getUserCredentials();
|
||||
if (credentials == null) {
|
||||
return new SimpleMongoDbFactory(mongo(), getDatabaseName());
|
||||
} else {
|
||||
return new SimpleMongoDbFactory(mongo(), getDatabaseName(), getUserCredentials());
|
||||
return new SimpleMongoDbFactory(mongo(), getDatabaseName(), credentials);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,11 @@ package org.springframework.data.mongodb.config;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
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 com.mongodb.ServerAddress;
|
||||
@@ -30,6 +34,8 @@ import com.mongodb.ServerAddress;
|
||||
*/
|
||||
public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(ServerAddressPropertyEditor.class);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||
@@ -38,21 +44,49 @@ public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
||||
public void setAsText(String 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 {
|
||||
serverAddresses[i] = new ServerAddress(hostAndPort[0], Integer.parseInt(hostAndPort[1]));
|
||||
} 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);
|
||||
if (address != null) {
|
||||
serverAddresses.add(address);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
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.query.Order;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -123,25 +122,30 @@ public class DefaultIndexOperations implements IndexOperations {
|
||||
return getIndexData(dbObjectList);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<IndexInfo> getIndexData(List<DBObject> dbObjectList) {
|
||||
|
||||
List<IndexInfo> indexInfoList = new ArrayList<IndexInfo>();
|
||||
|
||||
for (DBObject ix : dbObjectList) {
|
||||
|
||||
Map<String, Order> keyOrderMap = new LinkedHashMap<String, Order>();
|
||||
DBObject keyDbObject = (DBObject) ix.get("key");
|
||||
Iterator<?> entries = keyDbObject.toMap().entrySet().iterator();
|
||||
int numberOfElements = keyDbObject.keySet().size();
|
||||
|
||||
while (entries.hasNext()) {
|
||||
Entry<Object, Integer> thisEntry = (Entry<Object, Integer>) entries.next();
|
||||
String key = thisEntry.getKey().toString();
|
||||
int value = thisEntry.getValue();
|
||||
if (value == 1) {
|
||||
Map<String, Order> keyOrderMap = new HashMap<String, Order>();
|
||||
List<IndexField> indexFields = new ArrayList<IndexField>(numberOfElements);
|
||||
|
||||
for (String key : keyDbObject.keySet()) {
|
||||
|
||||
Object value = keyDbObject.get(key);
|
||||
|
||||
if (Integer.valueOf(1).equals(value)) {
|
||||
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);
|
||||
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 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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
* 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
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
|
||||
@@ -39,12 +38,10 @@ import com.mongodb.WriteConcern;
|
||||
* @author Oliver Gierke
|
||||
* @since 1.0
|
||||
*/
|
||||
public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptionTranslator {
|
||||
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, DisposableBean,
|
||||
PersistenceExceptionTranslator {
|
||||
|
||||
/**
|
||||
* Logger, available to subclasses.
|
||||
*/
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
private Mongo mongo;
|
||||
|
||||
private MongoOptions mongoOptions;
|
||||
private String host;
|
||||
@@ -89,34 +86,7 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptio
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -142,4 +112,45 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptio
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.authentication.UserCredentials;
|
||||
import org.springframework.data.convert.EntityReader;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
@@ -938,7 +939,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
entityClass, null, queryObject);
|
||||
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
||||
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) {
|
||||
wr = collection.remove(dboq);
|
||||
@@ -1337,13 +1338,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
updateObj.put(key, mongoConverter.convertToMongoType(updateObj.get(key)));
|
||||
}
|
||||
|
||||
DBObject mappedQuery = mapper.getMappedObject(query, entity);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("findAndModify using query: " + query + " fields: " + fields + " sort: " + sort + " for class: "
|
||||
+ entityClass + " and update: " + updateObj + " in collection: " + collectionName);
|
||||
LOGGER.debug("findAndModify using query: " + mappedQuery + " fields: " + fields + " sort: " + sort
|
||||
+ " for class: " + entityClass + " and update: " + updateObj + " in collection: " + collectionName);
|
||||
}
|
||||
|
||||
return executeFindOneInternal(new FindAndModifyCallback(mapper.getMappedObject(query, entity), fields, sort,
|
||||
updateObj, options), new ReadDbObjectCallback<T>(readerToUse, entityClass), collectionName);
|
||||
return executeFindOneInternal(new FindAndModifyCallback(mappedQuery, fields, sort, updateObj, options),
|
||||
new ReadDbObjectCallback<T>(readerToUse, entityClass), collectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1364,9 +1367,19 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
return;
|
||||
}
|
||||
|
||||
ConversionService conversionService = mongoConverter.getConversionService();
|
||||
BeanWrapper<PersistentEntity<Object, ?>, Object> wrapper = BeanWrapper.create(savedObject, conversionService);
|
||||
|
||||
try {
|
||||
BeanWrapper.create(savedObject, mongoConverter.getConversionService()).setProperty(idProp, id);
|
||||
return;
|
||||
|
||||
Object idValue = wrapper.getProperty(idProp);
|
||||
|
||||
if (idValue != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.setProperty(idProp, id);
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
@@ -41,6 +42,9 @@ import com.mongodb.DBObject;
|
||||
*/
|
||||
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 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
|
||||
* {@link PersistentEntity} metadata.
|
||||
*
|
||||
* @param query
|
||||
* @param entity
|
||||
* @param query must not be {@literal null}.
|
||||
* @param entity can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public DBObject getMappedObject(DBObject query, MongoPersistentEntity<?> entity) {
|
||||
@@ -68,8 +72,10 @@ public class QueryMapper {
|
||||
DBObject newDbo = new BasicDBObject();
|
||||
|
||||
for (String key : query.keySet()) {
|
||||
|
||||
String newKey = key;
|
||||
Object value = query.get(key);
|
||||
|
||||
if (isIdKey(key, entity)) {
|
||||
if (value instanceof DBObject) {
|
||||
DBObject valueDbo = (DBObject) value;
|
||||
@@ -81,34 +87,51 @@ public class QueryMapper {
|
||||
}
|
||||
valueDbo.put(inKey, ids.toArray(new Object[ids.size()]));
|
||||
} else {
|
||||
value = getMappedObject((DBObject) value, entity);
|
||||
value = getMappedObject((DBObject) value, null);
|
||||
}
|
||||
} else {
|
||||
value = convertId(value);
|
||||
}
|
||||
newKey = "_id";
|
||||
} else if (key.startsWith("$") && key.endsWith("or")) {
|
||||
} else if (key.matches(N_OR_PATTERN)) {
|
||||
// $or/$nor
|
||||
Iterable<?> conditions = (Iterable<?>) value;
|
||||
BasicBSONList newConditions = new BasicBSONList();
|
||||
Iterator<?> iter = conditions.iterator();
|
||||
while (iter.hasNext()) {
|
||||
newConditions.add(getMappedObject((DBObject) iter.next(), entity));
|
||||
newConditions.add(getMappedObject((DBObject) iter.next(), null));
|
||||
}
|
||||
value = newConditions;
|
||||
} else if (key.equals("$ne")) {
|
||||
value = convertId(value);
|
||||
} else if (value instanceof DBObject) {
|
||||
newDbo.put(newKey, getMappedObject((DBObject) value, entity));
|
||||
continue;
|
||||
}
|
||||
|
||||
newDbo.put(newKey, converter.convertToMongoType(value));
|
||||
newDbo.put(newKey, convertSimpleOrDBObject(value, null));
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
@@ -123,7 +146,7 @@ public class QueryMapper {
|
||||
return idProperty.getName().equals(key) || idProperty.getFieldName().equals(key);
|
||||
}
|
||||
|
||||
return Arrays.asList("id", "_id").contains(key);
|
||||
return DEFAULT_ID_NAMES.contains(key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,6 @@ package org.springframework.data.mongodb.core;
|
||||
|
||||
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.dao.DataAccessException;
|
||||
import org.springframework.data.authentication.UserCredentials;
|
||||
@@ -39,12 +37,10 @@ import com.mongodb.WriteConcern;
|
||||
*/
|
||||
public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final Mongo mongo;
|
||||
private final String databaseName;
|
||||
private String username;
|
||||
private String password;
|
||||
private final boolean mongoInstanceCreated;
|
||||
private final UserCredentials credentials;
|
||||
private WriteConcern writeConcern;
|
||||
|
||||
/**
|
||||
@@ -54,12 +50,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
* @param databaseName database name, not be {@literal null}.
|
||||
*/
|
||||
public SimpleMongoDbFactory(Mongo mongo, String databaseName) {
|
||||
Assert.notNull(mongo, "Mongo must not be null");
|
||||
Assert.hasText(databaseName, "Database name must not be empty");
|
||||
Assert.isTrue(databaseName.matches("[\\w-]+"),
|
||||
"Database name must only contain letters, numbers, underscores and dashes!");
|
||||
this.mongo = mongo;
|
||||
this.databaseName = databaseName;
|
||||
this(mongo, databaseName, new UserCredentials(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,12 +58,10 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
*
|
||||
* @param mongo Mongo instance, 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) {
|
||||
this(mongo, databaseName);
|
||||
this.username = userCredentials.getUsername();
|
||||
this.password = userCredentials.getPassword();
|
||||
public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials) {
|
||||
this(mongo, databaseName, credentials, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +73,21 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
* @see MongoURI
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,10 +99,6 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
this.writeConcern = writeConcern;
|
||||
}
|
||||
|
||||
public WriteConcern getWriteConcern() {
|
||||
return writeConcern;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.MongoDbFactory#getDb()
|
||||
@@ -116,6 +115,9 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
|
||||
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());
|
||||
|
||||
if (writeConcern != null) {
|
||||
@@ -126,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 {
|
||||
mongo.close();
|
||||
}
|
||||
|
||||
public static String parseChars(char[] chars) {
|
||||
if (chars == null) {
|
||||
return null;
|
||||
} else {
|
||||
return String.valueOf(chars);
|
||||
if (mongoInstanceCreated) {
|
||||
mongo.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static String parseChars(char[] chars) {
|
||||
return chars == null ? null : String.valueOf(chars);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,10 +36,10 @@ import org.springframework.data.convert.WritingConverter;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BinaryToUUIDConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.UUIDToBinaryConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToURLConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.URLToStringConverter;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -91,8 +91,8 @@ public class CustomConversions {
|
||||
this.converters.add(StringToBigDecimalConverter.INSTANCE);
|
||||
this.converters.add(BigIntegerToStringConverter.INSTANCE);
|
||||
this.converters.add(StringToBigIntegerConverter.INSTANCE);
|
||||
this.converters.add(UUIDToBinaryConverter.INSTANCE);
|
||||
this.converters.add(BinaryToUUIDConverter.INSTANCE);
|
||||
this.converters.add(URLToStringConverter.INSTANCE);
|
||||
this.converters.add(StringToURLConverter.INSTANCE);
|
||||
this.converters.addAll(converters);
|
||||
|
||||
for (Object c : this.converters) {
|
||||
|
||||
@@ -18,6 +18,7 @@ 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;
|
||||
@@ -25,6 +26,7 @@ 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;
|
||||
@@ -37,6 +39,9 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -44,13 +49,19 @@ class MappedConstructor {
|
||||
*
|
||||
* @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) {
|
||||
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()) {
|
||||
@@ -83,6 +94,7 @@ class MappedConstructor {
|
||||
*
|
||||
* @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) {
|
||||
|
||||
@@ -92,7 +104,7 @@ class MappedConstructor {
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format("Didn't find a MappedParameter for %s!", parameter.toString()));
|
||||
throw new MappingException(String.format("Didn't find a MappedParameter for %s!", parameter.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,4 +177,4 @@ class MappedConstructor {
|
||||
return this.property.equals(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,7 +439,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
*
|
||||
* @param collection must not be {@literal null}.
|
||||
* @param property must not be {@literal null}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected DBObject createCollection(Collection<?> collection, MongoPersistentProperty property) {
|
||||
@@ -819,7 +818,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return null;
|
||||
}
|
||||
|
||||
Class<?> target = conversions.getCustomWriteTarget(getClass());
|
||||
Class<?> target = conversions.getCustomWriteTarget(obj.getClass());
|
||||
if (target != null) {
|
||||
return conversionService.convert(obj, target);
|
||||
}
|
||||
@@ -850,14 +849,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return result;
|
||||
}
|
||||
|
||||
if (obj instanceof List) {
|
||||
return maybeConvertList((List<?>) obj);
|
||||
}
|
||||
|
||||
if (obj.getClass().isArray()) {
|
||||
return maybeConvertList(Arrays.asList((Object[]) obj));
|
||||
}
|
||||
|
||||
if (obj instanceof Collection) {
|
||||
return maybeConvertList((Collection<?>) obj);
|
||||
}
|
||||
|
||||
DBObject newDbo = new BasicDBObject();
|
||||
this.write(obj, newDbo);
|
||||
return removeTypeInfoRecursively(newDbo);
|
||||
|
||||
@@ -15,18 +15,15 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.UUID;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bson.BSON;
|
||||
import org.bson.types.Binary;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -127,50 +124,26 @@ abstract class MongoConverters {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom {@link Converter} to convert {@link UUID}s into {@link Binary}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static enum UUIDToBinaryConverter implements Converter<UUID, Binary> {
|
||||
|
||||
public static enum URLToStringConverter implements Converter<URL, String> {
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
public Binary convert(UUID source) {
|
||||
|
||||
try {
|
||||
return source == null ? null : new Binary(BSON.B_UUID, source.toString().getBytes("UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new MappingException(String.format("Could nor convert UUID %s into Binary!", source.toString()), e);
|
||||
}
|
||||
public String convert(URL source) {
|
||||
return source == null ? null : source.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static enum BinaryToUUIDConverter implements Converter<Binary, UUID> {
|
||||
|
||||
public static enum StringToURLConverter implements Converter<String, URL> {
|
||||
INSTANCE;
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(BinaryToUUIDConverter.class);
|
||||
private static final TypeDescriptor SOURCE = TypeDescriptor.valueOf(String.class);
|
||||
private static final TypeDescriptor TARGET = TypeDescriptor.valueOf(URL.class);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
public UUID convert(Binary source) {
|
||||
|
||||
if (BSON.B_UUID != source.getType()) {
|
||||
LOG.warn(String.format("Source binary %s is not an UUID actually! Trying to read it nevertheless...",
|
||||
source.toString()));
|
||||
}
|
||||
public URL convert(String source) {
|
||||
|
||||
try {
|
||||
return source == null ? null : UUID.fromString(new String(source.getData(), "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new MappingException(String.format("Could not convert Binary %s into UUID!", source.toString()), e);
|
||||
return source == null ? null : new URL(source);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new ConversionFailedException(SOURCE, TARGET, source, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,35 +15,52 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.index;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
public class IndexInfo {
|
||||
|
||||
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.indexFields = Collections.unmodifiableList(indexFields);
|
||||
this.name = name;
|
||||
this.unique = unique;
|
||||
this.dropDuplicates = dropDuplicates;
|
||||
this.sparse = sparse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #getIndexFields()} instead as this {@link Map} does not contain geo indexes.
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public Map<String, Order> getFieldSpec() {
|
||||
return fieldSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the individual index fields of the index.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<IndexField> getIndexFields() {
|
||||
return this.indexFields;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -62,7 +79,7 @@ public class IndexInfo {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IndexInfo [fieldSpec=" + fieldSpec + ", name=" + name + ", unique=" + unique + ", dropDuplicates="
|
||||
return "IndexInfo [indexFields=" + indexFields + ", name=" + name + ", unique=" + unique + ", dropDuplicates="
|
||||
+ dropDuplicates + ", sparse=" + sparse + "]";
|
||||
}
|
||||
|
||||
@@ -71,7 +88,7 @@ public class IndexInfo {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
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 + (sparse ? 1231 : 1237);
|
||||
result = prime * result + (unique ? 1231 : 1237);
|
||||
@@ -80,34 +97,39 @@ public class IndexInfo {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
if (this == obj) {
|
||||
return true;
|
||||
if (obj == null)
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
IndexInfo other = (IndexInfo) obj;
|
||||
if (dropDuplicates != other.dropDuplicates)
|
||||
if (dropDuplicates != other.dropDuplicates) {
|
||||
return false;
|
||||
if (fieldSpec == null) {
|
||||
if (other.fieldSpec != null)
|
||||
}
|
||||
if (indexFields == null) {
|
||||
if (other.indexFields != null) {
|
||||
return false;
|
||||
} else if (!fieldSpec.equals(other.fieldSpec))
|
||||
}
|
||||
} else if (!indexFields.equals(other.indexFields)) {
|
||||
return false;
|
||||
}
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
if (other.name != null) {
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
}
|
||||
} else if (!name.equals(other.name)) {
|
||||
return false;
|
||||
if (sparse != other.sparse)
|
||||
}
|
||||
if (sparse != other.sparse) {
|
||||
return false;
|
||||
if (unique != other.unique)
|
||||
}
|
||||
if (unique != other.unique) {
|
||||
return false;
|
||||
}
|
||||
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,6 +23,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.event.MappingContextEvent;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
@@ -76,7 +77,13 @@ public class MongoPersistentEntityIndexCreator implements
|
||||
*/
|
||||
public void onApplicationEvent(
|
||||
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) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.math.BigInteger;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bson.types.Binary;
|
||||
@@ -52,6 +53,7 @@ public abstract class MongoSimpleTypes {
|
||||
simpleTypes.add(DBObject.class);
|
||||
simpleTypes.add(Pattern.class);
|
||||
simpleTypes.add(Binary.class);
|
||||
simpleTypes.add(UUID.class);
|
||||
MONGO_SIMPLE_TYPES = Collections.unmodifiableSet(simpleTypes);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,33 +26,39 @@ import com.mongodb.DBObject;
|
||||
* Collects the results of performing a MapReduce operations.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
* @param <T> The class in which the results are mapped onto, accessible via an interator.
|
||||
* @author Oliver Gierke
|
||||
* @param <T> The class in which the results are mapped onto, accessible via an iterator.
|
||||
*/
|
||||
public class MapReduceResults<T> implements Iterable<T> {
|
||||
|
||||
private final List<T> mappedResults;
|
||||
private final DBObject rawResults;
|
||||
private final String outputCollection;
|
||||
private final MapReduceTiming mapReduceTiming;
|
||||
private final MapReduceCounts mapReduceCounts;
|
||||
|
||||
private DBObject rawResults;
|
||||
|
||||
private MapReduceTiming mapReduceTiming;
|
||||
|
||||
private MapReduceCounts mapReduceCounts;
|
||||
|
||||
private String outputCollection;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MapReduceResults} from the given mapped results and the raw one.
|
||||
*
|
||||
* @param mappedResults must not be {@literal null}.
|
||||
* @param rawResults must not be {@literal null}.
|
||||
*/
|
||||
public MapReduceResults(List<T> mappedResults, DBObject rawResults) {
|
||||
|
||||
Assert.notNull(mappedResults);
|
||||
Assert.notNull(rawResults);
|
||||
|
||||
this.mappedResults = mappedResults;
|
||||
this.rawResults = rawResults;
|
||||
parseTiming(rawResults);
|
||||
parseCounts(rawResults);
|
||||
if (rawResults.get("result") != null) {
|
||||
this.outputCollection = (String) rawResults.get("result");
|
||||
}
|
||||
this.mapReduceTiming = parseTiming(rawResults);
|
||||
this.mapReduceCounts = parseCounts(rawResults);
|
||||
this.outputCollection = parseOutputCollection(rawResults);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
public Iterator<T> iterator() {
|
||||
return mappedResults.iterator();
|
||||
}
|
||||
@@ -73,28 +79,71 @@ public class MapReduceResults<T> implements Iterable<T> {
|
||||
return rawResults;
|
||||
}
|
||||
|
||||
protected void parseTiming(DBObject rawResults) {
|
||||
private MapReduceTiming parseTiming(DBObject rawResults) {
|
||||
|
||||
DBObject timing = (DBObject) rawResults.get("timing");
|
||||
if (timing != null) {
|
||||
if (timing.get("mapTime") != null && timing.get("emitLoop") != null && timing.get("total") != null) {
|
||||
mapReduceTiming = new MapReduceTiming((Long) timing.get("mapTime"), (Integer) timing.get("emitLoop"),
|
||||
(Integer) timing.get("total"));
|
||||
}
|
||||
} else {
|
||||
mapReduceTiming = new MapReduceTiming(-1, -1, -1);
|
||||
|
||||
if (timing == null) {
|
||||
return 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");
|
||||
if (counts != null) {
|
||||
if (counts.get("input") != null && counts.get("emit") != null && counts.get("output") != null) {
|
||||
mapReduceCounts = new MapReduceCounts((Integer) counts.get("input"), (Integer) counts.get("emit"),
|
||||
(Integer) counts.get("output"));
|
||||
}
|
||||
} else {
|
||||
mapReduceCounts = new MapReduceCounts(-1, -1, -1);
|
||||
|
||||
if (counts == null) {
|
||||
return 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,14 +20,15 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bson.BSON;
|
||||
import org.bson.types.BasicBSONList;
|
||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||
import org.springframework.data.mongodb.core.geo.Circle;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.mongodb.core.geo.Shape;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
@@ -97,13 +98,17 @@ public class Criteria implements CriteriaDefinition {
|
||||
throw new InvalidMongoDbApiUsageException(
|
||||
"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.");
|
||||
}
|
||||
this.isValue = o;
|
||||
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
|
||||
*
|
||||
@@ -269,7 +274,11 @@ public class Criteria implements CriteriaDefinition {
|
||||
* @return
|
||||
*/
|
||||
public Criteria not() {
|
||||
criteria.put("$not", null);
|
||||
return not(null);
|
||||
}
|
||||
|
||||
private Criteria not(Object value) {
|
||||
criteria.put("$not", value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -280,8 +289,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
* @return
|
||||
*/
|
||||
public Criteria regex(String re) {
|
||||
criteria.put("$regex", re);
|
||||
return this;
|
||||
return regex(re, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,13 +300,32 @@ public class Criteria implements CriteriaDefinition {
|
||||
* @return
|
||||
*/
|
||||
public Criteria regex(String re, String options) {
|
||||
criteria.put("$regex", re);
|
||||
if (StringUtils.hasText(options)) {
|
||||
criteria.put("$options", options);
|
||||
return regex(toPattern(re, 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;
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
@@ -426,16 +453,17 @@ public class Criteria implements CriteriaDefinition {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
boolean not = false;
|
||||
for (String k : this.criteria.keySet()) {
|
||||
Object value = this.criteria.get(k);
|
||||
if (not) {
|
||||
DBObject notDbo = new BasicDBObject();
|
||||
notDbo.put(k, this.criteria.get(k));
|
||||
notDbo.put(k, value);
|
||||
dbo.put("$not", notDbo);
|
||||
not = false;
|
||||
} else {
|
||||
if ("$not".equals(k)) {
|
||||
if ("$not".equals(k) && value == null) {
|
||||
not = true;
|
||||
} else {
|
||||
dbo.put(k, this.criteria.get(k));
|
||||
dbo.put(k, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
* 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.List;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link Criteria#orOperator(Criteria...)} instead.
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Deprecated
|
||||
public class OrQuery extends Query {
|
||||
|
||||
public OrQuery(Query... q) {
|
||||
@@ -31,5 +37,4 @@ public class OrQuery extends Query {
|
||||
}
|
||||
return new Criteria(criteriaList, "$or");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import static org.springframework.data.mongodb.core.SerializationUtils.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -140,4 +142,14 @@ public class Query {
|
||||
protected List<Criteria> getCriteria() {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -85,7 +85,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
} else if (method.isGeoNearQuery()) {
|
||||
return new GeoNearExecution(accessor).execute(query);
|
||||
} else if (method.isCollectionQuery()) {
|
||||
return new CollectionExecution().execute(query);
|
||||
return new CollectionExecution(accessor.getPageable()).execute(query);
|
||||
} else if (method.isPageQuery()) {
|
||||
return new PagedExecution(accessor.getPageable()).execute(query);
|
||||
} else {
|
||||
@@ -133,12 +133,23 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
*/
|
||||
class CollectionExecution extends Execution {
|
||||
|
||||
private final Pageable pageable;
|
||||
|
||||
CollectionExecution(Pageable pageable) {
|
||||
this.pageable = pageable;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.query.Query)
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Query query) {
|
||||
|
||||
if (pageable != null) {
|
||||
query = applyPagination(query, pageable);
|
||||
}
|
||||
|
||||
return readCollection(query);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.query.Criteria;
|
||||
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.repository.query.ConvertingParameterAccessor.PotentiallyConvertingIterator;
|
||||
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||
@@ -45,7 +44,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @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 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)
|
||||
*/
|
||||
@Override
|
||||
protected Query create(Part part, Iterator<Object> iterator) {
|
||||
protected Criteria create(Part part, Iterator<Object> iterator) {
|
||||
|
||||
if (isGeoNearQuery && part.getType().equals(Type.NEAR)) {
|
||||
return null;
|
||||
@@ -103,7 +102,7 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
||||
where(path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)),
|
||||
(PotentiallyConvertingIterator) iterator);
|
||||
|
||||
return new Query(criteria);
|
||||
return criteria;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -111,7 +110,7 @@ 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)
|
||||
*/
|
||||
@Override
|
||||
protected Query and(Part part, Query base, Iterator<Object> iterator) {
|
||||
protected Criteria and(Part part, Criteria base, Iterator<Object> iterator) {
|
||||
|
||||
if (base == null) {
|
||||
return create(part, iterator);
|
||||
@@ -122,7 +121,8 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
||||
Criteria criteria = from(part.getType(),
|
||||
where(path2.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)),
|
||||
(PotentiallyConvertingIterator) iterator);
|
||||
return base.addCriteria(criteria);
|
||||
|
||||
return criteria.andOperator(criteria);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -133,8 +133,10 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
||||
* #or(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected Query or(Query base, Query query) {
|
||||
return new OrQuery(new Query[] { base, query });
|
||||
protected Criteria or(Criteria base, Criteria criteria) {
|
||||
|
||||
Criteria result = new Criteria();
|
||||
return result.orOperator(base, criteria);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -145,16 +147,17 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Query> {
|
||||
* #complete(java.lang.Object, org.springframework.data.domain.Sort)
|
||||
*/
|
||||
@Override
|
||||
protected Query complete(Query query, Sort sort) {
|
||||
protected Query complete(Criteria criteria, Sort sort) {
|
||||
|
||||
if (query == null) {
|
||||
if (criteria == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Query query = new Query(criteria);
|
||||
QueryUtils.applySorting(query, sort);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Created query " + query.getQueryObject());
|
||||
LOG.debug("Created query " + query);
|
||||
}
|
||||
|
||||
return query;
|
||||
|
||||
@@ -20,11 +20,12 @@ import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
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.
|
||||
*
|
||||
@@ -55,12 +56,9 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.mongodb.repository.AbstractMongoQuery#createQuery(org.springframework.data.
|
||||
* repository.query.SimpleParameterAccessor, org.springframework.data.mongodb.core.core.support.convert.MongoConverter)
|
||||
*/
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery#createQuery(org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor)
|
||||
*/
|
||||
@Override
|
||||
protected Query createQuery(ConvertingParameterAccessor accessor) {
|
||||
|
||||
@@ -99,17 +97,6 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
}
|
||||
|
||||
private String getParameterWithIndex(ConvertingParameterAccessor accessor, int index) {
|
||||
|
||||
Object parameter = accessor.getBindableValue(index);
|
||||
|
||||
if (parameter == null) {
|
||||
return "null";
|
||||
} else if (parameter instanceof String || parameter.getClass().isEnum()) {
|
||||
return String.format("\"%s\"", parameter);
|
||||
} else if (parameter instanceof ObjectId) {
|
||||
return String.format("{ '$oid' : '%s' }", parameter);
|
||||
}
|
||||
|
||||
return parameter.toString();
|
||||
return JSON.serialize(accessor.getBindableValue(index));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.Mongo;
|
||||
@@ -59,7 +60,7 @@ public class MongoDbFactoryParserIntegrationTests {
|
||||
SimpleMongoDbFactory dbFactory = new SimpleMongoDbFactory(new Mongo("localhost"), "database");
|
||||
dbFactory.setWriteConcern(WriteConcern.SAFE);
|
||||
dbFactory.getDb();
|
||||
assertThat(WriteConcern.SAFE, is(dbFactory.getWriteConcern()));
|
||||
assertThat(ReflectionTestUtils.getField(dbFactory, "writeConcern"), is((Object) WriteConcern.SAFE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -91,15 +92,17 @@ public class MongoDbFactoryParserIntegrationTests {
|
||||
private void assertWriteConcern(ClassPathXmlApplicationContext ctx, WriteConcern expectedWriteConcern) {
|
||||
SimpleMongoDbFactory dbFactory = ctx.getBean("first", SimpleMongoDbFactory.class);
|
||||
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 myExpectedWriteConcern = new MyWriteConcern(expectedWriteConcern);
|
||||
|
||||
assertThat(myDbFactoryWriteConcern, equalTo(myExpectedWriteConcern));
|
||||
assertThat(myDbWriteConcern, equalTo(myExpectedWriteConcern));
|
||||
assertThat(myDbWriteConcern, equalTo(myDbFactoryWriteConcern));
|
||||
assertThat(myDbFactoryWriteConcern, is(myExpectedWriteConcern));
|
||||
assertThat(myDbWriteConcern, is(myExpectedWriteConcern));
|
||||
assertThat(myDbWriteConcern, is(myDbFactoryWriteConcern));
|
||||
}
|
||||
|
||||
// This test will fail since equals in WriteConcern uses == for _w and not .equals
|
||||
@@ -108,7 +111,7 @@ public class MongoDbFactoryParserIntegrationTests {
|
||||
String s2 = new String("rack1");
|
||||
WriteConcern wc1 = new WriteConcern(s1);
|
||||
WriteConcern wc2 = new WriteConcern(s2);
|
||||
assertThat(wc1, equalTo(wc2));
|
||||
assertThat(wc1, is(wc2));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.data.mongodb.config;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
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.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.CommandResult;
|
||||
import com.mongodb.Mongo;
|
||||
@@ -36,47 +38,45 @@ import com.mongodb.ServerAddress;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class MongoNamespaceReplicaSetTests extends NamespaceTestSupport {
|
||||
public class MongoNamespaceReplicaSetTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext ctx;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testParsingMongoWithReplicaSets() throws Exception {
|
||||
|
||||
assertTrue(ctx.containsBean("replicaSetMongo"));
|
||||
MongoFactoryBean mfb = (MongoFactoryBean) ctx.getBean("&replicaSetMongo");
|
||||
|
||||
List<ServerAddress> replicaSetSeeds = readField("replicaSetSeeds", mfb);
|
||||
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());
|
||||
List<ServerAddress> replicaSetSeeds = (List<ServerAddress>) ReflectionTestUtils.getField(mfb, "replicaSetSeeds");
|
||||
|
||||
assertThat(replicaSetSeeds, is(notNullValue()));
|
||||
assertThat(replicaSetSeeds, hasItems(new ServerAddress("127.0.0.1", 10001), new ServerAddress("localhost", 10002)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testParsingWithPropertyPlaceHolder() throws Exception {
|
||||
|
||||
assertTrue(ctx.containsBean("manyReplicaSetMongo"));
|
||||
MongoFactoryBean mfb = (MongoFactoryBean) ctx.getBean("&manyReplicaSetMongo");
|
||||
|
||||
List<ServerAddress> replicaSetSeeds = readField("replicaSetSeeds", mfb);
|
||||
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());
|
||||
List<ServerAddress> replicaSetSeeds = (List<ServerAddress>) ReflectionTestUtils.getField(mfb, "replicaSetSeeds");
|
||||
|
||||
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
|
||||
@Ignore("CI infrastructure does not yet support replica sets")
|
||||
public void testMongoWithReplicaSets() {
|
||||
|
||||
Mongo mongo = ctx.getBean(Mongo.class);
|
||||
assertEquals(2, mongo.getAllAddress().size());
|
||||
List<ServerAddress> servers = mongo.getAllAddress();
|
||||
@@ -88,6 +88,5 @@ public class MongoNamespaceReplicaSetTests extends NamespaceTestSupport {
|
||||
MongoTemplate template = new MongoTemplate(mongo, "admin");
|
||||
CommandResult result = template.executeCommand("{replSetGetStatus : 1}");
|
||||
assertEquals("blort", result.getString("set"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,19 @@
|
||||
|
||||
package org.springframework.data.mongodb.config;
|
||||
|
||||
import static org.springframework.test.util.ReflectionTestUtils.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.test.util.ReflectionTestUtils.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.authentication.UserCredentials;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.MongoFactoryBean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoOptions;
|
||||
|
||||
@@ -62,8 +64,7 @@ public class MongoNamespaceTests {
|
||||
Mongo mongo = (Mongo) getField(dbf, "mongo");
|
||||
assertEquals("localhost", mongo.getAddress().getHost());
|
||||
assertEquals(27017, mongo.getAddress().getPort());
|
||||
assertEquals("joe", getField(dbf, "username"));
|
||||
assertEquals("secret", getField(dbf, "password"));
|
||||
assertEquals(new UserCredentials("joe", "secret"), getField(dbf, "credentials"));
|
||||
assertEquals("database", getField(dbf, "databaseName"));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,42 +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,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));
|
||||
}
|
||||
}
|
||||
@@ -130,6 +130,7 @@ public class MongoTemplateTests {
|
||||
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfTypeLong.class));
|
||||
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfPrimitiveLong.class));
|
||||
template.dropCollection(template.getCollectionName(TestClass.class));
|
||||
template.dropCollection(Sample.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -906,8 +907,6 @@ public class MongoTemplateTests {
|
||||
assertThat(lastMongoAction.getEntityClass().toString(), is(PersonWithIdPropertyOfTypeObjectId.class.toString()));
|
||||
assertThat(lastMongoAction.getMongoActionOperation(), is(MongoActionOperation.UPDATE));
|
||||
assertThat(lastMongoAction.getQuery(), equalTo(q.getQueryObject()));
|
||||
assertThat(lastMongoAction.getDocument(), equalTo(u.getUpdateObject()));
|
||||
|
||||
}
|
||||
|
||||
private class FsyncSafeWriteConcernResolver implements WriteConcernResolver {
|
||||
@@ -1080,10 +1079,62 @@ public class MongoTemplateTests {
|
||||
assertThat(template.findOne(query(where("id").is(id)), Sample.class), is(nullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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"));
|
||||
System.out.println(query.getQueryObject());
|
||||
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);
|
||||
}
|
||||
|
||||
static class MyId {
|
||||
|
||||
String first;
|
||||
String second;
|
||||
}
|
||||
|
||||
static class TypeWithMyId {
|
||||
|
||||
@Id
|
||||
MyId id;
|
||||
}
|
||||
|
||||
public static class Sample {
|
||||
|
||||
@Id
|
||||
String id;
|
||||
String field;
|
||||
}
|
||||
|
||||
static class TestClass {
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.SerializationUtils.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Test;
|
||||
|
||||
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;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.authentication.UserCredentials;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
@@ -70,8 +71,8 @@ public class SimpleMongoDbFactoryUnitTests {
|
||||
MongoURI mongoURI = new MongoURI("mongodb://myUsername:myPassword@localhost/myDatabase.myCollection");
|
||||
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoURI);
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "username").toString(), is("myUsername"));
|
||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "password").toString(), is("myPassword"));
|
||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "credentials"), is((Object) new UserCredentials(
|
||||
"myUsername", "myPassword")));
|
||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
|
||||
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.springframework.data.mongodb.core.convert;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.URL;
|
||||
import java.text.DateFormat;
|
||||
import java.text.Format;
|
||||
import java.util.Arrays;
|
||||
@@ -153,13 +154,22 @@ public class CustomConversionsUnitTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-390
|
||||
* @see DATAMONGO-462
|
||||
*/
|
||||
@Test
|
||||
public void convertsUUIDsToBinaryByDefault() {
|
||||
public void hasWriteConverterForURL() {
|
||||
|
||||
CustomConversions conversions = new CustomConversions();
|
||||
assertThat(conversions.hasCustomWriteTarget(UUID.class), is(true));
|
||||
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> {
|
||||
|
||||
@@ -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");
|
||||
* 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
|
||||
* 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,
|
||||
@@ -33,11 +33,12 @@ import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit test to reproduce DATADOC-273.
|
||||
* Unit test to reproduce DATAMONGO-273.
|
||||
*
|
||||
* @author Harlan Iverson
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class DataDoc273Test {
|
||||
public class DataMongo273Tests {
|
||||
|
||||
MappingMongoConverter converter;
|
||||
|
||||
@@ -54,7 +55,7 @@ public class DataDoc273Test {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATADOC-273
|
||||
* @see DATAMONGO-273
|
||||
*/
|
||||
@Test
|
||||
public void convertMapOfThings() {
|
||||
@@ -80,7 +81,7 @@ public class DataDoc273Test {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATADOC-294
|
||||
* @see DATAMONGO-294
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@@ -96,7 +97,6 @@ public class DataDoc273Test {
|
||||
|
||||
DBObject result = new BasicDBList();
|
||||
converter.write(listOfThings, result);
|
||||
System.out.println(result.toString());
|
||||
|
||||
List listOfThings2 = converter.read(List.class, result);
|
||||
|
||||
@@ -106,7 +106,7 @@ public class DataDoc273Test {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATADOC-294
|
||||
* @see DATAMONGO-294
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@@ -121,7 +121,7 @@ public class DataDoc273Test {
|
||||
listOfThings.add(train);
|
||||
listOfThings.add(automobile);
|
||||
|
||||
Map box = new HashMap();
|
||||
Map<String, Object> box = new HashMap<String, Object>();
|
||||
box.put("one", listOfThings);
|
||||
|
||||
Shipment shipment = new Shipment(box);
|
||||
@@ -138,7 +138,7 @@ public class DataDoc273Test {
|
||||
assertTrue(listOfThings2.get(2) instanceof Automobile);
|
||||
}
|
||||
|
||||
class Plane {
|
||||
static class Plane {
|
||||
|
||||
String maker;
|
||||
int numberOfPropellers;
|
||||
@@ -149,7 +149,7 @@ public class DataDoc273Test {
|
||||
}
|
||||
}
|
||||
|
||||
class Train {
|
||||
static class Train {
|
||||
|
||||
String railLine;
|
||||
int numberOfCars;
|
||||
@@ -160,7 +160,7 @@ public class DataDoc273Test {
|
||||
}
|
||||
}
|
||||
|
||||
class Automobile {
|
||||
static class Automobile {
|
||||
|
||||
String make;
|
||||
String model;
|
||||
@@ -174,11 +174,11 @@ public class DataDoc273Test {
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class Shipment {
|
||||
static class Shipment {
|
||||
|
||||
Map boxes = new HashMap();
|
||||
Map<String, Object> boxes;
|
||||
|
||||
public Shipment(Map boxes) {
|
||||
public Shipment(Map<String, Object> boxes) {
|
||||
this.boxes = boxes;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import static org.junit.Assert.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -114,12 +115,30 @@ public class MappingMongoConverterUnitTests {
|
||||
DBObject dbObject = new BasicDBObject();
|
||||
converter.write(person, dbObject);
|
||||
|
||||
assertThat(dbObject.get("birthDate"), is(Date.class));
|
||||
assertThat(dbObject.get("birthDate"), is(instanceOf(Date.class)));
|
||||
|
||||
Person result = converter.read(Person.class, dbObject);
|
||||
assertThat(result.birthDate, is(notNullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertsCustomTypeOnConvertToMongoType() {
|
||||
|
||||
List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
|
||||
converters.add(new LocalDateToDateConverter());
|
||||
converters.add(new DateToLocalDateConverter());
|
||||
|
||||
CustomConversions conversions = new CustomConversions(converters);
|
||||
mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
|
||||
|
||||
converter = new MappingMongoConverter(factory, mappingContext);
|
||||
converter.setCustomConversions(conversions);
|
||||
converter.afterPropertiesSet();
|
||||
|
||||
LocalDate date = new LocalDate();
|
||||
converter.convertToMongoType(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-130
|
||||
*/
|
||||
@@ -157,7 +176,7 @@ public class MappingMongoConverterUnitTests {
|
||||
dbObject.put("birthDate", new LocalDate());
|
||||
dbObject.put(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Person.class.getName());
|
||||
|
||||
assertThat(converter.read(Contact.class, dbObject), is(Person.class));
|
||||
assertThat(converter.read(Contact.class, dbObject), is(instanceOf(Person.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,7 +189,7 @@ public class MappingMongoConverterUnitTests {
|
||||
dbObject.put("birthDate", new LocalDate());
|
||||
dbObject.put(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Person.class.getName());
|
||||
|
||||
assertThat(converter.read(BirthDateContainer.class, dbObject), is(BirthDateContainer.class));
|
||||
assertThat(converter.read(BirthDateContainer.class, dbObject), is(instanceOf(BirthDateContainer.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -198,7 +217,7 @@ public class MappingMongoConverterUnitTests {
|
||||
DBObject result = new BasicDBObject();
|
||||
converter.write(value, result);
|
||||
|
||||
assertThat(result.get("sampleEnum"), is(String.class));
|
||||
assertThat(result.get("sampleEnum"), is(instanceOf(String.class)));
|
||||
assertThat(result.get("sampleEnum").toString(), is("FIRST"));
|
||||
}
|
||||
|
||||
@@ -214,7 +233,7 @@ public class MappingMongoConverterUnitTests {
|
||||
DBObject result = new BasicDBObject();
|
||||
converter.write(value, result);
|
||||
|
||||
assertThat(result.get("enums"), is(BasicDBList.class));
|
||||
assertThat(result.get("enums"), is(instanceOf(BasicDBList.class)));
|
||||
|
||||
BasicDBList enums = (BasicDBList) result.get("enums");
|
||||
assertThat(enums.size(), is(1));
|
||||
@@ -244,7 +263,7 @@ public class MappingMongoConverterUnitTests {
|
||||
|
||||
ClassWithEnumProperty result = converter.read(ClassWithEnumProperty.class, dbObject);
|
||||
|
||||
assertThat(result.enums, is(List.class));
|
||||
assertThat(result.enums, is(instanceOf(List.class)));
|
||||
assertThat(result.enums.size(), is(1));
|
||||
assertThat(result.enums, hasItem(SampleEnum.FIRST));
|
||||
}
|
||||
@@ -309,7 +328,7 @@ public class MappingMongoConverterUnitTests {
|
||||
converter.write(wrapper, dbObject);
|
||||
|
||||
Object result = dbObject.get("contacts");
|
||||
assertThat(result, is(BasicDBList.class));
|
||||
assertThat(result, is(instanceOf(BasicDBList.class)));
|
||||
BasicDBList contacts = (BasicDBList) result;
|
||||
DBObject personDbObject = (DBObject) contacts.get(0);
|
||||
assertThat(personDbObject.get("foo").toString(), is("Oliver"));
|
||||
@@ -332,7 +351,7 @@ public class MappingMongoConverterUnitTests {
|
||||
assertThat(result.contacts, is(notNullValue()));
|
||||
assertThat(result.contacts.size(), is(1));
|
||||
Contact contact = result.contacts.get(0);
|
||||
assertThat(contact, is(Person.class));
|
||||
assertThat(contact, is(instanceOf(Person.class)));
|
||||
assertThat(((Person) contact).firstname, is("Oliver"));
|
||||
|
||||
}
|
||||
@@ -346,7 +365,7 @@ public class MappingMongoConverterUnitTests {
|
||||
converter.write(wrapper, dbObject);
|
||||
|
||||
Object localeField = dbObject.get("locale");
|
||||
assertThat(localeField, is(String.class));
|
||||
assertThat(localeField, is(instanceOf(String.class)));
|
||||
assertThat((String) localeField, is("en_US"));
|
||||
|
||||
LocaleWrapper read = converter.read(LocaleWrapper.class, dbObject);
|
||||
@@ -454,13 +473,13 @@ public class MappingMongoConverterUnitTests {
|
||||
DBObject dbo1 = new BasicDBObject();
|
||||
|
||||
converter.write(p1, dbo1);
|
||||
assertThat(dbo1.get("_id"), is(String.class));
|
||||
assertThat(dbo1.get("_id"), is(instanceOf(String.class)));
|
||||
|
||||
PersonPojoStringId p2 = new PersonPojoStringId(new ObjectId().toString(), "Text-1");
|
||||
DBObject dbo2 = new BasicDBObject();
|
||||
|
||||
converter.write(p2, dbo2);
|
||||
assertThat(dbo2.get("_id"), is(ObjectId.class));
|
||||
assertThat(dbo2.get("_id"), is(instanceOf(ObjectId.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -474,8 +493,8 @@ public class MappingMongoConverterUnitTests {
|
||||
|
||||
ClassWithSortedMap result = converter.read(ClassWithSortedMap.class, wrapper);
|
||||
|
||||
assertThat(result, is(ClassWithSortedMap.class));
|
||||
assertThat(result.map, is(SortedMap.class));
|
||||
assertThat(result, is(instanceOf(ClassWithSortedMap.class)));
|
||||
assertThat(result.map, is(instanceOf(SortedMap.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -741,7 +760,7 @@ public class MappingMongoConverterUnitTests {
|
||||
|
||||
assertThat(result.containsField("Foo"), is(true));
|
||||
assertThat(result.get("Foo"), is(notNullValue()));
|
||||
assertThat(result.get("Foo"), is(BasicDBList.class));
|
||||
assertThat(result.get("Foo"), is(instanceOf(BasicDBList.class)));
|
||||
|
||||
BasicDBList list = (BasicDBList) result.get("Foo");
|
||||
|
||||
@@ -792,11 +811,11 @@ public class MappingMongoConverterUnitTests {
|
||||
converter.write(wrapper, result);
|
||||
|
||||
Object mapObject = result.get("mapOfObjects");
|
||||
assertThat(mapObject, is(BasicDBObject.class));
|
||||
assertThat(mapObject, is(instanceOf(BasicDBObject.class)));
|
||||
|
||||
DBObject map = (DBObject) mapObject;
|
||||
Object valueObject = map.get("foo");
|
||||
assertThat(valueObject, is(BasicDBList.class));
|
||||
assertThat(valueObject, is(instanceOf(BasicDBList.class)));
|
||||
|
||||
List<Object> list = (List<Object>) valueObject;
|
||||
assertThat(list.size(), is(1));
|
||||
@@ -887,7 +906,7 @@ public class MappingMongoConverterUnitTests {
|
||||
converter.write(wrapper, result);
|
||||
|
||||
Object contacts = result.get("contacts");
|
||||
assertThat(contacts, is(Collection.class));
|
||||
assertThat(contacts, is(instanceOf(Collection.class)));
|
||||
assertThat(((Collection<?>) contacts).size(), is(2));
|
||||
assertThat(((Collection<Object>) contacts), hasItem(nullValue()));
|
||||
}
|
||||
@@ -950,7 +969,7 @@ public class MappingMongoConverterUnitTests {
|
||||
Item read = converter.read(Item.class, result);
|
||||
assertThat(read.attributes.size(), is(1));
|
||||
assertThat(read.attributes.get(0).key, is(attribute.key));
|
||||
assertThat(read.attributes.get(0).value, is(Collection.class));
|
||||
assertThat(read.attributes.get(0).value, is(instanceOf(Collection.class)));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<String> values = (Collection<String>) read.attributes.get(0).value;
|
||||
@@ -998,6 +1017,48 @@ public class MappingMongoConverterUnitTests {
|
||||
assertThat(result.containsKey("foobar"), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-382
|
||||
*/
|
||||
@Test
|
||||
public void convertsSetToBasicDBList() {
|
||||
|
||||
Address address = new Address();
|
||||
address.city = "London";
|
||||
address.street = "Foo";
|
||||
|
||||
Object result = converter.convertToMongoType(Collections.singleton(address));
|
||||
assertThat(result, is(instanceOf(BasicDBList.class)));
|
||||
|
||||
Set<?> readResult = converter.read(Set.class, (BasicDBList) result);
|
||||
assertThat(readResult.size(), is(1));
|
||||
assertThat(readResult.iterator().next(), is(instanceOf(Map.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-462
|
||||
*/
|
||||
@Test
|
||||
public void readsURLsAsStringsByDefault() throws Exception {
|
||||
DBObject dbObject = new BasicDBObject("url", new URL("http://springsource.org"));
|
||||
URLWrapper result = converter.read(URLWrapper.class, dbObject);
|
||||
assertThat(result.url, is(new URL("http://springsource.org")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-462
|
||||
*/
|
||||
@Test
|
||||
public void writesURLsAsStringsByDefault() throws Exception {
|
||||
|
||||
URLWrapper wrapper = new URLWrapper();
|
||||
wrapper.url = new URL("http://springsource.org");
|
||||
DBObject sink = new BasicDBObject();
|
||||
|
||||
converter.write(wrapper, sink);
|
||||
assertThat(sink.get("url"), is((Object) "http://springsource.org"));
|
||||
}
|
||||
|
||||
static class GenericType<T> {
|
||||
T content;
|
||||
}
|
||||
@@ -1129,6 +1190,10 @@ public class MappingMongoConverterUnitTests {
|
||||
Object value;
|
||||
}
|
||||
|
||||
static class URLWrapper {
|
||||
URL url;
|
||||
}
|
||||
|
||||
private class LocalDateToDateConverter implements Converter<LocalDate, Date> {
|
||||
|
||||
public Date convert(LocalDate source) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -19,15 +19,10 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bson.BSON;
|
||||
import org.bson.types.Binary;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BinaryToUUIDConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.UUIDToBinaryConverter;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MongoConverters}.
|
||||
@@ -46,20 +41,4 @@ public class MongoConvertersUnitTests {
|
||||
BigDecimal reference = StringToBigDecimalConverter.INSTANCE.convert(value);
|
||||
assertThat(reference, is(bigDecimal));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-390
|
||||
*/
|
||||
@Test
|
||||
public void convertsUUIDToBinaryCorrectly() {
|
||||
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Binary binary = UUIDToBinaryConverter.INSTANCE.convert(uuid);
|
||||
|
||||
assertThat(binary, is(notNullValue()));
|
||||
assertThat(binary.getType(), is(BSON.B_UUID));
|
||||
|
||||
UUID result = BinaryToUUIDConverter.INSTANCE.convert(binary);
|
||||
assertThat(result, is(uuid));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,14 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
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.Venue;
|
||||
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.Order;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.monitor.ServerInfo;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
@@ -192,6 +196,26 @@ public class GeoSpatialTests {
|
||||
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
|
||||
public List<DBObject> getIndexInfo(Class<?> clazz) {
|
||||
return template.execute(clazz, new CollectionCallback<List<DBObject>>() {
|
||||
|
||||
@@ -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.index;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link IndexField}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class IndexFieldUnitTests {
|
||||
|
||||
@Test
|
||||
public void createsPlainIndexFieldCorrectly() {
|
||||
|
||||
IndexField field = IndexField.create("foo", Order.ASCENDING);
|
||||
|
||||
assertThat(field.getKey(), is("foo"));
|
||||
assertThat(field.getOrder(), is(Order.ASCENDING));
|
||||
assertThat(field.isGeo(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createsGeoIndexFieldCorrectly() {
|
||||
|
||||
IndexField field = IndexField.geo("foo");
|
||||
|
||||
assertThat(field.getKey(), is("foo"));
|
||||
assertThat(field.getOrder(), is(nullValue()));
|
||||
assertThat(field.isGeo(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctEqualsForPlainFields() {
|
||||
|
||||
IndexField first = IndexField.create("foo", Order.ASCENDING);
|
||||
IndexField second = IndexField.create("foo", Order.ASCENDING);
|
||||
|
||||
assertThat(first, is(second));
|
||||
assertThat(second, is(first));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctEqualsForGeoFields() {
|
||||
|
||||
IndexField first = IndexField.geo("bar");
|
||||
IndexField second = IndexField.geo("bar");
|
||||
|
||||
assertThat(first, is(second));
|
||||
assertThat(second, is(first));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.mapreduce;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MapReduceResults}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MapReduceResultsUnitTests {
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-428
|
||||
*/
|
||||
@Test
|
||||
public void resolvesOutputCollectionForPlainResult() {
|
||||
|
||||
DBObject rawResult = new BasicDBObject("result", "FOO");
|
||||
MapReduceResults<Object> results = new MapReduceResults<Object>(Collections.emptyList(), rawResult);
|
||||
|
||||
assertThat(results.getOutputCollection(), is("FOO"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-428
|
||||
*/
|
||||
@Test
|
||||
public void resolvesOutputCollectionForDBObjectResult() {
|
||||
|
||||
DBObject rawResult = new BasicDBObject("result", new BasicDBObject("collection", "FOO"));
|
||||
MapReduceResults<Object> results = new MapReduceResults<Object>(Collections.emptyList(), rawResult);
|
||||
|
||||
assertThat(results.getOutputCollection(), is("FOO"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-378
|
||||
*/
|
||||
@Test
|
||||
public void handlesLongTotalInResult() {
|
||||
|
||||
DBObject inner = new BasicDBObject("total", 1L);
|
||||
inner.put("mapTime", 1L);
|
||||
inner.put("emitLoop", 1);
|
||||
|
||||
DBObject source = new BasicDBObject("timing", inner);
|
||||
new MapReduceResults<Object>(Collections.emptyList(), source);
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
* 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
|
||||
* 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,
|
||||
@@ -84,7 +84,7 @@ public class QueryMapperUnitTests {
|
||||
|
||||
DBObject query = new BasicDBObject("_id", new ObjectId().toString());
|
||||
DBObject result = mapper.getMappedObject(query, null);
|
||||
assertThat(result.get("_id"), is(ObjectId.class));
|
||||
assertThat(result.get("_id"), is(instanceOf(ObjectId.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -114,9 +114,9 @@ public class QueryMapperUnitTests {
|
||||
|
||||
DBObject result = mapper.getMappedObject(criteria.getCriteriaObject(), context.getPersistentEntity(Sample.class));
|
||||
Object object = result.get("_id");
|
||||
assertThat(object, is(DBObject.class));
|
||||
assertThat(object, is(instanceOf(DBObject.class)));
|
||||
DBObject dbObject = (DBObject) object;
|
||||
assertThat(dbObject.get("$ne"), is(ObjectId.class));
|
||||
assertThat(dbObject.get("$ne"), is(instanceOf(ObjectId.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +128,7 @@ public class QueryMapperUnitTests {
|
||||
DBObject result = mapper.getMappedObject(query.getQueryObject(), null);
|
||||
|
||||
Object object = result.get("foo");
|
||||
assertThat(object, is(String.class));
|
||||
assertThat(object, is(instanceOf(String.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -137,10 +137,10 @@ public class QueryMapperUnitTests {
|
||||
DBObject result = mapper.getMappedObject(query.getQueryObject(), null);
|
||||
|
||||
Object object = result.get("foo");
|
||||
assertThat(object, is(DBObject.class));
|
||||
assertThat(object, is(instanceOf(DBObject.class)));
|
||||
|
||||
Object ne = ((DBObject) object).get("$ne");
|
||||
assertThat(ne, is(String.class));
|
||||
assertThat(ne, is(instanceOf(String.class)));
|
||||
assertThat(ne.toString(), is(Enum.INSTANCE.name()));
|
||||
}
|
||||
|
||||
@@ -151,14 +151,14 @@ public class QueryMapperUnitTests {
|
||||
DBObject result = mapper.getMappedObject(query.getQueryObject(), null);
|
||||
|
||||
Object object = result.get("foo");
|
||||
assertThat(object, is(DBObject.class));
|
||||
assertThat(object, is(instanceOf(DBObject.class)));
|
||||
|
||||
Object in = ((DBObject) object).get("$in");
|
||||
assertThat(in, is(BasicDBList.class));
|
||||
assertThat(in, is(instanceOf(BasicDBList.class)));
|
||||
|
||||
BasicDBList list = (BasicDBList) in;
|
||||
assertThat(list.size(), is(1));
|
||||
assertThat(list.get(0), is(String.class));
|
||||
assertThat(list.get(0), is(instanceOf(String.class)));
|
||||
assertThat(list.get(0).toString(), is(Enum.INSTANCE.name()));
|
||||
}
|
||||
|
||||
@@ -186,6 +186,18 @@ public class QueryMapperUnitTests {
|
||||
assertThat(result.get("bar"), is(notNullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-429
|
||||
*/
|
||||
@Test
|
||||
public void transformsArraysCorrectly() {
|
||||
|
||||
Query query = new BasicQuery("{ 'tags' : { '$all' : [ 'green', 'orange']}}");
|
||||
|
||||
DBObject result = mapper.getMappedObject(query.getQueryObject(), null);
|
||||
assertThat(result, is(query.getQueryObject()));
|
||||
}
|
||||
|
||||
class Sample {
|
||||
|
||||
@Id
|
||||
|
||||
@@ -100,7 +100,7 @@ public class QueryTests {
|
||||
public void testComplexQueryWithMultipleChainedCriteria() {
|
||||
Query q = new Query(where("name").regex("^T.*").and("age").gt(20).lt(80).and("city")
|
||||
.in("Stockholm", "London", "New York"));
|
||||
String expected = "{ \"name\" : { \"$regex\" : \"^T.*\"} , \"age\" : { \"$gt\" : 20 , \"$lt\" : 80} , "
|
||||
String expected = "{ \"name\" : { \"$regex\" : \"^T.*\" , \"$options\" : \"\"} , \"age\" : { \"$gt\" : 20 , \"$lt\" : 80} , "
|
||||
+ "\"city\" : { \"$in\" : [ \"Stockholm\" , \"London\" , \"New York\"]}}";
|
||||
Assert.assertEquals(expected, q.getQueryObject().toString());
|
||||
}
|
||||
@@ -134,7 +134,7 @@ public class QueryTests {
|
||||
@Test
|
||||
public void testQueryWithRegex() {
|
||||
Query q = new Query(where("name").regex("b.*"));
|
||||
String expected = "{ \"name\" : { \"$regex\" : \"b.*\"}}";
|
||||
String expected = "{ \"name\" : { \"$regex\" : \"b.*\" , \"$options\" : \"\"}}";
|
||||
Assert.assertEquals(expected, q.getQueryObject().toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,6 +32,7 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.geo.Box;
|
||||
import org.springframework.data.mongodb.core.geo.Circle;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
@@ -53,19 +54,24 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
protected PersonRepository repository;
|
||||
|
||||
@Autowired
|
||||
MongoOperations operations;
|
||||
|
||||
Person dave, oliver, carter, boyd, stefan, leroi, alicia;
|
||||
QPerson person;
|
||||
|
||||
List<Person> all;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
public void setUp() throws InterruptedException {
|
||||
|
||||
repository.deleteAll();
|
||||
|
||||
dave = new Person("Dave", "Matthews", 42);
|
||||
oliver = new Person("Oliver August", "Matthews", 4);
|
||||
carter = new Person("Carter", "Beauford", 49);
|
||||
Thread.sleep(10);
|
||||
boyd = new Person("Boyd", "Tinsley", 45);
|
||||
stefan = new Person("Stefan", "Lessard", 34);
|
||||
leroi = new Person("Leroi", "Moore", 41);
|
||||
@@ -304,6 +310,16 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
|
||||
assertThat(females.get(0), is(alicia));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-446
|
||||
*/
|
||||
@Test
|
||||
public void findsPeopleBySexPaginated() {
|
||||
|
||||
List<Person> males = repository.findBySex(Sex.MALE, new PageRequest(0, 2));
|
||||
assertThat(males.size(), is(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsPeopleByNamedQuery() {
|
||||
List<Person> result = repository.findByNamedQuery("Dave");
|
||||
@@ -396,4 +412,24 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
|
||||
assertThat(result.get(5), is(oliver));
|
||||
assertThat(result.get(6), is(stefan));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-425
|
||||
*/
|
||||
@Test
|
||||
public void bindsDateParameterForDerivedQueryCorrectly() {
|
||||
|
||||
List<Person> result = repository.findByCreatedAtLessThan(boyd.createdAt);
|
||||
assertThat(result.isEmpty(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-425
|
||||
*/
|
||||
@Test
|
||||
public void bindsDateParameterForManuallyDefinedQueryCorrectly() {
|
||||
|
||||
List<Person> result = repository.findByCreatedAtLessThanManually(boyd.createdAt);
|
||||
assertThat(result.isEmpty(), is(false));
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
@@ -41,6 +42,7 @@ public class Person extends Contact {
|
||||
private Integer age;
|
||||
@SuppressWarnings("unused")
|
||||
private Sex sex;
|
||||
Date createdAt;
|
||||
|
||||
@GeoSpatialIndexed
|
||||
private Point location;
|
||||
@@ -71,6 +73,7 @@ public class Person extends Contact {
|
||||
this.age = age;
|
||||
this.sex = sex;
|
||||
this.email = (firstname == null ? "noone" : firstname.toLowerCase()) + "@dmband.com";
|
||||
this.createdAt = new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.mongodb.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -146,9 +147,22 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
|
||||
|
||||
List<Person> findBySex(Sex sex);
|
||||
|
||||
List<Person> findBySex(Sex sex, Pageable pageable);
|
||||
|
||||
List<Person> findByNamedQuery(String firstname);
|
||||
|
||||
GeoResults<Person> findByLocationNear(Point point, Distance maxDistance);
|
||||
|
||||
GeoPage<Person> findByLocationNear(Point point, Distance maxDistance, Pageable pageable);
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-425
|
||||
*/
|
||||
List<Person> findByCreatedAtLessThan(Date date);
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-425
|
||||
*/
|
||||
@Query("{ 'createdAt' : { '$lt' : ?0 }}")
|
||||
List<Person> findByCreatedAtLessThanManually(Date date);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public class RepositoryIndexCreationIntegrationTests {
|
||||
|
||||
assertThat(indexInfo.isEmpty(), is(false));
|
||||
assertThat(indexInfo.size(), is(greaterThan(2)));
|
||||
assertThat(getIndexNamesFrom(indexInfo), hasItems("findByLastname", "findByFirstnameNotIn"));
|
||||
assertThat(getIndexNamesFrom(indexInfo), hasItems("findByLastnameLike", "findByFirstnameLike"));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class MongoNamespaceIntegrationTests extends AbstractPersonRepositoryInte
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() {
|
||||
public void setUp() throws InterruptedException {
|
||||
super.setUp();
|
||||
factory = new DefaultListableBeanFactory();
|
||||
reader = new XmlBeanDefinitionReader(factory);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -211,6 +211,20 @@ public class MongoQueryCreatorUnitTests {
|
||||
assertThat(creator.createQuery().getQueryObject(), is(query.getQueryObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO
|
||||
*/
|
||||
@Test
|
||||
public void createsOrQueryCorrectly() {
|
||||
|
||||
PartTree tree = new PartTree("findByFirstNameOrAge", Person.class);
|
||||
MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, "Dave", 42), context);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
assertThat(query.getQueryObject(),
|
||||
is(query(new Criteria().orOperator(where("firstName").is("Dave"), where("age").is(42))).getQueryObject()));
|
||||
}
|
||||
|
||||
private void assertBindsDistanceToQuery(Point point, Distance distance, Query reference) throws Exception {
|
||||
|
||||
when(converter.convertToMongoType("Dave")).thenReturn("Dave");
|
||||
|
||||
@@ -77,12 +77,12 @@ public class SpringDataMongodbSerializerUnitTests {
|
||||
address.zipCode = "01234";
|
||||
|
||||
DBObject result = serializer.asDBObject("foo", address);
|
||||
assertThat(result, is(BasicDBObject.class));
|
||||
assertThat(result, is(instanceOf(BasicDBObject.class)));
|
||||
BasicDBObject dbObject = (BasicDBObject) result;
|
||||
|
||||
Object value = dbObject.get("foo");
|
||||
assertThat(value, is(notNullValue()));
|
||||
assertThat(value, is(BasicDBObject.class));
|
||||
assertThat(value, is(instanceOf(BasicDBObject.class)));
|
||||
|
||||
Object reference = converter.convertToMongoType(address);
|
||||
assertThat(value, is(reference));
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
<para>If you encounter a bug or want to suggest an improvement, please
|
||||
create a ticket on the Spring Data issue <ulink
|
||||
url="https://jira.springframework.org/browse/DATAKV">tracker</ulink>.</para>
|
||||
url="https://jira.springframework.org/browse/DATAMONGO">tracker</ulink>.</para>
|
||||
|
||||
<para>To stay up to date with the latest news and announcements in the
|
||||
Spring eco system, subscribe to the Spring Community <ulink
|
||||
|
||||
@@ -86,7 +86,5 @@
|
||||
Book</ulink>"</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para />
|
||||
</section></para>
|
||||
</partintro>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<partintro>
|
||||
<title>Document Structure</title>
|
||||
|
||||
@@ -15,6 +18,4 @@
|
||||
introduces the repository support for MongoDB.
|
||||
</para>
|
||||
|
||||
<!-- <para><xref linkend="couch.core"/> introduces the CouchDB module feature set.</para> -->
|
||||
|
||||
</partintro>
|
||||
@@ -251,7 +251,7 @@ public class MongoApp {
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>spring-data-mongodb-1.0.0.RELEASE.jar</para>
|
||||
<para>spring-data-mongodb-1.0.2.RELEASE.jar</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
@@ -624,7 +624,7 @@ public class MongoConfiguration {
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para></para>
|
||||
<para/>
|
||||
</section>
|
||||
|
||||
<section id="mongo.mongo-db-factory-xml">
|
||||
@@ -686,7 +686,7 @@ public class MongoConfiguration {
|
||||
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
|
||||
</bean></programlisting>
|
||||
|
||||
<para></para>
|
||||
<para/>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -1546,8 +1546,17 @@ assertThat(p.getAge(), is(1));</programlisting>
|
||||
follow a fluent API style so that you can easily chain together multiple
|
||||
method criteria and queries while having easy to understand code. Static
|
||||
imports in Java are used to help remove the need to see the 'new' keyword
|
||||
for creating Query and Criteria instances so as to improve
|
||||
readability.</para>
|
||||
for creating <classname>Query</classname> and
|
||||
<classname>Criteria</classname> instances so as to improve readability. If
|
||||
you like to create <classname>Query</classname> instances from a plain
|
||||
JSON String use <classname>BasicQuery</classname>.</para>
|
||||
|
||||
<example>
|
||||
<title>Creating a Query instance from a plain JSON String</title>
|
||||
|
||||
<programlisting language="java">BasicQuery query = new BasicQuery("{ age : { $lt : 50 }, accounts.balance : { $gt : 1000.00 }}");
|
||||
List<Person> result = mongoTemplate.find(query, Person.class); </programlisting>
|
||||
</example>
|
||||
|
||||
<para>GeoSpatial queries are also supported and are described more in the
|
||||
section <link linkend="mongo.geospatial">GeoSpatial Queries</link>.</para>
|
||||
@@ -1572,10 +1581,10 @@ assertThat(p.getAge(), is(1));</programlisting>
|
||||
<programlisting language="java">import static org.springframework.data.mongodb.core.query.Criteria.where;
|
||||
import static org.springframework.data.mongodb.core.query.Query.query;
|
||||
|
||||
...
|
||||
…
|
||||
|
||||
List<Person> result = mongoTemplate.find(query(where("age").lt(50).and("accounts.balance").gt(1000.00d)), Person.class);
|
||||
</programlisting>
|
||||
List<Person> result = mongoTemplate.find(query(where("age").lt(50)
|
||||
.and("accounts.balance").gt(1000.00d)), Person.class); </programlisting>
|
||||
</example>
|
||||
|
||||
<para>All find methods take a <classname>Query</classname> object as a
|
||||
@@ -1769,7 +1778,7 @@ import static org.springframework.data.mongodb.core.query.Query.query;
|
||||
<para><literal>Criteria</literal> <emphasis role="bold">withinBox
|
||||
</emphasis> <literal>(Box box)</literal> Creates a geospatial
|
||||
criterion using a <literal>$within $box</literal> operation
|
||||
<literal /></para>
|
||||
<literal/></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
@@ -2722,4 +2731,4 @@ mongoTemplate.dropCollection("MyNewCollection"); </programlisting>
|
||||
}
|
||||
});</programlisting>
|
||||
</section>
|
||||
</chapter>
|
||||
</chapter>
|
||||
|
||||
@@ -1,6 +1,34 @@
|
||||
Spring Data Document Changelog
|
||||
=============================================
|
||||
|
||||
Changes in version 1.0.2.RELEASE MongoDB (2012-06-20)
|
||||
-----------------------------------------------------
|
||||
** Bug
|
||||
* [DATAMONGO-360] - java.lang.ClassCastException when placing GeospatialIndex into IndexOperations and invoking IndexOperations.getIndexInfo()
|
||||
* [DATAMONGO-366] - Chapter 3.2. points to wrong bugtracker
|
||||
* [DATAMONGO-378] - MapReduceResults ClassCastException due to raw results counts as Long
|
||||
* [DATAMONGO-411] - Potential ClassCastExceptions in MongoPersistentEntityIndexCreator
|
||||
* [DATAMONGO-412] - getUserCredentials() is called twice in AbstractMongoConfiguration::mongoDbFactory()
|
||||
* [DATAMONGO-413] - Using "Or" in repository query yields a ClassCastException
|
||||
* [DATAMONGO-422] - UUIDToBinaryConverter not compatible with mongo java driver
|
||||
* [DATAMONGO-423] - Criteria.regex should use java.util.Pattern instead of $regex
|
||||
* [DATAMONGO-425] - Binding a Date to a manually defined repository query fails
|
||||
* [DATAMONGO-428] - ClassCastException when using outputDatabase option in map-reduce
|
||||
* [DATAMONGO-429] - using @Query annotation, arrays are translated somewhere between query creation and mongo interpretation
|
||||
* [DATAMONGO-446] - Pageable query methods returning List are broken
|
||||
* [DATAMONGO-447] - Removal of Documents fails in in debug mode for Documents with complex ids
|
||||
* [DATAMONGO-450] - enabling DEBUG causes RuntimeException
|
||||
* [DATAMONGO-454] - ServerAddressPropertyEditor fails if a hostname is unresolvable
|
||||
* [DATAMONGO-461] - MappedConstructor potentially throws NullPointerException
|
||||
* [DATAMONGO-462] - findAll() fails with NPE - discovering the root cause
|
||||
|
||||
** Improvement
|
||||
* [DATAMONGO-448] - Remove the need for Converters for complex classes that are used as IDs
|
||||
* [DATAMONGO-455] - Document how to use raw queries using BasicQuery
|
||||
|
||||
** Task
|
||||
* [DATAMONGO-463] - Release 1.0.2
|
||||
|
||||
Changes in version 1.0.1.RELEASE MongoDB (2012-02-11)
|
||||
-----------------------------------------------------
|
||||
** Bug
|
||||
|
||||
Reference in New Issue
Block a user