Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ca297df50 | ||
|
|
22078d9bb0 | ||
|
|
adfa7cdd88 | ||
|
|
88deac4ca7 | ||
|
|
0275e6fb4c | ||
|
|
291b89a8b6 | ||
|
|
fe9d086334 | ||
|
|
cf4db90a7f | ||
|
|
dc67830c6f | ||
|
|
33004f217d | ||
|
|
72adb309ee | ||
|
|
2e493ea8c5 | ||
|
|
f0fc3961d2 | ||
|
|
f80fd92692 | ||
|
|
87ef66cb12 | ||
|
|
332d9d95f4 | ||
|
|
c18d6381aa | ||
|
|
53697179c3 | ||
|
|
7b3acb2890 | ||
|
|
d1ac323e4a | ||
|
|
b1068687bb | ||
|
|
6eae6d3e2c | ||
|
|
abfb98afe1 | ||
|
|
f361368893 | ||
|
|
063438002b | ||
|
|
9b54a5cd39 | ||
|
|
14360f2ab4 | ||
|
|
81c368c851 | ||
|
|
cf3818e04c | ||
|
|
da9870504f | ||
|
|
1285f4f26e | ||
|
|
791938f05d | ||
|
|
1b2d98dd3d | ||
|
|
de364c65ab | ||
|
|
57a74b0427 | ||
|
|
f35df8fe69 | ||
|
|
2d3aac1826 | ||
|
|
15db4ba6ea | ||
|
|
f02ac5ea44 | ||
|
|
86633e01db | ||
|
|
5fe3763f9c | ||
|
|
d1e2b143f3 | ||
|
|
61ab232bc1 | ||
|
|
443cde6236 | ||
|
|
b23796fb45 | ||
|
|
605f7459f7 | ||
|
|
ef6db5970b | ||
|
|
47a5a32713 | ||
|
|
1675528fc7 | ||
|
|
3455cbc634 | ||
|
|
ed779e52b7 | ||
|
|
c70898b019 |
@@ -26,7 +26,7 @@ Add the Maven dependency:
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.4.1.RELEASE</version>
|
||||
<version>1.4.2.RELEASE</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
||||
22
pom.xml
22
pom.xml
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.5.0.M1</version>
|
||||
<version>1.4.4.BUILD-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Data MongoDB</name>
|
||||
@@ -15,10 +15,10 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>1.4.0.M1</version>
|
||||
<version>1.3.4.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../spring-data-build/parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
<modules>
|
||||
<module>spring-data-mongodb</module>
|
||||
<module>spring-data-mongodb-cross-store</module>
|
||||
@@ -29,7 +29,7 @@
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>1.8.0.M1</springdata.commons>
|
||||
<springdata.commons>1.7.4.BUILD-SNAPSHOT</springdata.commons>
|
||||
<mongo>2.11.4</mongo>
|
||||
<mongo-osgi>${mongo}</mongo-osgi>
|
||||
</properties>
|
||||
@@ -107,7 +107,7 @@
|
||||
<profile>
|
||||
<id>mongo-next</id>
|
||||
<properties>
|
||||
<mongo>2.12.0-rc0</mongo>
|
||||
<mongo>2.12.0</mongo>
|
||||
<mongo-osgi>2.12.0</mongo-osgi>
|
||||
</properties>
|
||||
</profile>
|
||||
@@ -124,10 +124,14 @@
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-milestone</id>
|
||||
<url>http://repo.spring.io/libs-milestone/</url>
|
||||
<id>spring-libs-snapshopt</id>
|
||||
<url>http://repo.spring.io/libs-snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<repository>
|
||||
<id>spring-libs-snapshot</id>
|
||||
<url>http://repo.spring.io/libs-snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.5.0.M1</version>
|
||||
<version>1.4.4.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.5.0.M1</version>
|
||||
<version>1.4.4.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -56,17 +56,13 @@
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectj}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JPA -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
<version>${jpa}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- For Tests -->
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.5.0.M1</version>
|
||||
<version>1.4.4.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.5.0.M1</version>
|
||||
<version>1.4.4.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -5,6 +5,15 @@
|
||||
<element type="IncludeTypePattern" name="org.springframework.data.mongodb.**"/>
|
||||
</element>
|
||||
<architecture>
|
||||
<element type="Layer" name="Config">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="WeakTypePattern" name="**.config.**"/>
|
||||
</element>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|GridFS" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Monitoring" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Repositories" type="AllowedDependency"/>
|
||||
</element>
|
||||
<element type="Layer" name="Repositories">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.repository.**"/>
|
||||
@@ -31,20 +40,10 @@
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.config.**"/>
|
||||
</element>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Repositories::Subsystem|Implementation" type="AllowedDependency"/>
|
||||
</element>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Config" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core" type="AllowedDependency"/>
|
||||
</element>
|
||||
<element type="Layer" name="Config">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="WeakTypePattern" name="**.config.**"/>
|
||||
</element>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|GridFS" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Monitoring" type="AllowedDependency"/>
|
||||
</element>
|
||||
<element type="Layer" name="Monitoring">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.monitor.**"/>
|
||||
@@ -58,39 +57,41 @@
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core" type="AllowedDependency"/>
|
||||
</element>
|
||||
<element type="Layer" name="Core">
|
||||
<element type="TypeFilter" name="Assignment"/>
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.core.**"/>
|
||||
</element>
|
||||
<element type="Subsystem" name="Mapping">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.core.mapping.**"/>
|
||||
<element type="IncludeTypePattern" name="**.mapping.**"/>
|
||||
</element>
|
||||
</element>
|
||||
<element type="Subsystem" name="Geospatial">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.core.geo.**"/>
|
||||
<element type="IncludeTypePattern" name="**.geo.**"/>
|
||||
</element>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping" type="AllowedDependency"/>
|
||||
</element>
|
||||
<element type="Subsystem" name="Query">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.core.query.**"/>
|
||||
<element type="IncludeTypePattern" name="**.query.**"/>
|
||||
</element>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Geospatial" type="AllowedDependency"/>
|
||||
</element>
|
||||
<element type="Subsystem" name="Conversion">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.core.convert.**"/>
|
||||
<element type="IncludeTypePattern" name="**.convert.**"/>
|
||||
</element>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Geospatial" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Query" type="AllowedDependency"/>
|
||||
</element>
|
||||
<element type="Subsystem" name="SpEL">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.core.spel.**"/>
|
||||
<element type="IncludeTypePattern" name="**.spel.**"/>
|
||||
</element>
|
||||
</element>
|
||||
<element type="Subsystem" name="Aggregation">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.core.aggregation.**"/>
|
||||
<element type="IncludeTypePattern" name="**.aggregation.**"/>
|
||||
</element>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Conversion" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping" type="AllowedDependency"/>
|
||||
@@ -99,7 +100,7 @@
|
||||
</element>
|
||||
<element type="Subsystem" name="Index">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.core.index.**"/>
|
||||
<element type="IncludeTypePattern" name="**.index.**"/>
|
||||
</element>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Query" type="AllowedDependency"/>
|
||||
@@ -115,13 +116,6 @@
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping" type="AllowedDependency"/>
|
||||
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Query" type="AllowedDependency"/>
|
||||
</element>
|
||||
<element type="Subsystem" name="Util">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
<element type="IncludeTypePattern" name="**.util.**"/>
|
||||
</element>
|
||||
<stereotype name="Unrestricted"/>
|
||||
<stereotype name="Public"/>
|
||||
</element>
|
||||
</element>
|
||||
<element type="Subsystem" name="API">
|
||||
<element type="TypeFilter" name="Assignment">
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.5.0.M1</version>
|
||||
<version>1.4.4.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2013 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.
|
||||
@@ -24,14 +24,13 @@ package org.springframework.data.mongodb.config;
|
||||
*/
|
||||
public abstract class BeanNames {
|
||||
|
||||
public static final String MAPPING_CONTEXT_BEAN_NAME = "mongoMappingContext";
|
||||
|
||||
static final String INDEX_HELPER_BEAN_NAME = "indexCreationHelper";
|
||||
static final String MONGO_BEAN_NAME = "mongo";
|
||||
static final String DB_FACTORY_BEAN_NAME = "mongoDbFactory";
|
||||
static final String VALIDATING_EVENT_LISTENER_BEAN_NAME = "validatingMongoEventListener";
|
||||
static final String IS_NEW_STRATEGY_FACTORY_BEAN_NAME = "isNewStrategyFactory";
|
||||
static final String MAPPING_CONTEXT = "mappingContext";
|
||||
static final String INDEX_HELPER = "indexCreationHelper";
|
||||
static final String MONGO = "mongo";
|
||||
static final String DB_FACTORY = "mongoDbFactory";
|
||||
static final String VALIDATING_EVENT_LISTENER = "validatingMongoEventListener";
|
||||
static final String IS_NEW_STRATEGY_FACTORY = "isNewStrategyFactory";
|
||||
static final String DEFAULT_CONVERTER_BEAN_NAME = "mappingConverter";
|
||||
static final String MONGO_TEMPLATE_BEAN_NAME = "mongoTemplate";
|
||||
static final String GRID_FS_TEMPLATE_BEAN_NAME = "gridFsTemplate";
|
||||
static final String MONGO_TEMPLATE = "mongoTemplate";
|
||||
static final String GRID_FS_TEMPLATE = "gridFsTemplate";
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class GridFsTemplateParser extends AbstractBeanDefinitionParser {
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.GRID_FS_TEMPLATE_BEAN_NAME;
|
||||
return StringUtils.hasText(id) ? id : BeanNames.GRID_FS_TEMPLATE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -64,7 +64,7 @@ class GridFsTemplateParser extends AbstractBeanDefinitionParser {
|
||||
if (StringUtils.hasText(dbFactoryRef)) {
|
||||
gridFsTemplateBuilder.addConstructorArgReference(dbFactoryRef);
|
||||
} else {
|
||||
gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY_BEAN_NAME);
|
||||
gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(converterRef)) {
|
||||
@@ -77,7 +77,7 @@ class GridFsTemplateParser extends AbstractBeanDefinitionParser {
|
||||
gridFsTemplateBuilder.addConstructorArgValue(bucket);
|
||||
}
|
||||
|
||||
return (AbstractBeanDefinition) helper.getComponentIdButFallback(gridFsTemplateBuilder, BeanNames.GRID_FS_TEMPLATE_BEAN_NAME)
|
||||
return (AbstractBeanDefinition) helper.getComponentIdButFallback(gridFsTemplateBuilder, BeanNames.GRID_FS_TEMPLATE)
|
||||
.getBeanDefinition();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ import org.w3c.dom.Element;
|
||||
* @author Oliver Gierke
|
||||
* @author Maciej Walkowiak
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
|
||||
@@ -83,10 +84,13 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
*/
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
|
||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||
if (parserContext.isNested()) {
|
||||
parserContext.getReaderContext().error("Mongo Converter must not be defined as nested bean.", element);
|
||||
}
|
||||
|
||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||
String id = element.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE);
|
||||
id = StringUtils.hasText(id) ? id : DEFAULT_CONVERTER_BEAN_NAME;
|
||||
id = StringUtils.hasText(id) ? id : "mappingConverter";
|
||||
|
||||
parserContext.pushContainingComponent(new CompositeComponentDefinition("Mapping Mongo Converter", element));
|
||||
|
||||
@@ -98,7 +102,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
// Need a reference to a Mongo instance
|
||||
String dbFactoryRef = element.getAttribute("db-factory-ref");
|
||||
if (!StringUtils.hasText(dbFactoryRef)) {
|
||||
dbFactoryRef = DB_FACTORY_BEAN_NAME;
|
||||
dbFactoryRef = DB_FACTORY;
|
||||
}
|
||||
|
||||
// Converter
|
||||
@@ -116,10 +120,10 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
}
|
||||
|
||||
try {
|
||||
registry.getBeanDefinition(INDEX_HELPER_BEAN_NAME);
|
||||
registry.getBeanDefinition(INDEX_HELPER);
|
||||
} catch (NoSuchBeanDefinitionException ignored) {
|
||||
if (!StringUtils.hasText(dbFactoryRef)) {
|
||||
dbFactoryRef = DB_FACTORY_BEAN_NAME;
|
||||
dbFactoryRef = DB_FACTORY;
|
||||
}
|
||||
BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
|
||||
@@ -128,14 +132,14 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
indexHelperBuilder.addDependsOn(ctxRef);
|
||||
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(indexHelperBuilder.getBeanDefinition(),
|
||||
INDEX_HELPER_BEAN_NAME));
|
||||
INDEX_HELPER));
|
||||
}
|
||||
|
||||
BeanDefinition validatingMongoEventListener = potentiallyCreateValidatingMongoEventListener(element, parserContext);
|
||||
|
||||
if (validatingMongoEventListener != null) {
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(validatingMongoEventListener,
|
||||
VALIDATING_EVENT_LISTENER_BEAN_NAME));
|
||||
VALIDATING_EVENT_LISTENER));
|
||||
}
|
||||
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(converterBuilder.getBeanDefinition(), id));
|
||||
@@ -180,7 +184,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
return new RuntimeBeanReference(validatorName);
|
||||
}
|
||||
|
||||
public static String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
|
||||
static String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
|
||||
BeanDefinition conversionsDefinition, String converterId) {
|
||||
|
||||
String ctxRef = element.getAttribute("mapping-context-ref");
|
||||
@@ -215,8 +219,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
CamelCaseAbbreviatingFieldNamingStrategy.class));
|
||||
}
|
||||
|
||||
ctxRef = converterId == null || DEFAULT_CONVERTER_BEAN_NAME.equals(converterId) ? MAPPING_CONTEXT_BEAN_NAME
|
||||
: converterId + "." + MAPPING_CONTEXT_BEAN_NAME;
|
||||
ctxRef = converterId + "." + MAPPING_CONTEXT;
|
||||
|
||||
parserContext.registerBeanComponent(componentDefinitionBuilder.getComponent(mappingContextBuilder, ctxRef));
|
||||
return ctxRef;
|
||||
@@ -311,10 +314,9 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
mappingContextStrategyFactoryBuilder.addConstructorArgReference(mappingContextRef);
|
||||
|
||||
BeanComponentDefinitionBuilder builder = new BeanComponentDefinitionBuilder(element, context);
|
||||
context.registerBeanComponent(builder.getComponent(mappingContextStrategyFactoryBuilder,
|
||||
IS_NEW_STRATEGY_FACTORY_BEAN_NAME));
|
||||
context.registerBeanComponent(builder.getComponent(mappingContextStrategyFactoryBuilder, IS_NEW_STRATEGY_FACTORY));
|
||||
|
||||
return IS_NEW_STRATEGY_FACTORY_BEAN_NAME;
|
||||
return IS_NEW_STRATEGY_FACTORY;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,19 +15,14 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.config;
|
||||
|
||||
import static org.springframework.data.config.ParsingUtils.*;
|
||||
import static org.springframework.data.mongodb.config.BeanNames.*;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.auditing.config.IsNewAwareAuditingHandlerBeanDefinitionParser;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.config.IsNewAwareAuditingHandlerBeanDefinitionParser;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
@@ -63,24 +58,23 @@ public class MongoAuditingBeanDefinitionParser extends AbstractSingleBeanDefinit
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
String mappingContextRef = element.getAttribute("mapping-context-ref");
|
||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||
|
||||
if (!StringUtils.hasText(mappingContextRef)) {
|
||||
if (!registry.containsBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY)) {
|
||||
|
||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||
String mappingContextName = BeanNames.MAPPING_CONTEXT;
|
||||
|
||||
if (!registry.containsBeanDefinition(MAPPING_CONTEXT_BEAN_NAME)) {
|
||||
registry.registerBeanDefinition(MAPPING_CONTEXT_BEAN_NAME, new RootBeanDefinition(MongoMappingContext.class));
|
||||
if (!registry.containsBeanDefinition(BeanNames.MAPPING_CONTEXT)) {
|
||||
mappingContextName = MappingMongoConverterParser.potentiallyCreateMappingContext(element, parserContext, null,
|
||||
BeanNames.DEFAULT_CONVERTER_BEAN_NAME);
|
||||
}
|
||||
|
||||
mappingContextRef = MAPPING_CONTEXT_BEAN_NAME;
|
||||
MappingMongoConverterParser.createIsNewStrategyFactoryBeanDefinition(mappingContextName, parserContext, element);
|
||||
}
|
||||
|
||||
IsNewAwareAuditingHandlerBeanDefinitionParser parser = new IsNewAwareAuditingHandlerBeanDefinitionParser(
|
||||
mappingContextRef);
|
||||
parser.parse(element, parserContext);
|
||||
BeanDefinitionParser parser = new IsNewAwareAuditingHandlerBeanDefinitionParser(BeanNames.IS_NEW_STRATEGY_FACTORY);
|
||||
BeanDefinition handlerBeanDefinition = parser.parse(element, parserContext);
|
||||
|
||||
builder.addConstructorArgValue(getObjectFactoryBeanDefinition(parser.getResolvedBeanName(),
|
||||
parserContext.extractSource(element)));
|
||||
builder.addConstructorArgValue(handlerBeanDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,15 +21,17 @@ import static org.springframework.data.mongodb.config.BeanNames.*;
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
|
||||
import org.springframework.data.auditing.config.AnnotationAuditingConfiguration;
|
||||
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
|
||||
import org.springframework.data.auditing.config.AuditingConfiguration;
|
||||
import org.springframework.data.config.ParsingUtils;
|
||||
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
|
||||
import org.springframework.data.support.IsNewStrategyFactory;
|
||||
@@ -52,15 +54,6 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
||||
return EnableMongoAuditing.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName()
|
||||
*/
|
||||
@Override
|
||||
protected String getAuditingHandlerBeanName() {
|
||||
return "mongoAuditingHandler";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||
@@ -77,16 +70,16 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration)
|
||||
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AnnotationAuditingConfiguration)
|
||||
*/
|
||||
@Override
|
||||
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
|
||||
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AnnotationAuditingConfiguration configuration) {
|
||||
|
||||
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
|
||||
Assert.notNull(configuration, "AnnotationAuditingConfiguration must not be null!");
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
|
||||
builder.addConstructorArgReference(MAPPING_CONTEXT_BEAN_NAME);
|
||||
return configureDefaultAuditHandlerAttributes(configuration, builder);
|
||||
return configureDefaultAuditHandlerAttributes(configuration,
|
||||
BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class)).addConstructorArgReference(
|
||||
BeanNames.IS_NEW_STRATEGY_FACTORY);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -100,12 +93,8 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
||||
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!");
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
|
||||
|
||||
BeanDefinitionBuilder listenerBeanDefinitionBuilder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(AuditingEventListener.class);
|
||||
listenerBeanDefinitionBuilder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(
|
||||
getAuditingHandlerBeanName(), registry));
|
||||
|
||||
registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(),
|
||||
registerInfrastructureBeanWithId(BeanDefinitionBuilder.rootBeanDefinition(AuditingEventListener.class)
|
||||
.addConstructorArgValue(auditingHandlerDefinition).getRawBeanDefinition(),
|
||||
AuditingEventListener.class.getName(), registry);
|
||||
}
|
||||
|
||||
@@ -118,13 +107,25 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
||||
*/
|
||||
private void defaultDependenciesIfNecessary(BeanDefinitionRegistry registry, Object source) {
|
||||
|
||||
if (!registry.containsBeanDefinition(MAPPING_CONTEXT_BEAN_NAME)) {
|
||||
if (!registry.containsBeanDefinition(MAPPING_CONTEXT)) {
|
||||
|
||||
RootBeanDefinition definition = new RootBeanDefinition(MongoMappingContext.class);
|
||||
definition.setRole(ROLE_INFRASTRUCTURE);
|
||||
definition.setSource(source);
|
||||
|
||||
registry.registerBeanDefinition(MAPPING_CONTEXT_BEAN_NAME, definition);
|
||||
registry.registerBeanDefinition(MAPPING_CONTEXT, definition);
|
||||
}
|
||||
|
||||
if (!registry.containsBeanDefinition(IS_NEW_STRATEGY_FACTORY)) {
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(MappingContextIsNewStrategyFactory.class);
|
||||
builder.addConstructorArgReference(MAPPING_CONTEXT);
|
||||
|
||||
AbstractBeanDefinition definition = ParsingUtils.getSourceBeanDefinition(builder, source);
|
||||
definition.setRole(ROLE_INFRASTRUCTURE);
|
||||
|
||||
registry.registerBeanDefinition(IS_NEW_STRATEGY_FACTORY, definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 by the original author(s).
|
||||
* Copyright 2011-2013 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -54,7 +54,7 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.DB_FACTORY_BEAN_NAME;
|
||||
return StringUtils.hasText(id) ? id : BeanNames.DB_FACTORY;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -103,7 +103,7 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
|
||||
BeanComponentDefinition component = helper.getComponent(writeConcernPropertyEditorBuilder);
|
||||
parserContext.registerBeanComponent(component);
|
||||
|
||||
return (AbstractBeanDefinition) helper.getComponentIdButFallback(dbFactoryBuilder, BeanNames.DB_FACTORY_BEAN_NAME)
|
||||
return (AbstractBeanDefinition) helper.getComponentIdButFallback(dbFactoryBuilder, BeanNames.DB_FACTORY)
|
||||
.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2013 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,9 @@
|
||||
package org.springframework.data.mongodb.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
import org.springframework.data.mongodb.repository.config.MongoRepositoryConfigurationExtension;
|
||||
import org.springframework.data.repository.config.RepositoryBeanDefinitionParser;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB configuration.
|
||||
@@ -31,6 +34,10 @@ public class MongoNamespaceHandler extends NamespaceHandlerSupport {
|
||||
*/
|
||||
public void init() {
|
||||
|
||||
RepositoryConfigurationExtension extension = new MongoRepositoryConfigurationExtension();
|
||||
RepositoryBeanDefinitionParser repositoryBeanDefinitionParser = new RepositoryBeanDefinitionParser(extension);
|
||||
|
||||
registerBeanDefinitionParser("repositories", repositoryBeanDefinitionParser);
|
||||
registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser());
|
||||
registerBeanDefinitionParser("mongo", new MongoParser());
|
||||
registerBeanDefinitionParser("db-factory", new MongoDbFactoryParser());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 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.
|
||||
@@ -58,7 +58,7 @@ public class MongoParser implements BeanDefinitionParser {
|
||||
MongoParsingUtils.parseMongoOptions(element, builder);
|
||||
MongoParsingUtils.parseReplicaSet(element, builder);
|
||||
|
||||
String defaultedId = StringUtils.hasText(id) ? id : BeanNames.MONGO_BEAN_NAME;
|
||||
String defaultedId = StringUtils.hasText(id) ? id : BeanNames.MONGO;
|
||||
|
||||
parserContext.pushContainingComponent(new CompositeComponentDefinition("Mongo", source));
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2013 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.
|
||||
@@ -35,7 +35,6 @@ import org.w3c.dom.Element;
|
||||
* {@link BeanDefinitionParser} to parse {@code template} elements into {@link BeanDefinition}s.
|
||||
*
|
||||
* @author Martin Baumgartner
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class MongoTemplateParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
@@ -48,7 +47,7 @@ class MongoTemplateParser extends AbstractBeanDefinitionParser {
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.MONGO_TEMPLATE_BEAN_NAME;
|
||||
return StringUtils.hasText(id) ? id : BeanNames.MONGO_TEMPLATE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -69,7 +68,7 @@ class MongoTemplateParser extends AbstractBeanDefinitionParser {
|
||||
if (StringUtils.hasText(dbFactoryRef)) {
|
||||
mongoTemplateBuilder.addConstructorArgReference(dbFactoryRef);
|
||||
} else {
|
||||
mongoTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY_BEAN_NAME);
|
||||
mongoTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(converterRef)) {
|
||||
@@ -81,7 +80,7 @@ class MongoTemplateParser extends AbstractBeanDefinitionParser {
|
||||
BeanComponentDefinition component = helper.getComponent(writeConcernPropertyEditorBuilder);
|
||||
parserContext.registerBeanComponent(component);
|
||||
|
||||
return (AbstractBeanDefinition) helper.getComponentIdButFallback(mongoTemplateBuilder,
|
||||
BeanNames.MONGO_TEMPLATE_BEAN_NAME).getBeanDefinition();
|
||||
return (AbstractBeanDefinition) helper.getComponentIdButFallback(mongoTemplateBuilder, BeanNames.MONGO_TEMPLATE)
|
||||
.getBeanDefinition();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
|
||||
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResult;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
|
||||
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
|
||||
@@ -49,10 +50,7 @@ import com.mongodb.WriteResult;
|
||||
* @author Oliver Gierke
|
||||
* @author Tobias Trelle
|
||||
* @author Chuong Ngo
|
||||
* @author Christoph Strobl
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public interface MongoOperations {
|
||||
|
||||
/**
|
||||
@@ -415,7 +413,7 @@ public interface MongoOperations {
|
||||
MapReduceOptions mapReduceOptions, Class<T> entityClass);
|
||||
|
||||
/**
|
||||
* Returns {@link GeoResults} for all entities matching the given {@link NearQuery}. Will consider entity mapping
|
||||
* Returns {@link GeoResult} for all entities matching the given {@link NearQuery}. Will consider entity mapping
|
||||
* information to determine the collection the query is ran against.
|
||||
*
|
||||
* @param near must not be {@literal null}.
|
||||
@@ -425,7 +423,7 @@ public interface MongoOperations {
|
||||
<T> GeoResults<T> geoNear(NearQuery near, Class<T> entityClass);
|
||||
|
||||
/**
|
||||
* Returns {@link GeoResults} for all entities matching the given {@link NearQuery}.
|
||||
* Returns {@link GeoResult} for all entities matching the given {@link NearQuery}.
|
||||
*
|
||||
* @param near must not be {@literal null}.
|
||||
* @param entityClass must not be {@literal null}.
|
||||
@@ -865,7 +863,7 @@ public interface MongoOperations {
|
||||
*
|
||||
* @param object
|
||||
*/
|
||||
WriteResult remove(Object object);
|
||||
void remove(Object object);
|
||||
|
||||
/**
|
||||
* Removes the given object from the given collection.
|
||||
@@ -873,7 +871,7 @@ public interface MongoOperations {
|
||||
* @param object
|
||||
* @param collection must not be {@literal null} or empty.
|
||||
*/
|
||||
WriteResult remove(Object object, String collection);
|
||||
void remove(Object object, String collection);
|
||||
|
||||
/**
|
||||
* Remove all documents that match the provided query document criteria from the the collection used to store the
|
||||
@@ -882,7 +880,7 @@ public interface MongoOperations {
|
||||
* @param query
|
||||
* @param entityClass
|
||||
*/
|
||||
WriteResult remove(Query query, Class<?> entityClass);
|
||||
void remove(Query query, Class<?> entityClass);
|
||||
|
||||
/**
|
||||
* Remove all documents that match the provided query document criteria from the the collection used to store the
|
||||
@@ -892,7 +890,7 @@ public interface MongoOperations {
|
||||
* @param entityClass
|
||||
* @param collectionName
|
||||
*/
|
||||
WriteResult remove(Query query, Class<?> entityClass, String collectionName);
|
||||
void remove(Query query, Class<?> entityClass, String collectionName);
|
||||
|
||||
/**
|
||||
* Remove all documents from the specified collection that match the provided query document criteria. There is no
|
||||
@@ -901,40 +899,7 @@ public interface MongoOperations {
|
||||
* @param query the query document that specifies the criteria used to remove a record
|
||||
* @param collectionName name of the collection where the objects will removed
|
||||
*/
|
||||
WriteResult remove(Query query, String collectionName);
|
||||
|
||||
/**
|
||||
* Returns and removes all documents form the specified collection that match the provided query.
|
||||
*
|
||||
* @param query
|
||||
* @param collectionName
|
||||
* @return
|
||||
* @since 1.5
|
||||
*/
|
||||
<T> List<T> findAllAndRemove(Query query, String collectionName);
|
||||
|
||||
/**
|
||||
* Returns and removes all documents matching the given query form the collection used to store the entityClass.
|
||||
*
|
||||
* @param query
|
||||
* @param entityClass
|
||||
* @return
|
||||
* @since 1.5
|
||||
*/
|
||||
<T> List<T> findAllAndRemove(Query query, Class<T> entityClass);
|
||||
|
||||
/**
|
||||
* Returns and removes all documents that match the provided query document criteria from the the collection used to
|
||||
* store the entityClass. The Class parameter is also used to help convert the Id of the object if it is present in
|
||||
* the query.
|
||||
*
|
||||
* @param query
|
||||
* @param entityClass
|
||||
* @param collectionName
|
||||
* @return
|
||||
* @since 1.5
|
||||
*/
|
||||
<T> List<T> findAllAndRemove(Query query, Class<T> entityClass, String collectionName);
|
||||
void remove(Query query, String collectionName);
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link MongoConverter}.
|
||||
|
||||
@@ -27,7 +27,6 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -48,12 +47,9 @@ import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.authentication.UserCredentials;
|
||||
import org.springframework.data.convert.EntityReader;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.geo.Metric;
|
||||
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;
|
||||
@@ -71,7 +67,10 @@ import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoWriter;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.convert.UpdateMapper;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResult;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.geo.Metric;
|
||||
import org.springframework.data.mongodb.core.index.MongoMappingEventPublisher;
|
||||
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
@@ -96,7 +95,6 @@ import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.jca.cci.core.ConnectionCallback;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -115,6 +113,7 @@ import com.mongodb.WriteConcern;
|
||||
import com.mongodb.WriteResult;
|
||||
import com.mongodb.util.JSON;
|
||||
import com.mongodb.util.JSONParseException;
|
||||
|
||||
/**
|
||||
* Primary implementation of {@link MongoOperations}.
|
||||
*
|
||||
@@ -130,7 +129,6 @@ import com.mongodb.util.JSONParseException;
|
||||
* @author Chuong Ngo
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MongoTemplate.class);
|
||||
@@ -354,7 +352,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
public void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch) {
|
||||
executeQuery(query, collectionName, dch, new QueryCursorPreparer(query));
|
||||
executeQuery(query, collectionName, dch, new QueryCursorPreparer(query, null));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -532,7 +530,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
return doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass,
|
||||
new QueryCursorPreparer(query));
|
||||
new QueryCursorPreparer(query, entityClass));
|
||||
}
|
||||
|
||||
public <T> T findById(Object id, Class<T> entityClass) {
|
||||
@@ -614,8 +612,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
public <T> T findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass,
|
||||
String collectionName) {
|
||||
return doFindAndModify(collectionName, query.getQueryObject(), query.getFieldsObject(), query.getSortObject(),
|
||||
entityClass, update, options);
|
||||
return doFindAndModify(collectionName, query.getQueryObject(), query.getFieldsObject(),
|
||||
getMappedSortObject(query, entityClass), entityClass, update, options);
|
||||
}
|
||||
|
||||
// Find methods that take a Query to express the query and that return a single object that is also removed from the
|
||||
@@ -626,8 +624,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
public <T> T findAndRemove(Query query, Class<T> entityClass, String collectionName) {
|
||||
return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(), query.getSortObject(),
|
||||
entityClass);
|
||||
|
||||
return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(),
|
||||
getMappedSortObject(query, entityClass), entityClass);
|
||||
}
|
||||
|
||||
public long count(Query query, Class<?> entityClass) {
|
||||
@@ -743,7 +742,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
MongoPersistentEntity<?> mongoPersistentEntity = getPersistentEntity(entity.getClass());
|
||||
|
||||
if (mongoPersistentEntity != null && mongoPersistentEntity.hasVersionProperty()) {
|
||||
BeanWrapper<Object> wrapper = BeanWrapper.create(entity, this.mongoConverter.getConversionService());
|
||||
BeanWrapper<PersistentEntity<Object, ?>, Object> wrapper = BeanWrapper.create(entity,
|
||||
this.mongoConverter.getConversionService());
|
||||
wrapper.setProperty(mongoPersistentEntity.getVersionProperty(), 0);
|
||||
}
|
||||
}
|
||||
@@ -837,11 +837,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
private <T> void doSaveVersioned(T objectToSave, MongoPersistentEntity<?> entity, String collectionName) {
|
||||
|
||||
BeanWrapper<T> beanWrapper = BeanWrapper.create(objectToSave, this.mongoConverter.getConversionService());
|
||||
BeanWrapper<PersistentEntity<T, ?>, T> beanWrapper = BeanWrapper.create(objectToSave,
|
||||
this.mongoConverter.getConversionService());
|
||||
MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
MongoPersistentProperty versionProperty = entity.getVersionProperty();
|
||||
|
||||
Number version = beanWrapper.getProperty(versionProperty, Number.class);
|
||||
Number version = beanWrapper.getProperty(versionProperty, Number.class, !versionProperty.usePropertyAccess());
|
||||
|
||||
// Fresh instance -> initialize version property
|
||||
if (version == null) {
|
||||
@@ -855,7 +856,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
Query query = new Query(Criteria.where(idProperty.getName()).is(id).and(versionProperty.getName()).is(version));
|
||||
|
||||
// Bump version number
|
||||
Number number = beanWrapper.getProperty(versionProperty, Number.class);
|
||||
Number number = beanWrapper.getProperty(versionProperty, Number.class, false);
|
||||
beanWrapper.setProperty(versionProperty, number.longValue() + 1);
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
@@ -1047,48 +1048,24 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
return dbObject.containsField(persistentEntity.getVersionProperty().getFieldName());
|
||||
}
|
||||
|
||||
public WriteResult remove(Object object) {
|
||||
public void remove(Object object) {
|
||||
|
||||
if (object == null) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
return remove(getIdQueryFor(object), object.getClass());
|
||||
remove(getIdQueryFor(object), object.getClass());
|
||||
}
|
||||
|
||||
public WriteResult remove(Object object, String collection) {
|
||||
public void remove(Object object, String collection) {
|
||||
|
||||
Assert.hasText(collection);
|
||||
|
||||
if (object == null) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
return doRemove(collection, getIdQueryFor(object), object.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link Entry} containing the {@link MongoPersistentProperty} defining the {@literal id} as
|
||||
* {@link Entry#getKey()} and the {@link Id}s property value as its {@link Entry#getValue()}.
|
||||
*
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
private Map.Entry<MongoPersistentProperty, Object> extractIdPropertyAndValue(Object object) {
|
||||
|
||||
Assert.notNull(object, "Id cannot be extracted from 'null'.");
|
||||
|
||||
Class<?> objectType = object.getClass();
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(objectType);
|
||||
MongoPersistentProperty idProp = entity == null ? null : entity.getIdProperty();
|
||||
|
||||
if (idProp == null) {
|
||||
throw new MappingException("No id property found for object of type " + objectType);
|
||||
}
|
||||
|
||||
Object idValue = BeanWrapper.create(object, mongoConverter.getConversionService())
|
||||
.getProperty(idProp, Object.class);
|
||||
return Collections.singletonMap(idProp, idValue).entrySet().iterator().next();
|
||||
doRemove(collection, getIdQueryFor(object), object.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1099,31 +1076,21 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
*/
|
||||
private Query getIdQueryFor(Object object) {
|
||||
|
||||
Map.Entry<MongoPersistentProperty, Object> id = extractIdPropertyAndValue(object);
|
||||
return new Query(where(id.getKey().getFieldName()).is(id.getValue()));
|
||||
}
|
||||
Assert.notNull(object);
|
||||
|
||||
/**
|
||||
* Returns a {@link Query} for the given entities by their ids.
|
||||
*
|
||||
* @param objects must not be {@literal null} or {@literal empty}.
|
||||
* @return
|
||||
*/
|
||||
private Query getIdInQueryFor(Collection<?> objects) {
|
||||
Class<?> objectType = object.getClass();
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(objectType);
|
||||
MongoPersistentProperty idProp = entity == null ? null : entity.getIdProperty();
|
||||
|
||||
Assert.notEmpty(objects, "Cannot create Query for empty collection.");
|
||||
|
||||
Iterator<?> it = objects.iterator();
|
||||
Map.Entry<MongoPersistentProperty, Object> firstEntry = extractIdPropertyAndValue(it.next());
|
||||
|
||||
ArrayList<Object> ids = new ArrayList<Object>(objects.size());
|
||||
ids.add(firstEntry.getValue());
|
||||
|
||||
while (it.hasNext()) {
|
||||
ids.add(extractIdPropertyAndValue(it.next()).getValue());
|
||||
if (idProp == null) {
|
||||
throw new MappingException("No id property found for object of type " + objectType);
|
||||
}
|
||||
|
||||
return new Query(where(firstEntry.getKey().getFieldName()).in(ids));
|
||||
ConversionService service = mongoConverter.getConversionService();
|
||||
Object idProperty = null;
|
||||
|
||||
idProperty = BeanWrapper.create(object, service).getProperty(idProp, Object.class, true);
|
||||
return new Query(where(idProp.getFieldName()).is(idProperty));
|
||||
}
|
||||
|
||||
private void assertUpdateableIdIfNotSet(Object entity) {
|
||||
@@ -1136,7 +1103,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
ConversionService service = mongoConverter.getConversionService();
|
||||
Object idValue = BeanWrapper.create(entity, service).getProperty(idProperty, Object.class);
|
||||
Object idValue = BeanWrapper.create(entity, service).getProperty(idProperty, Object.class, true);
|
||||
|
||||
if (idValue == null && !MongoSimpleTypes.AUTOGENERATED_ID_TYPES.contains(idProperty.getType())) {
|
||||
throw new InvalidDataAccessApiUsageException(String.format(
|
||||
@@ -1145,19 +1112,19 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
}
|
||||
|
||||
public WriteResult remove(Query query, String collectionName) {
|
||||
return remove(query, null, collectionName);
|
||||
public void remove(Query query, String collectionName) {
|
||||
remove(query, null, collectionName);
|
||||
}
|
||||
|
||||
public WriteResult remove(Query query, Class<?> entityClass) {
|
||||
return remove(query, entityClass, determineCollectionName(entityClass));
|
||||
public void remove(Query query, Class<?> entityClass) {
|
||||
remove(query, entityClass, determineCollectionName(entityClass));
|
||||
}
|
||||
|
||||
public WriteResult remove(Query query, Class<?> entityClass, String collectionName) {
|
||||
return doRemove(collectionName, query, entityClass);
|
||||
public void remove(Query query, Class<?> entityClass, String collectionName) {
|
||||
doRemove(collectionName, query, entityClass);
|
||||
}
|
||||
|
||||
protected <T> WriteResult doRemove(final String collectionName, final Query query, final Class<T> entityClass) {
|
||||
protected <T> void doRemove(final String collectionName, final Query query, final Class<T> entityClass) {
|
||||
|
||||
if (query == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Query passed in to remove can't be null!");
|
||||
@@ -1168,8 +1135,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
final DBObject queryObject = query.getQueryObject();
|
||||
final MongoPersistentEntity<?> entity = getPersistentEntity(entityClass);
|
||||
|
||||
return execute(collectionName, new CollectionCallback<WriteResult>() {
|
||||
public WriteResult doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
execute(collectionName, new CollectionCallback<Void>() {
|
||||
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
|
||||
maybeEmitEvent(new BeforeDeleteEvent<T>(queryObject, entityClass));
|
||||
|
||||
@@ -1185,12 +1152,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
WriteResult wr = writeConcernToUse == null ? collection.remove(dboq) : collection.remove(dboq,
|
||||
writeConcernToUse);
|
||||
|
||||
handleAnyWriteResultErrors(wr, dboq, MongoActionOperation.REMOVE);
|
||||
|
||||
maybeEmitEvent(new AfterDeleteEvent<T>(queryObject, entityClass));
|
||||
|
||||
return wr;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1346,54 +1312,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
return aggregate(aggregation, collectionName, outputType, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.MongoOperations#findAllAndRemove(org.springframework.data.mongodb.core.query.Query, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> findAllAndRemove(Query query, String collectionName) {
|
||||
return findAndRemove(query, null, collectionName);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.MongoOperations#findAllAndRemove(org.springframework.data.mongodb.core.query.Query, java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> findAllAndRemove(Query query, Class<T> entityClass) {
|
||||
return findAllAndRemove(query, entityClass, determineCollectionName(entityClass));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.MongoOperations#findAllAndRemove(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> findAllAndRemove(Query query, Class<T> entityClass, String collectionName) {
|
||||
return doFindAndDelete(collectionName, query, entityClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve and remove all documents matching the given {@code query} by calling {@link #find(Query, Class, String)}
|
||||
* and {@link #remove(Query, Class, String)}, whereas the {@link Query} for {@link #remove(Query, Class, String)} is
|
||||
* constructed out of the find result.
|
||||
*
|
||||
* @param collectionName
|
||||
* @param query
|
||||
* @param entityClass
|
||||
* @return
|
||||
*/
|
||||
protected <T> List<T> doFindAndDelete(String collectionName, Query query, Class<T> entityClass) {
|
||||
|
||||
List<T> result = find(query, entityClass, collectionName);
|
||||
|
||||
if (!CollectionUtils.isEmpty(result)) {
|
||||
remove(getIdInQueryFor(result), entityClass, collectionName);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected <O> AggregationResults<O> aggregate(Aggregation aggregation, String collectionName, Class<O> outputType,
|
||||
AggregationOperationContext context) {
|
||||
|
||||
@@ -1453,13 +1371,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
"Can not use skip or field specification with map reduce operations");
|
||||
}
|
||||
if (query.getQueryObject() != null) {
|
||||
copyMapReduceOptions.put("query", query.getQueryObject());
|
||||
copyMapReduceOptions.put("query", queryMapper.getMappedObject(query.getQueryObject(), null));
|
||||
}
|
||||
if (query.getLimit() > 0) {
|
||||
copyMapReduceOptions.put("limit", query.getLimit());
|
||||
}
|
||||
if (query.getSortObject() != null) {
|
||||
copyMapReduceOptions.put("sort", query.getSortObject());
|
||||
copyMapReduceOptions.put("sort", queryMapper.getMappedObject(query.getSortObject(), null));
|
||||
}
|
||||
}
|
||||
return copyMapReduceOptions;
|
||||
@@ -1695,9 +1613,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
ConversionService conversionService = mongoConverter.getConversionService();
|
||||
BeanWrapper<Object> wrapper = BeanWrapper.create(savedObject, conversionService);
|
||||
BeanWrapper<PersistentEntity<Object, ?>, Object> wrapper = BeanWrapper.create(savedObject, conversionService);
|
||||
|
||||
Object idValue = wrapper.getProperty(idProp, idProp.getType());
|
||||
Object idValue = wrapper.getProperty(idProp, idProp.getType(), true);
|
||||
|
||||
if (idValue != null) {
|
||||
return;
|
||||
@@ -1941,6 +1859,16 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
return converter;
|
||||
}
|
||||
|
||||
private DBObject getMappedSortObject(Query query, Class<?> type) {
|
||||
|
||||
if (query == null || query.getSortObject() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(type);
|
||||
return queryMapper.getMappedObject(query.getSortObject(), entity);
|
||||
}
|
||||
|
||||
// Callback implementations
|
||||
|
||||
/**
|
||||
@@ -2134,9 +2062,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
class QueryCursorPreparer implements CursorPreparer {
|
||||
|
||||
private final Query query;
|
||||
private final Class<?> type;
|
||||
|
||||
public QueryCursorPreparer(Query query, Class<?> type) {
|
||||
|
||||
public QueryCursorPreparer(Query query) {
|
||||
this.query = query;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2164,7 +2095,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
cursorToUse = cursorToUse.limit(query.getLimit());
|
||||
}
|
||||
if (query.getSortObject() != null) {
|
||||
cursorToUse = cursorToUse.sort(query.getSortObject());
|
||||
DBObject sortDbo = type != null ? getMappedSortObject(query, type) : query.getSortObject();
|
||||
cursorToUse = cursorToUse.sort(sortDbo);
|
||||
}
|
||||
if (StringUtils.hasText(query.getHint())) {
|
||||
cursorToUse = cursorToUse.hint(query.getHint());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2014 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.
|
||||
@@ -248,7 +248,7 @@ public class Aggregation {
|
||||
|
||||
if (operation instanceof FieldsExposingAggregationOperation) {
|
||||
FieldsExposingAggregationOperation exposedFieldsOperation = (FieldsExposingAggregationOperation) operation;
|
||||
context = new ExposedFieldsAggregationOperationContext(exposedFieldsOperation.getFields());
|
||||
context = new ExposedFieldsAggregationOperationContext(exposedFieldsOperation.getFields(), rootContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -268,14 +268,21 @@ public final class ExposedFields implements Iterable<ExposedField> {
|
||||
return field.isAliased();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the synthetic
|
||||
*/
|
||||
public boolean isSynthetic() {
|
||||
return synthetic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the field can be referred to using the given name.
|
||||
*
|
||||
* @param input
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public boolean canBeReferredToBy(String input) {
|
||||
return getTarget().equals(input);
|
||||
public boolean canBeReferredToBy(String name) {
|
||||
return getName().equals(name) || getTarget().equals(name);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -340,6 +347,7 @@ public final class ExposedFields implements Iterable<ExposedField> {
|
||||
public FieldReference(ExposedField field) {
|
||||
|
||||
Assert.notNull(field, "ExposedField must not be null!");
|
||||
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2014 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,16 +32,22 @@ import com.mongodb.DBObject;
|
||||
class ExposedFieldsAggregationOperationContext implements AggregationOperationContext {
|
||||
|
||||
private final ExposedFields exposedFields;
|
||||
private final AggregationOperationContext rootContext;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ExposedFieldsAggregationOperationContext} from the given {@link ExposedFields}.
|
||||
* Creates a new {@link ExposedFieldsAggregationOperationContext} from the given {@link ExposedFields}. Uses the given
|
||||
* {@link AggregationOperationContext} to perform a mapping to mongo types if necessary.
|
||||
*
|
||||
* @param exposedFields must not be {@literal null}.
|
||||
* @param rootContext must not be {@literal null}.
|
||||
*/
|
||||
public ExposedFieldsAggregationOperationContext(ExposedFields exposedFields) {
|
||||
public ExposedFieldsAggregationOperationContext(ExposedFields exposedFields, AggregationOperationContext rootContext) {
|
||||
|
||||
Assert.notNull(exposedFields, "ExposedFields must not be null!");
|
||||
Assert.notNull(rootContext, "RootContext must not be null!");
|
||||
|
||||
this.exposedFields = exposedFields;
|
||||
this.rootContext = rootContext;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -50,7 +56,7 @@ class ExposedFieldsAggregationOperationContext implements AggregationOperationCo
|
||||
*/
|
||||
@Override
|
||||
public DBObject getMappedObject(DBObject dbObject) {
|
||||
return dbObject;
|
||||
return rootContext.getMappedObject(dbObject);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -59,7 +65,7 @@ class ExposedFieldsAggregationOperationContext implements AggregationOperationCo
|
||||
*/
|
||||
@Override
|
||||
public FieldReference getReference(Field field) {
|
||||
return getReference(field.getTarget());
|
||||
return getReference(field, field.getTarget());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -68,11 +74,42 @@ class ExposedFieldsAggregationOperationContext implements AggregationOperationCo
|
||||
*/
|
||||
@Override
|
||||
public FieldReference getReference(String name) {
|
||||
return getReference(null, name);
|
||||
}
|
||||
|
||||
ExposedField field = exposedFields.getField(name);
|
||||
/**
|
||||
* Returns a {@link FieldReference} to the given {@link Field} with the given {@code name}.
|
||||
*
|
||||
* @param field may be {@literal null}
|
||||
* @param name must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
private FieldReference getReference(Field field, String name) {
|
||||
|
||||
if (field != null) {
|
||||
return new FieldReference(field);
|
||||
Assert.notNull(name, "Name must not be null!");
|
||||
|
||||
ExposedField exposedField = exposedFields.getField(name);
|
||||
|
||||
if (exposedField != null) {
|
||||
|
||||
if (field != null) {
|
||||
// we return a FieldReference to the given field directly to make sure that we reference the proper alias here.
|
||||
return new FieldReference(new ExposedField(field, exposedField.isSynthetic()));
|
||||
}
|
||||
|
||||
return new FieldReference(exposedField);
|
||||
}
|
||||
|
||||
if (name.contains(".")) {
|
||||
|
||||
// for nested field references we only check that the root field exists.
|
||||
ExposedField rootField = exposedFields.getField(name.split("\\.")[0]);
|
||||
|
||||
if (rootField != null) {
|
||||
|
||||
// We have to synthetic to true, in order to render the field-name as is.
|
||||
return new FieldReference(new ExposedField(name, true));
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Invalid reference '%s'!", name));
|
||||
|
||||
@@ -96,7 +96,6 @@ public class CustomConversions {
|
||||
|
||||
List<Object> toRegister = new ArrayList<Object>();
|
||||
|
||||
// Add user provided converters to make sure they can override the defaults
|
||||
toRegister.addAll(converters);
|
||||
toRegister.add(CustomToStringConverter.INSTANCE);
|
||||
toRegister.add(BigDecimalToStringConverter.INSTANCE);
|
||||
@@ -106,9 +105,9 @@ public class CustomConversions {
|
||||
toRegister.add(URLToStringConverter.INSTANCE);
|
||||
toRegister.add(StringToURLConverter.INSTANCE);
|
||||
toRegister.add(DBObjectToStringConverter.INSTANCE);
|
||||
|
||||
toRegister.addAll(JodaTimeConverters.getConvertersToRegister());
|
||||
toRegister.addAll(GeoConverters.getConvertersToRegister());
|
||||
|
||||
// Add user provided converters to make sure they can override the defaults
|
||||
|
||||
for (Object c : toRegister) {
|
||||
registerConversion(c);
|
||||
|
||||
@@ -28,11 +28,11 @@ import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.objenesis.Objenesis;
|
||||
import org.objenesis.ObjenesisStd;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.cglib.proxy.Callback;
|
||||
import org.springframework.cglib.proxy.Enhancer;
|
||||
import org.springframework.cglib.proxy.Factory;
|
||||
import org.springframework.cglib.proxy.MethodProxy;
|
||||
import org.springframework.core.SpringVersion;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.mongodb.LazyLoadingException;
|
||||
@@ -57,7 +57,6 @@ import com.mongodb.DBRef;
|
||||
*/
|
||||
public class DefaultDbRefResolver implements DbRefResolver {
|
||||
|
||||
private static final boolean IS_SPRING_4_OR_BETTER = SpringVersion.getVersion().startsWith("4");
|
||||
private static final boolean OBJENESIS_PRESENT = ClassUtils.isPresent("org.objenesis.Objenesis", null);
|
||||
|
||||
private final MongoDbFactory mongoDbFactory;
|
||||
@@ -138,7 +137,7 @@ public class DefaultDbRefResolver implements DbRefResolver {
|
||||
proxyFactory.setProxyTargetClass(true);
|
||||
proxyFactory.setTargetClass(propertyType);
|
||||
|
||||
if (IS_SPRING_4_OR_BETTER || !OBJENESIS_PRESENT) {
|
||||
if (!OBJENESIS_PRESENT) {
|
||||
proxyFactory.addAdvice(interceptor);
|
||||
return proxyFactory.getProxy();
|
||||
}
|
||||
@@ -374,13 +373,27 @@ public class DefaultDbRefResolver implements DbRefResolver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Static class to accomodate optional dependency on Objenesis.
|
||||
* Static class to accommodate optional dependency on Objenesis.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @since 1.4
|
||||
*/
|
||||
private static class ObjenesisProxyEnhancer {
|
||||
|
||||
private static final Objenesis OBJENESIS = new ObjenesisStd(true);
|
||||
private static final boolean IS_SPRING_4_OR_BETTER = ClassUtils.isPresent(
|
||||
"org.springframework.core.DefaultParameterNameDiscoverer", null);
|
||||
|
||||
private static final InstanceCreatorStrategy INSTANCE_CREATOR;
|
||||
|
||||
static {
|
||||
|
||||
if (IS_SPRING_4_OR_BETTER) {
|
||||
INSTANCE_CREATOR = new Spring4ObjenesisInstanceCreatorStrategy();
|
||||
} else {
|
||||
INSTANCE_CREATOR = new DefaultObjenesisInstanceCreatorStrategy();
|
||||
}
|
||||
}
|
||||
|
||||
public static Object enhanceAndGet(ProxyFactory proxyFactory, Class<?> type,
|
||||
org.springframework.cglib.proxy.MethodInterceptor interceptor) {
|
||||
@@ -390,9 +403,77 @@ public class DefaultDbRefResolver implements DbRefResolver {
|
||||
enhancer.setCallbackType(org.springframework.cglib.proxy.MethodInterceptor.class);
|
||||
enhancer.setInterfaces(new Class[] { LazyLoadingProxy.class });
|
||||
|
||||
Factory factory = (Factory) OBJENESIS.newInstance(enhancer.createClass());
|
||||
Factory factory = (Factory) INSTANCE_CREATOR.newInstance(enhancer.createClass());
|
||||
factory.setCallbacks(new Callback[] { interceptor });
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for constructing new instances of a given {@link Class}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
interface InstanceCreatorStrategy {
|
||||
Object newInstance(Class<?> clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* An {@link InstanceCreatorStrategy} that uses Objenesis from the classpath.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
private static class DefaultObjenesisInstanceCreatorStrategy implements InstanceCreatorStrategy {
|
||||
|
||||
private static final Objenesis OBJENESIS = new ObjenesisStd(true);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.DefaultDbRefResolver.ObjenesisProxyEnhancer.InstanceCreatorStrategy#newInstance(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public Object newInstance(Class<?> clazz) {
|
||||
return OBJENESIS.newInstance(clazz);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An {@link InstanceCreatorStrategy} that uses a repackaged version of Objenesis from Spring 4.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
private static class Spring4ObjenesisInstanceCreatorStrategy implements InstanceCreatorStrategy {
|
||||
|
||||
private static final String SPRING4_OBJENESIS_CLASS_NAME = "org.springframework.objenesis.ObjenesisStd";
|
||||
private static final Object OBJENESIS;
|
||||
private static final Method NEW_INSTANCE_METHOD;
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
Class<?> objenesisClass = ClassUtils.forName(SPRING4_OBJENESIS_CLASS_NAME,
|
||||
ObjenesisProxyEnhancer.class.getClassLoader());
|
||||
|
||||
OBJENESIS = BeanUtils.instantiateClass(objenesisClass.getConstructor(boolean.class), true);
|
||||
NEW_INSTANCE_METHOD = objenesisClass.getMethod("newInstance", Class.class);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Could not setup Objenesis infrastructure with Spring 4 ", e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.DefaultDbRefResolver.ObjenesisProxyEnhancer.InstanceCreatorStrategy#newInstance(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public Object newInstance(Class<?> clazz) {
|
||||
|
||||
try {
|
||||
return NEW_INSTANCE_METHOD.invoke(OBJENESIS, clazz);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Could not created instance for " + clazz, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,520 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.convert.ReadingConverter;
|
||||
import org.springframework.data.convert.WritingConverter;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.geo.Shape;
|
||||
import org.springframework.data.mongodb.core.geo.Sphere;
|
||||
import org.springframework.data.mongodb.core.query.GeoCommand;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Wrapper class to contain useful geo structure converters for the usage with Mongo.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
abstract class GeoConverters {
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private GeoConverters() {}
|
||||
|
||||
/**
|
||||
* Returns the geo converters to be registered.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Collection<? extends Object> getConvertersToRegister() {
|
||||
return Arrays.asList( //
|
||||
BoxToDbObjectConverter.INSTANCE //
|
||||
, PolygonToDbObjectConverter.INSTANCE //
|
||||
, CircleToDbObjectConverter.INSTANCE //
|
||||
, LegacyCircleToDbObjectConverter.INSTANCE //
|
||||
, SphereToDbObjectConverter.INSTANCE //
|
||||
, DbObjectToBoxConverter.INSTANCE //
|
||||
, DbObjectToPolygonConverter.INSTANCE //
|
||||
, DbObjectToCircleConverter.INSTANCE //
|
||||
, DbObjectToLegacyCircleConverter.INSTANCE //
|
||||
, DbObjectToSphereConverter.INSTANCE //
|
||||
, DbObjectToPointConverter.INSTANCE //
|
||||
, PointToDbObjectConverter.INSTANCE //
|
||||
, GeoCommandToDbObjectConverter.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link List} of {@link Double}s into a {@link Point}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@ReadingConverter
|
||||
public static enum DbObjectToPointConverter implements Converter<DBObject, Point> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public Point convert(DBObject source) {
|
||||
|
||||
Assert.isTrue(source.keySet().size() == 2, "Source must contain 2 elements");
|
||||
|
||||
return source == null ? null : new org.springframework.data.mongodb.core.geo.Point((Double) source.get("x"),
|
||||
(Double) source.get("y"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link Point} into a {@link List} of {@link Double}s.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
public static enum PointToDbObjectConverter implements Converter<Point, DBObject> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public DBObject convert(Point source) {
|
||||
return source == null ? null : new BasicDBObject("x", source.getX()).append("y", source.getY());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link Box} into a {@link BasicDBList}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@WritingConverter
|
||||
public static enum BoxToDbObjectConverter implements Converter<Box, DBObject> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public DBObject convert(Box source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
result.put("first", PointToDbObjectConverter.INSTANCE.convert(source.getFirst()));
|
||||
result.put("second", PointToDbObjectConverter.INSTANCE.convert(source.getSecond()));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link BasicDBList} into a {@link org.springframework.data.mongodb.core.geo.Box}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@ReadingConverter
|
||||
public static enum DbObjectToBoxConverter implements Converter<DBObject, Box> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public Box convert(DBObject source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Point first = DbObjectToPointConverter.INSTANCE.convert((DBObject) source.get("first"));
|
||||
Point second = DbObjectToPointConverter.INSTANCE.convert((DBObject) source.get("second"));
|
||||
|
||||
return new org.springframework.data.mongodb.core.geo.Box(first, second);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link Circle} into a {@link BasicDBList}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
public static enum CircleToDbObjectConverter implements Converter<Circle, DBObject> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public DBObject convert(Circle source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DBObject result = new BasicDBObject();
|
||||
result.put("center", PointToDbObjectConverter.INSTANCE.convert(source.getCenter()));
|
||||
result.put("radius", source.getRadius().getNormalizedValue());
|
||||
result.put("metric", source.getRadius().getMetric().toString());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link DBObject} into a {@link org.springframework.data.mongodb.core.geo.Circle}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@ReadingConverter
|
||||
public static enum DbObjectToCircleConverter implements Converter<DBObject, Circle> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Circle convert(DBObject source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DBObject center = (DBObject) source.get("center");
|
||||
Double radius = (Double) source.get("radius");
|
||||
|
||||
Distance distance = new Distance(radius);
|
||||
|
||||
if (source.containsField("metric")) {
|
||||
|
||||
String metricString = (String) source.get("metric");
|
||||
Assert.notNull(metricString, "Metric must not be null!");
|
||||
|
||||
distance = distance.in(Metrics.valueOf(metricString));
|
||||
}
|
||||
|
||||
Assert.notNull(center, "Center must not be null!");
|
||||
Assert.notNull(radius, "Radius must not be null!");
|
||||
|
||||
return new Circle(DbObjectToPointConverter.INSTANCE.convert(center), distance);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link Circle} into a {@link BasicDBList}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static enum LegacyCircleToDbObjectConverter implements
|
||||
Converter<org.springframework.data.mongodb.core.geo.Circle, DBObject> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public DBObject convert(org.springframework.data.mongodb.core.geo.Circle source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DBObject result = new BasicDBObject();
|
||||
result.put("center", PointToDbObjectConverter.INSTANCE.convert(source.getCenter()));
|
||||
result.put("radius", source.getRadius());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link BasicDBList} into a {@link org.springframework.data.mongodb.core.geo.Circle}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@ReadingConverter
|
||||
@SuppressWarnings("deprecation")
|
||||
public static enum DbObjectToLegacyCircleConverter implements
|
||||
Converter<DBObject, org.springframework.data.mongodb.core.geo.Circle> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public org.springframework.data.mongodb.core.geo.Circle convert(DBObject source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DBObject centerSource = (DBObject) source.get("center");
|
||||
Double radius = (Double) source.get("radius");
|
||||
|
||||
Assert.notNull(centerSource, "Center must not be null!");
|
||||
Assert.notNull(radius, "Radius must not be null!");
|
||||
|
||||
Point center = DbObjectToPointConverter.INSTANCE.convert(centerSource);
|
||||
return new org.springframework.data.mongodb.core.geo.Circle(center, radius);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link Sphere} into a {@link BasicDBList}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
public static enum SphereToDbObjectConverter implements Converter<Sphere, DBObject> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public DBObject convert(Sphere source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DBObject result = new BasicDBObject();
|
||||
result.put("center", PointToDbObjectConverter.INSTANCE.convert(source.getCenter()));
|
||||
result.put("radius", source.getRadius().getNormalizedValue());
|
||||
result.put("metric", source.getRadius().getMetric().toString());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link BasicDBList} into a {@link Sphere}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@ReadingConverter
|
||||
public static enum DbObjectToSphereConverter implements Converter<DBObject, Sphere> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Sphere convert(DBObject source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DBObject center = (DBObject) source.get("center");
|
||||
Double radius = (Double) source.get("radius");
|
||||
|
||||
Distance distance = new Distance(radius);
|
||||
|
||||
if (source.containsField("metric")) {
|
||||
|
||||
String metricString = (String) source.get("metric");
|
||||
Assert.notNull(metricString, "Metric must not be null!");
|
||||
|
||||
distance = distance.in(Metrics.valueOf(metricString));
|
||||
}
|
||||
|
||||
Assert.notNull(center, "Center must not be null!");
|
||||
Assert.notNull(radius, "Radius must not be null!");
|
||||
|
||||
return new Sphere(DbObjectToPointConverter.INSTANCE.convert(center), distance);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link Polygon} into a {@link BasicDBList}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
public static enum PolygonToDbObjectConverter implements Converter<Polygon, DBObject> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public DBObject convert(Polygon source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Point> points = source.getPoints();
|
||||
List<DBObject> pointTuples = new ArrayList<DBObject>(points.size());
|
||||
|
||||
for (Point point : points) {
|
||||
pointTuples.add(PointToDbObjectConverter.INSTANCE.convert(point));
|
||||
}
|
||||
|
||||
DBObject result = new BasicDBObject();
|
||||
result.put("points", pointTuples);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link BasicDBList} into a {@link org.springframework.data.mongodb.core.geo.Polygon}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@ReadingConverter
|
||||
public static enum DbObjectToPolygonConverter implements Converter<DBObject, Polygon> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({ "deprecation", "unchecked" })
|
||||
public Polygon convert(DBObject source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<DBObject> points = (List<DBObject>) source.get("points");
|
||||
List<Point> newPoints = new ArrayList<Point>(points.size());
|
||||
|
||||
for (DBObject element : points) {
|
||||
|
||||
Assert.notNull(element, "Point elements of polygon must not be null!");
|
||||
newPoints.add(DbObjectToPointConverter.INSTANCE.convert(element));
|
||||
}
|
||||
|
||||
return new org.springframework.data.mongodb.core.geo.Polygon(newPoints);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link Sphere} into a {@link BasicDBList}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
public static enum GeoCommandToDbObjectConverter implements Converter<GeoCommand, DBObject> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public DBObject convert(GeoCommand source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BasicDBList argument = new BasicDBList();
|
||||
|
||||
Shape shape = source.getShape();
|
||||
|
||||
if (shape instanceof Box) {
|
||||
|
||||
argument.add(toList(((Box) shape).getFirst()));
|
||||
argument.add(toList(((Box) shape).getSecond()));
|
||||
|
||||
} else if (shape instanceof Circle) {
|
||||
|
||||
argument.add(toList(((Circle) shape).getCenter()));
|
||||
argument.add(((Circle) shape).getRadius().getNormalizedValue());
|
||||
|
||||
} else if (shape instanceof org.springframework.data.mongodb.core.geo.Circle) {
|
||||
|
||||
argument.add(toList(((org.springframework.data.mongodb.core.geo.Circle) shape).getCenter()));
|
||||
argument.add(((org.springframework.data.mongodb.core.geo.Circle) shape).getRadius());
|
||||
|
||||
} else if (shape instanceof Polygon) {
|
||||
|
||||
for (Point point : ((Polygon) shape).getPoints()) {
|
||||
argument.add(toList(point));
|
||||
}
|
||||
|
||||
} else if (shape instanceof Sphere) {
|
||||
|
||||
argument.add(toList(((Sphere) shape).getCenter()));
|
||||
argument.add(((Sphere) shape).getRadius().getNormalizedValue());
|
||||
}
|
||||
|
||||
return new BasicDBObject(source.getCommand(), argument);
|
||||
}
|
||||
}
|
||||
|
||||
static List<Double> toList(Point point) {
|
||||
return Arrays.asList(point.getX(), point.getY());
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -29,10 +31,10 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.ConversionServiceFactory;
|
||||
import org.springframework.data.convert.CollectionFactory;
|
||||
import org.springframework.data.convert.EntityInstantiator;
|
||||
import org.springframework.data.convert.TypeMapper;
|
||||
import org.springframework.data.mapping.Association;
|
||||
@@ -82,6 +84,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
protected final QueryMapper idMapper;
|
||||
protected final DbRefResolver dbRefResolver;
|
||||
protected ApplicationContext applicationContext;
|
||||
protected boolean useFieldAccessOnly = true;
|
||||
protected MongoTypeMapper typeMapper;
|
||||
protected String mapKeyDotReplacement = null;
|
||||
|
||||
@@ -165,6 +168,17 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures whether to use field access only for entity mapping. Setting this to true will force the
|
||||
* {@link MongoConverter} to not go through getters or setters even if they are present for getting and setting
|
||||
* property values.
|
||||
*
|
||||
* @param useFieldAccessOnly
|
||||
*/
|
||||
public void setUseFieldAccessOnly(boolean useFieldAccessOnly) {
|
||||
this.useFieldAccessOnly = useFieldAccessOnly;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
@@ -242,7 +256,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
|
||||
S instance = instantiator.createInstance(entity, provider);
|
||||
|
||||
final BeanWrapper<S> wrapper = BeanWrapper.create(instance, conversionService);
|
||||
final BeanWrapper<MongoPersistentEntity<S>, S> wrapper = BeanWrapper.create(instance, conversionService);
|
||||
final S result = wrapper.getBean();
|
||||
|
||||
// Set properties not already set in the constructor
|
||||
@@ -254,7 +268,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
}
|
||||
|
||||
Object obj = getValueInternal(prop, dbo, evaluator, result);
|
||||
wrapper.setProperty(prop, obj);
|
||||
wrapper.setProperty(prop, obj, useFieldAccessOnly);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -294,6 +308,11 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
Assert.isTrue(annotation != null, "The referenced property has to be mapped with @DBRef!");
|
||||
}
|
||||
|
||||
// @see DATAMONGO-913
|
||||
if (object instanceof LazyLoadingProxy) {
|
||||
return ((LazyLoadingProxy) object).toDBRef();
|
||||
}
|
||||
|
||||
return createDBRef(object, referingProperty);
|
||||
}
|
||||
|
||||
@@ -365,13 +384,15 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
throw new MappingException("No mapping metadata found for entity of type " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
final BeanWrapper<Object> wrapper = BeanWrapper.create(obj, conversionService);
|
||||
final BeanWrapper<MongoPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(obj, conversionService);
|
||||
final MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
|
||||
if (!dbo.containsField("_id") && null != idProperty) {
|
||||
|
||||
boolean fieldAccessOnly = idProperty.usePropertyAccess() ? false : useFieldAccessOnly;
|
||||
|
||||
try {
|
||||
Object id = wrapper.getProperty(idProperty, Object.class);
|
||||
Object id = wrapper.getProperty(idProperty, Object.class, fieldAccessOnly);
|
||||
dbo.put("_id", idMapper.convertId(id));
|
||||
} catch (ConversionException ignored) {}
|
||||
}
|
||||
@@ -384,7 +405,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return;
|
||||
}
|
||||
|
||||
Object propertyObj = wrapper.getProperty(prop);
|
||||
boolean fieldAccessOnly = prop.usePropertyAccess() ? false : useFieldAccessOnly;
|
||||
|
||||
Object propertyObj = wrapper.getProperty(prop, prop.getType(), fieldAccessOnly);
|
||||
|
||||
if (null != propertyObj) {
|
||||
|
||||
@@ -401,7 +424,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
public void doWithAssociation(Association<MongoPersistentProperty> association) {
|
||||
MongoPersistentProperty inverseProp = association.getInverse();
|
||||
Class<?> type = inverseProp.getType();
|
||||
Object propertyObj = wrapper.getProperty(inverseProp, type);
|
||||
Object propertyObj = wrapper.getProperty(inverseProp, type, useFieldAccessOnly);
|
||||
if (null != propertyObj) {
|
||||
writePropertyInternal(propertyObj, dbo, inverseProp);
|
||||
}
|
||||
@@ -774,8 +797,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
if (target.getClass().equals(idProperty.getType())) {
|
||||
id = target;
|
||||
} else {
|
||||
BeanWrapper<Object> wrapper = BeanWrapper.create(target, conversionService);
|
||||
id = wrapper.getProperty(idProperty, Object.class);
|
||||
BeanWrapper<MongoPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(target, conversionService);
|
||||
id = wrapper.getProperty(idProperty, Object.class, useFieldAccessOnly);
|
||||
}
|
||||
|
||||
if (null == id) {
|
||||
@@ -800,6 +823,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
* @param sourceValue must not be {@literal null}.
|
||||
* @return the converted {@link Collection} or array, will never be {@literal null}.
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "null" })
|
||||
private Object readCollectionOrArray(TypeInformation<?> targetType, BasicDBList sourceValue, Object parent) {
|
||||
|
||||
Assert.notNull(targetType);
|
||||
@@ -810,12 +834,21 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return getPotentiallyConvertedSimpleRead(new HashSet<Object>(), collectionType);
|
||||
}
|
||||
|
||||
collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class;
|
||||
|
||||
TypeInformation<?> componentType = targetType.getComponentType();
|
||||
Class<?> rawComponentType = componentType == null ? null : componentType.getType();
|
||||
|
||||
collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class;
|
||||
Collection<Object> items = targetType.getType().isArray() ? new ArrayList<Object>() : CollectionFactory
|
||||
.createCollection(collectionType, rawComponentType, sourceValue.size());
|
||||
Collection<Object> items;
|
||||
|
||||
if (targetType.getType().isArray()) {
|
||||
items = new ArrayList<Object>();
|
||||
} else if (EnumSet.class.isAssignableFrom(collectionType)) {
|
||||
Assert.notNull(rawComponentType, "Component type must not be null for enum sets!");
|
||||
items = EnumSet.noneOf(rawComponentType.asSubclass(Enum.class));
|
||||
} else {
|
||||
items = CollectionFactory.createCollection(collectionType, sourceValue.size());
|
||||
}
|
||||
|
||||
for (int i = 0; i < sourceValue.size(); i++) {
|
||||
|
||||
@@ -841,7 +874,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
* @param dbObject
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "null", "rawtypes" })
|
||||
protected Map<Object, Object> readMap(TypeInformation<?> type, DBObject dbObject, Object parent) {
|
||||
|
||||
Assert.notNull(dbObject);
|
||||
@@ -854,10 +887,19 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
TypeInformation<?> valueType = type.getMapValueType();
|
||||
Class<?> rawValueType = valueType == null ? null : valueType.getType();
|
||||
|
||||
Map<Object, Object> map = CollectionFactory.createMap(mapType, rawKeyType, dbObject.keySet().size());
|
||||
Map<Object, Object> map;
|
||||
|
||||
if (EnumMap.class.isAssignableFrom(mapType)) {
|
||||
Assert.notNull(keyType, "Key type must nut be null for enum maps!");
|
||||
map = new EnumMap(rawKeyType.asSubclass(Enum.class));
|
||||
} else {
|
||||
map = CollectionFactory.createMap(mapType, dbObject.keySet().size());
|
||||
}
|
||||
|
||||
Map<String, Object> sourceMap = dbObject.toMap();
|
||||
|
||||
for (Entry<String, Object> entry : sourceMap.entrySet()) {
|
||||
|
||||
if (typeMapper.isTypeKey(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
@@ -919,7 +961,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return getPotentiallyConvertedSimpleWrite(obj);
|
||||
}
|
||||
|
||||
TypeInformation<?> typeHint = typeInformation == null ? null : ClassTypeInformation.OBJECT;
|
||||
TypeInformation<?> typeHint = typeInformation == null ? ClassTypeInformation.OBJECT : typeInformation;
|
||||
|
||||
if (obj instanceof BasicDBList) {
|
||||
return maybeConvertList((BasicDBList) obj, typeHint);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 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.
|
||||
@@ -33,14 +33,15 @@ import com.mongodb.DBObject;
|
||||
* Wrapper class to contain useful converters for the usage with Mongo.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
abstract class MongoConverters {
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private MongoConverters() {}
|
||||
private MongoConverters() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple singleton to convert {@link ObjectId}s to their {@link String} representation.
|
||||
|
||||
@@ -250,14 +250,31 @@ public class QueryMapper {
|
||||
* type of the given value is compatible with the type of the given document field in order to deal with potential
|
||||
* query field exclusions, since MongoDB uses the {@code int} {@literal 0} as an indicator for an excluded field.
|
||||
*
|
||||
* @param documentField
|
||||
* @param documentField must not be {@literal null}.
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
protected boolean isAssociationConversionNecessary(Field documentField, Object value) {
|
||||
return documentField.isAssociation() && value != null
|
||||
&& (documentField.getProperty().getActualType().isAssignableFrom(value.getClass()) //
|
||||
|| documentField.getPropertyEntity().getIdProperty().getActualType().isAssignableFrom(value.getClass()));
|
||||
|
||||
Assert.notNull(documentField, "Document field must not be null!");
|
||||
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!documentField.isAssociation()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Class<? extends Object> type = value.getClass();
|
||||
MongoPersistentProperty property = documentField.getProperty();
|
||||
|
||||
if (property.getActualType().isAssignableFrom(type)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MongoPersistentEntity<?> entity = documentField.getPropertyEntity();
|
||||
return entity.hasIdProperty() && entity.getIdProperty().getActualType().isAssignableFrom(type);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,7 +306,7 @@ public class QueryMapper {
|
||||
* @return the converted mongo type or null if source is null
|
||||
*/
|
||||
protected Object delegateConvertToMongoType(Object source, MongoPersistentEntity<?> entity) {
|
||||
return converter.convertToMongoType(source);
|
||||
return converter.convertToMongoType(source, entity == null ? null : entity.getTypeInformation());
|
||||
}
|
||||
|
||||
protected Object convertAssociation(Object source, Field field) {
|
||||
@@ -594,6 +611,21 @@ public class QueryMapper {
|
||||
*/
|
||||
public MetadataBackedField(String name, MongoPersistentEntity<?> entity,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) {
|
||||
this(name, entity, context, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MetadataBackedField} with the given name, {@link MongoPersistentEntity} and
|
||||
* {@link MappingContext} with the given {@link MongoPersistentProperty}.
|
||||
*
|
||||
* @param name must not be {@literal null} or empty.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
* @param property may be {@literal null}.
|
||||
*/
|
||||
public MetadataBackedField(String name, MongoPersistentEntity<?> entity,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context,
|
||||
MongoPersistentProperty property) {
|
||||
|
||||
super(name);
|
||||
|
||||
@@ -603,7 +635,7 @@ public class QueryMapper {
|
||||
this.mappingContext = context;
|
||||
|
||||
this.path = getPath(name);
|
||||
this.property = path == null ? null : path.getLeafProperty();
|
||||
this.property = path == null ? property : path.getLeafProperty();
|
||||
this.association = findAssociation();
|
||||
}
|
||||
|
||||
@@ -613,7 +645,7 @@ public class QueryMapper {
|
||||
*/
|
||||
@Override
|
||||
public MetadataBackedField with(String name) {
|
||||
return new MetadataBackedField(name, entity, mappingContext);
|
||||
return new MetadataBackedField(name, entity, mappingContext, property);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty.PropertyToFieldNameConverter;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update.Modifier;
|
||||
import org.springframework.data.mongodb.core.query.Update.Modifiers;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
@@ -79,10 +80,19 @@ public class UpdateMapper extends QueryMapper {
|
||||
return createMapEntry(field, convertSimpleOrDBObject(rawValue, field.getPropertyEntity()));
|
||||
}
|
||||
|
||||
if (!isUpdateModifier(rawValue)) {
|
||||
return super.getMappedObjectForField(field, getMappedValue(field, rawValue));
|
||||
if (isQuery(rawValue)) {
|
||||
return createMapEntry(field,
|
||||
super.getMappedObject(((Query) rawValue).getQueryObject(), field.getPropertyEntity()));
|
||||
}
|
||||
|
||||
if (isUpdateModifier(rawValue)) {
|
||||
return getMappedUpdateModifier(field, rawValue);
|
||||
}
|
||||
|
||||
return super.getMappedObjectForField(field, getMappedValue(field, rawValue));
|
||||
}
|
||||
|
||||
private Entry<String, Object> getMappedUpdateModifier(Field field, Object rawValue) {
|
||||
Object value = null;
|
||||
|
||||
if (rawValue instanceof Modifier) {
|
||||
@@ -99,7 +109,6 @@ public class UpdateMapper extends QueryMapper {
|
||||
|
||||
value = modificationOperations;
|
||||
} else {
|
||||
|
||||
throw new IllegalArgumentException(String.format("Unable to map value of type '%s'!", rawValue.getClass()));
|
||||
}
|
||||
|
||||
@@ -119,6 +128,10 @@ public class UpdateMapper extends QueryMapper {
|
||||
return value instanceof Modifier || value instanceof Modifiers;
|
||||
}
|
||||
|
||||
private boolean isQuery(Object value) {
|
||||
return value instanceof Query;
|
||||
}
|
||||
|
||||
private DBObject getMappedValue(Modifier modifier) {
|
||||
|
||||
Object value = converter.convertToMongoType(modifier.getValue(), ClassTypeInformation.OBJECT);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2014 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -16,31 +16,44 @@
|
||||
package org.springframework.data.mongodb.core.geo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Represents a geospatial box value.
|
||||
* Represents a geospatial box value
|
||||
*
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.Box}. This class is scheduled to be
|
||||
* removed in the next major release.
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Deprecated
|
||||
public class Box extends org.springframework.data.geo.Box implements Shape {
|
||||
public class Box implements Shape {
|
||||
|
||||
public static final String COMMAND = "$box";
|
||||
@Field(order = 10)
|
||||
private final Point first;
|
||||
@Field(order = 20)
|
||||
private final Point second;
|
||||
|
||||
public Box(Point lowerLeft, Point upperRight) {
|
||||
super(lowerLeft, upperRight);
|
||||
Assert.notNull(lowerLeft);
|
||||
Assert.notNull(upperRight);
|
||||
this.first = lowerLeft;
|
||||
this.second = upperRight;
|
||||
}
|
||||
|
||||
public Box(double[] lowerLeft, double[] upperRight) {
|
||||
super(lowerLeft, upperRight);
|
||||
Assert.isTrue(lowerLeft.length == 2, "Point array has to have 2 elements!");
|
||||
Assert.isTrue(upperRight.length == 2, "Point array has to have 2 elements!");
|
||||
this.first = new Point(lowerLeft[0], lowerLeft[1]);
|
||||
this.second = new Point(upperRight[0], upperRight[1]);
|
||||
}
|
||||
|
||||
public Point getLowerLeft() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public Point getUpperRight() {
|
||||
return second;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -48,28 +61,46 @@ public class Box extends org.springframework.data.geo.Box implements Shape {
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#asList()
|
||||
*/
|
||||
public List<? extends Object> asList() {
|
||||
|
||||
List<List<Double>> list = new ArrayList<List<Double>>();
|
||||
|
||||
list.add(Arrays.asList(getFirst().getX(), getFirst().getY()));
|
||||
list.add(Arrays.asList(getSecond().getX(), getSecond().getY()));
|
||||
|
||||
list.add(getLowerLeft().asList());
|
||||
list.add(getUpperRight().asList());
|
||||
return list;
|
||||
}
|
||||
|
||||
public org.springframework.data.mongodb.core.geo.Point getLowerLeft() {
|
||||
return new org.springframework.data.mongodb.core.geo.Point(getFirst());
|
||||
}
|
||||
|
||||
public org.springframework.data.mongodb.core.geo.Point getUpperRight() {
|
||||
return new org.springframework.data.mongodb.core.geo.Point(getSecond());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
||||
*/
|
||||
public String getCommand() {
|
||||
return COMMAND;
|
||||
return "$box";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Box [%s, %s]", first, second);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 31;
|
||||
result += 17 * first.hashCode();
|
||||
result += 17 * second.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Box that = (Box) obj;
|
||||
return this.first.equals(that.first) && this.second.equals(that.second);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2014 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -16,32 +16,19 @@
|
||||
package org.springframework.data.mongodb.core.geo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Represents a geospatial circle value.
|
||||
* <p>
|
||||
* Note: We deliberately do not extend org.springframework.data.geo.Circle because introducing it's distance concept
|
||||
* would break the clients that use the old Circle API.
|
||||
* Represents a geospatial circle value
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.Circle}. This class is scheduled to be
|
||||
* removed in the next major release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class Circle implements Shape {
|
||||
|
||||
public static final String COMMAND = "$center";
|
||||
|
||||
private final Point center;
|
||||
private final double radius;
|
||||
|
||||
@@ -62,8 +49,7 @@ public class Circle implements Shape {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Circle} from the given coordinates and radius as {@link Distance} with a
|
||||
* {@link Metrics#NEUTRAL}.
|
||||
* Creates a new {@link Circle} from the given coordinates and radius.
|
||||
*
|
||||
* @param centerX
|
||||
* @param centerY
|
||||
@@ -96,11 +82,9 @@ public class Circle implements Shape {
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#asList()
|
||||
*/
|
||||
public List<Object> asList() {
|
||||
|
||||
List<Object> result = new ArrayList<Object>();
|
||||
result.add(Arrays.asList(getCenter().getX(), getCenter().getY()));
|
||||
result.add(getCenter().asList());
|
||||
result.add(getRadius());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -109,7 +93,7 @@ public class Circle implements Shape {
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
||||
*/
|
||||
public String getCommand() {
|
||||
return COMMAND;
|
||||
return "$center";
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* Copyright 2013 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,13 +18,11 @@ package org.springframework.data.mongodb.core.geo;
|
||||
/**
|
||||
* Value object to create custom {@link Metric}s on the fly.
|
||||
*
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.Metric}. This class is scheduled to be
|
||||
* removed in the next major release.
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Deprecated
|
||||
public class CustomMetric extends org.springframework.data.geo.CustomMetric implements Metric {
|
||||
public class CustomMetric implements Metric {
|
||||
|
||||
private final double multiplier;
|
||||
|
||||
/**
|
||||
* Creates a custom {@link Metric} using the given multiplier.
|
||||
@@ -32,6 +30,14 @@ public class CustomMetric extends org.springframework.data.geo.CustomMetric impl
|
||||
* @param multiplier
|
||||
*/
|
||||
public CustomMetric(double multiplier) {
|
||||
super(multiplier);
|
||||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Metric#getMultiplier()
|
||||
*/
|
||||
public double getMultiplier() {
|
||||
return multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2014 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -15,19 +15,17 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.geo;
|
||||
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Value object to represent distances in a given metric.
|
||||
*
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.Distance}. This class is scheduled to
|
||||
* be removed in the next major release.
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Deprecated
|
||||
public class Distance extends org.springframework.data.geo.Distance {
|
||||
public class Distance {
|
||||
|
||||
private final double value;
|
||||
private final Metric metric;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Distance}.
|
||||
@@ -38,7 +36,110 @@ public class Distance extends org.springframework.data.geo.Distance {
|
||||
this(value, Metrics.NEUTRAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Distance} with the given {@link Metric}.
|
||||
*
|
||||
* @param value
|
||||
* @param metric
|
||||
*/
|
||||
public Distance(double value, Metric metric) {
|
||||
super(value, metric);
|
||||
this.value = value;
|
||||
this.metric = metric == null ? Metrics.NEUTRAL : metric;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value
|
||||
*/
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the normalized value regarding the underlying {@link Metric}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getNormalizedValue() {
|
||||
return value / metric.getMultiplier();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the metric
|
||||
*/
|
||||
public Metric getMetric() {
|
||||
return metric;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given distance to the current one. The resulting {@link Distance} will be in the same metric as the
|
||||
* current one.
|
||||
*
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
public Distance add(Distance other) {
|
||||
double newNormalizedValue = getNormalizedValue() + other.getNormalizedValue();
|
||||
return new Distance(newNormalizedValue * metric.getMultiplier(), metric);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given {@link Distance} to the current one and forces the result to be in a given {@link Metric}.
|
||||
*
|
||||
* @param other
|
||||
* @param metric
|
||||
* @return
|
||||
*/
|
||||
public Distance add(Distance other, Metric metric) {
|
||||
double newLeft = getNormalizedValue() * metric.getMultiplier();
|
||||
double newRight = other.getNormalizedValue() * metric.getMultiplier();
|
||||
return new Distance(newLeft + newRight, metric);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Distance that = (Distance) obj;
|
||||
|
||||
return this.value == that.value && ObjectUtils.nullSafeEquals(this.metric, that.metric);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result += 31 * Double.doubleToLongBits(value);
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(metric);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(value);
|
||||
|
||||
if (metric != Metrics.NEUTRAL) {
|
||||
builder.append(" ").append(metric.toString());
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -16,21 +16,19 @@
|
||||
package org.springframework.data.mongodb.core.geo;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
/**
|
||||
* Custom {@link Page} to carry the average distance retrieved from the {@link GeoResults} the {@link GeoPage} is set up
|
||||
* from.
|
||||
*
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.GeoPage}. This class is scheduled to
|
||||
* be removed in the next major release.
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Deprecated
|
||||
public class GeoPage<T> extends org.springframework.data.geo.GeoPage<T> {
|
||||
public class GeoPage<T> extends PageImpl<GeoResult<T>> {
|
||||
|
||||
private static final long serialVersionUID = 23421312312412L;
|
||||
private final Distance averageDistance;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GeoPage} from the given {@link GeoResults}.
|
||||
@@ -38,7 +36,8 @@ public class GeoPage<T> extends org.springframework.data.geo.GeoPage<T> {
|
||||
* @param content must not be {@literal null}.
|
||||
*/
|
||||
public GeoPage(GeoResults<T> results) {
|
||||
super(results);
|
||||
super(results.getContent());
|
||||
this.averageDistance = results.getAverageDistance();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,6 +48,16 @@ public class GeoPage<T> extends org.springframework.data.geo.GeoPage<T> {
|
||||
* @param total
|
||||
*/
|
||||
public GeoPage(GeoResults<T> results, Pageable pageable, long total) {
|
||||
super(results, pageable, total);
|
||||
super(results.getContent(), pageable, total);
|
||||
this.averageDistance = results.getAverageDistance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average distance of the underlying results.
|
||||
*
|
||||
* @return the averageDistance
|
||||
*/
|
||||
public Distance getAverageDistance() {
|
||||
return averageDistance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,16 +15,17 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.geo;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Calue object capturing some arbitrary object plus a distance.
|
||||
*
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.GeoResult}. This class is scheduled to
|
||||
* be removed in the next major release.
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Deprecated
|
||||
public class GeoResult<T> extends org.springframework.data.geo.GeoResult<T> {
|
||||
public class GeoResult<T> {
|
||||
|
||||
private final T content;
|
||||
private final Distance distance;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GeoResult} for the given content and distance.
|
||||
@@ -33,6 +34,69 @@ public class GeoResult<T> extends org.springframework.data.geo.GeoResult<T> {
|
||||
* @param distance must not be {@literal null}.
|
||||
*/
|
||||
public GeoResult(T content, Distance distance) {
|
||||
super(content, distance);
|
||||
Assert.notNull(content);
|
||||
Assert.notNull(distance);
|
||||
this.content = content;
|
||||
this.distance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual content object.
|
||||
*
|
||||
* @return the content
|
||||
*/
|
||||
public T getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distance the actual content object has from the origin.
|
||||
*
|
||||
* @return the distance
|
||||
*/
|
||||
public Distance getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GeoResult<?> that = (GeoResult<?>) obj;
|
||||
|
||||
return this.content.equals(that.content) && this.distance.equals(that.distance);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
result += 31 * distance.hashCode();
|
||||
result += 31 * content.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("GeoResult [content: %s, distance: %s, ]", content.toString(), distance.toString());
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,23 +15,23 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.geo;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Value object to capture {@link GeoResult}s as well as the average distance they have.
|
||||
*
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.GeoResults}. This class is scheduled
|
||||
* to be removed in the next major release.
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Deprecated
|
||||
public class GeoResults<T> extends org.springframework.data.geo.GeoResults<T> {
|
||||
public class GeoResults<T> implements Iterable<GeoResult<T>> {
|
||||
|
||||
private final List<GeoResult<T>> results;
|
||||
private final Distance averageDistance;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GeoResults} instance manually calculating the average distance from the distance values of the
|
||||
@@ -39,12 +39,12 @@ public class GeoResults<T> extends org.springframework.data.geo.GeoResults<T> {
|
||||
*
|
||||
* @param results must not be {@literal null}.
|
||||
*/
|
||||
public GeoResults(List<? extends GeoResult<T>> results) {
|
||||
super(results);
|
||||
public GeoResults(List<GeoResult<T>> results) {
|
||||
this(results, (Metric) null);
|
||||
}
|
||||
|
||||
public GeoResults(List<? extends GeoResult<T>> results, Metric metric) {
|
||||
super(results, metric);
|
||||
public GeoResults(List<GeoResult<T>> results, Metric metric) {
|
||||
this(results, calculateAverageDistance(results, metric));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +54,92 @@ public class GeoResults<T> extends org.springframework.data.geo.GeoResults<T> {
|
||||
* @param averageDistance
|
||||
*/
|
||||
@PersistenceConstructor
|
||||
public GeoResults(List<? extends GeoResult<T>> results, Distance averageDistance) {
|
||||
super(results, averageDistance);
|
||||
public GeoResults(List<GeoResult<T>> results, Distance averageDistance) {
|
||||
Assert.notNull(results);
|
||||
this.results = results;
|
||||
this.averageDistance = averageDistance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average distance of all {@link GeoResult}s in this list.
|
||||
*
|
||||
* @return the averageDistance
|
||||
*/
|
||||
public Distance getAverageDistance() {
|
||||
return averageDistance;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
public Iterator<GeoResult<T>> iterator() {
|
||||
return results.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<GeoResult<T>> getContent() {
|
||||
return Collections.unmodifiableList(results);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GeoResults<?> that = (GeoResults<?>) obj;
|
||||
|
||||
return this.results.equals(that.results) && this.averageDistance == that.averageDistance;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result += 31 * results.hashCode();
|
||||
result += 31 * averageDistance.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("GeoResults: [averageDistance: %s, results: %s]", averageDistance.toString(),
|
||||
StringUtils.collectionToCommaDelimitedString(results));
|
||||
}
|
||||
|
||||
private static Distance calculateAverageDistance(List<? extends GeoResult<?>> results, Metric metric) {
|
||||
|
||||
if (results.isEmpty()) {
|
||||
return new Distance(0, metric);
|
||||
}
|
||||
|
||||
double averageDistance = 0;
|
||||
|
||||
for (GeoResult<?> result : results) {
|
||||
averageDistance += result.getDistance().getValue();
|
||||
}
|
||||
|
||||
return new Distance(averageDistance / results.size(), metric);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,16 @@
|
||||
/*
|
||||
* Copyright 2011-2014 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.geo;
|
||||
|
||||
/**
|
||||
* Interface for {@link Metric}s that can be applied to a base scale.
|
||||
*
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.Metric}. This class is scheduled to be
|
||||
* removed in the next major release.
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Deprecated
|
||||
public interface Metric extends org.springframework.data.geo.Metric {}
|
||||
public interface Metric {
|
||||
|
||||
/**
|
||||
* Returns the multiplier to calculate metrics values from a base scale.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
double getMultiplier();
|
||||
}
|
||||
@@ -1,18 +1,3 @@
|
||||
/*
|
||||
* Copyright 2011-2014 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.geo;
|
||||
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
@@ -20,17 +5,11 @@ import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
/**
|
||||
* Commonly used {@link Metrics} for {@link NearQuery}s.
|
||||
*
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.Metrics}. This class is scheduled to
|
||||
* be removed in the next major release.
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Deprecated
|
||||
public enum Metrics implements Metric {
|
||||
|
||||
KILOMETERS(org.springframework.data.geo.Metrics.KILOMETERS.getMultiplier()), //
|
||||
MILES(org.springframework.data.geo.Metrics.MILES.getMultiplier()), //
|
||||
NEUTRAL(org.springframework.data.geo.Metrics.NEUTRAL.getMultiplier()); //
|
||||
KILOMETERS(6378.137), MILES(3963.191), NEUTRAL(1);
|
||||
|
||||
private final double multiplier;
|
||||
|
||||
@@ -45,4 +24,4 @@ public enum Metrics implements Metric {
|
||||
public double getMultiplier() {
|
||||
return multiplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,37 +19,83 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Represents a geospatial point value.
|
||||
*
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.Point}. This class is scheduled to be
|
||||
* removed in the next major release.
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Deprecated
|
||||
public class Point extends org.springframework.data.geo.Point {
|
||||
public class Point {
|
||||
|
||||
@Field(order = 10) private final double x;
|
||||
@Field(order = 20) private final double y;
|
||||
|
||||
@PersistenceConstructor
|
||||
public Point(double x, double y) {
|
||||
super(x, y);
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Point(org.springframework.data.geo.Point point) {
|
||||
super(point);
|
||||
public Point(Point point) {
|
||||
Assert.notNull(point);
|
||||
this.x = point.x;
|
||||
this.y = point.y;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double[] asArray() {
|
||||
return new double[] { getX(), getY() };
|
||||
return new double[] { x, y };
|
||||
}
|
||||
|
||||
public List<Double> asList() {
|
||||
return asList(this);
|
||||
return Arrays.asList(x, y);
|
||||
}
|
||||
|
||||
public static List<Double> asList(org.springframework.data.geo.Point point) {
|
||||
return Arrays.asList(point.getX(), point.getY());
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(x);
|
||||
result = prime * result + (int) (temp ^ temp >>> 32);
|
||||
temp = Double.doubleToLongBits(y);
|
||||
result = prime * result + (int) (temp ^ temp >>> 32);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Point other = (Point) obj;
|
||||
if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x)) {
|
||||
return false;
|
||||
}
|
||||
if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Point [x=%f, y=%f]", x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -17,22 +17,19 @@ package org.springframework.data.mongodb.core.geo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple value object to represent a {@link Polygon}.
|
||||
*
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.Point}. This class is scheduled to be
|
||||
* removed in the next major release.
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Deprecated
|
||||
public class Polygon extends org.springframework.data.geo.Polygon implements Shape {
|
||||
public class Polygon implements Shape, Iterable<Point> {
|
||||
|
||||
public static final String COMMAND = "$polygon";
|
||||
private final List<Point> points;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Polygon} for the given Points.
|
||||
@@ -42,17 +39,31 @@ public class Polygon extends org.springframework.data.geo.Polygon implements Sha
|
||||
* @param z
|
||||
* @param others
|
||||
*/
|
||||
public <P extends Point> Polygon(P x, P y, P z, P... others) {
|
||||
super(x, y, z, others);
|
||||
public Polygon(Point x, Point y, Point z, Point... others) {
|
||||
|
||||
Assert.notNull(x);
|
||||
Assert.notNull(y);
|
||||
Assert.notNull(z);
|
||||
Assert.notNull(others);
|
||||
|
||||
this.points = new ArrayList<Point>(3 + others.length);
|
||||
this.points.addAll(Arrays.asList(x, y, z));
|
||||
this.points.addAll(Arrays.asList(others));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Polygon} for the given Points.
|
||||
*
|
||||
* @param points
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#asList()
|
||||
*/
|
||||
public <P extends Point> Polygon(List<P> points) {
|
||||
super(points);
|
||||
public List<List<Double>> asList() {
|
||||
|
||||
List<List<Double>> result = new ArrayList<List<Double>>();
|
||||
|
||||
for (Point point : points) {
|
||||
result.add(point.asList());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -60,33 +71,43 @@ public class Polygon extends org.springframework.data.geo.Polygon implements Sha
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
||||
*/
|
||||
public String getCommand() {
|
||||
return COMMAND;
|
||||
return "$polygon";
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#asList()
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
public Iterator<Point> iterator() {
|
||||
return this.points.iterator();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public List<? extends Object> asList() {
|
||||
return asList(this);
|
||||
}
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
/**
|
||||
* Returns a {@link List} of x,y-coordinate tuples of {@link Point}s from the given {@link Polygon}.
|
||||
*
|
||||
* @param polygon
|
||||
* @return
|
||||
*/
|
||||
public static List<? extends Object> asList(org.springframework.data.geo.Polygon polygon) {
|
||||
|
||||
List<Point> points = polygon.getPoints();
|
||||
List<List<Double>> tuples = new ArrayList<List<Double>>(points.size());
|
||||
|
||||
for (Point point : points) {
|
||||
tuples.add(Arrays.asList(point.getX(), point.getY()));
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return tuples;
|
||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Polygon that = (Polygon) obj;
|
||||
|
||||
return this.points.equals(that.points);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return points.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -20,13 +20,9 @@ import java.util.List;
|
||||
/**
|
||||
* Common interface for all shapes. Allows building MongoDB representations of them.
|
||||
*
|
||||
* @deprecated As of release 1.5, replaced by {@link org.springframework.data.geo.Shape}. This class is scheduled to be
|
||||
* removed in the next major release.
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Deprecated
|
||||
public interface Shape extends org.springframework.data.geo.Shape {
|
||||
public interface Shape {
|
||||
|
||||
/**
|
||||
* Returns the {@link Shape} as a list of usually {@link Double} or {@link List}s of {@link Double}s. Wildcard bound
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 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.geo;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Represents a geospatial sphere value.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class Sphere implements Shape {
|
||||
|
||||
public static final String COMMAND = "$centerSphere";
|
||||
private final Point center;
|
||||
private final Distance radius;
|
||||
|
||||
/**
|
||||
* Creates a Sphere around the given center {@link Point} with the given radius.
|
||||
*
|
||||
* @param center must not be {@literal null}.
|
||||
* @param radius must not be {@literal null}.
|
||||
*/
|
||||
@PersistenceConstructor
|
||||
public Sphere(Point center, Distance radius) {
|
||||
|
||||
Assert.notNull(center);
|
||||
Assert.notNull(radius);
|
||||
Assert.isTrue(radius.getValue() >= 0, "Radius must not be negative!");
|
||||
|
||||
this.center = center;
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Sphere around the given center {@link Point} with the given radius.
|
||||
*
|
||||
* @param center
|
||||
* @param radius
|
||||
*/
|
||||
public Sphere(Point center, double radius) {
|
||||
this(center, new Distance(radius));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Sphere from the given {@link Circle}.
|
||||
*
|
||||
* @param circle
|
||||
*/
|
||||
public Sphere(Circle circle) {
|
||||
this(circle.getCenter(), circle.getRadius());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Sphere from the given {@link Circle}.
|
||||
*
|
||||
* @param circle
|
||||
*/
|
||||
@Deprecated
|
||||
public Sphere(org.springframework.data.mongodb.core.geo.Circle circle) {
|
||||
this(circle.getCenter(), circle.getRadius());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the center of the {@link Circle}.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
public org.springframework.data.mongodb.core.geo.Point getCenter() {
|
||||
return new org.springframework.data.mongodb.core.geo.Point(this.center);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the radius of the {@link Circle}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Distance getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Sphere [center=%s, radius=%s]", center, radius);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null || !(obj instanceof Sphere)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Sphere that = (Sphere) obj;
|
||||
|
||||
return this.center.equals(that.center) && this.radius.equals(that.radius);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result += 31 * center.hashCode();
|
||||
result += 31 * radius.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#asList()
|
||||
*/
|
||||
@Override
|
||||
public List<? extends Object> asList() {
|
||||
return Arrays.asList(Arrays.asList(center.getX(), center.getY()), this.radius.getValue());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Shape#getCommand()
|
||||
*/
|
||||
@Override
|
||||
public String getCommand() {
|
||||
return COMMAND;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,3 @@
|
||||
/*
|
||||
* Copyright 2011-2014 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.
|
||||
*/
|
||||
/**
|
||||
* Support for MongoDB geo-spatial queries.
|
||||
*/
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.index;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -118,20 +119,22 @@ public class MongoPersistentEntityIndexCreator implements
|
||||
}
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||
public void doWithPersistentProperty(MongoPersistentProperty property) {
|
||||
public void doWithPersistentProperty(MongoPersistentProperty persistentProperty) {
|
||||
|
||||
if (property.isAnnotationPresent(Indexed.class)) {
|
||||
Field field = persistentProperty.getField();
|
||||
|
||||
Indexed index = property.findAnnotation(Indexed.class);
|
||||
if (field.isAnnotationPresent(Indexed.class)) {
|
||||
|
||||
Indexed index = field.getAnnotation(Indexed.class);
|
||||
String name = index.name();
|
||||
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = property.getFieldName();
|
||||
name = persistentProperty.getFieldName();
|
||||
} else {
|
||||
if (!name.equals(property.getName()) && index.unique() && !index.sparse()) {
|
||||
if (!name.equals(field.getName()) && index.unique() && !index.sparse()) {
|
||||
// Names don't match, and sparse is not true. This situation will generate an error on the server.
|
||||
if (LOGGER.isWarnEnabled()) {
|
||||
LOGGER.warn("The index name " + name + " doesn't match this property name: " + property.getName()
|
||||
LOGGER.warn("The index name " + name + " doesn't match this property name: " + field.getName()
|
||||
+ ". Setting sparse=true on this index will prevent errors when inserting documents.");
|
||||
}
|
||||
}
|
||||
@@ -139,7 +142,7 @@ public class MongoPersistentEntityIndexCreator implements
|
||||
|
||||
String collection = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection();
|
||||
int direction = index.direction() == IndexDirection.ASCENDING ? 1 : -1;
|
||||
DBObject definition = new BasicDBObject(property.getFieldName(), direction);
|
||||
DBObject definition = new BasicDBObject(persistentProperty.getFieldName(), direction);
|
||||
|
||||
ensureIndex(collection, name, definition, index.unique(), index.dropDups(), index.sparse(),
|
||||
index.background(), index.expireAfterSeconds());
|
||||
@@ -148,13 +151,13 @@ public class MongoPersistentEntityIndexCreator implements
|
||||
LOGGER.debug("Created property index " + index);
|
||||
}
|
||||
|
||||
} else if (property.isAnnotationPresent(GeoSpatialIndexed.class)) {
|
||||
} else if (field.isAnnotationPresent(GeoSpatialIndexed.class)) {
|
||||
|
||||
GeoSpatialIndexed index = property.findAnnotation(GeoSpatialIndexed.class);
|
||||
GeoSpatialIndexed index = field.getAnnotation(GeoSpatialIndexed.class);
|
||||
|
||||
GeospatialIndex indexObject = new GeospatialIndex(property.getFieldName());
|
||||
GeospatialIndex indexObject = new GeospatialIndex(persistentProperty.getFieldName());
|
||||
indexObject.withMin(index.min()).withMax(index.max());
|
||||
indexObject.named(StringUtils.hasText(index.name()) ? index.name() : property.getName());
|
||||
indexObject.named(StringUtils.hasText(index.name()) ? index.name() : field.getName());
|
||||
indexObject.typed(index.type()).withBucketSize(index.bucketSize())
|
||||
.withAdditionalField(index.additionalField());
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
@@ -49,14 +50,17 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
private static final Set<Class<?>> SUPPORTED_ID_TYPES = new HashSet<Class<?>>();
|
||||
private static final Set<String> SUPPORTED_ID_PROPERTY_NAMES = new HashSet<String>();
|
||||
|
||||
static {
|
||||
private static final Field CAUSE_FIELD;
|
||||
|
||||
static {
|
||||
SUPPORTED_ID_TYPES.add(ObjectId.class);
|
||||
SUPPORTED_ID_TYPES.add(String.class);
|
||||
SUPPORTED_ID_TYPES.add(BigInteger.class);
|
||||
|
||||
SUPPORTED_ID_PROPERTY_NAMES.add("id");
|
||||
SUPPORTED_ID_PROPERTY_NAMES.add("_id");
|
||||
|
||||
CAUSE_FIELD = ReflectionUtils.findField(Throwable.class, "cause");
|
||||
}
|
||||
|
||||
private final FieldNamingStrategy fieldNamingStrategy;
|
||||
@@ -82,6 +86,14 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.FooBasicPersistentProperty#isAssociation()
|
||||
*/
|
||||
@Override
|
||||
public boolean isAssociation() {
|
||||
return field.isAnnotationPresent(DBRef.class) || super.isAssociation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Also considers fields as id that are of supported id type and name.
|
||||
*
|
||||
@@ -96,7 +108,7 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
}
|
||||
|
||||
// We need to support a wider range of ID types than just the ones that can be converted to an ObjectId
|
||||
return SUPPORTED_ID_PROPERTY_NAMES.contains(getName());
|
||||
return SUPPORTED_ID_PROPERTY_NAMES.contains(field.getName());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -151,7 +163,8 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#getFieldOrder()
|
||||
*/
|
||||
public int getFieldOrder() {
|
||||
org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
|
||||
org.springframework.data.mongodb.core.mapping.Field annotation = getField().getAnnotation(
|
||||
org.springframework.data.mongodb.core.mapping.Field.class);
|
||||
return annotation != null ? annotation.order() : Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@@ -169,7 +182,7 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#isDbReference()
|
||||
*/
|
||||
public boolean isDbReference() {
|
||||
return isAnnotationPresent(DBRef.class);
|
||||
return getField().isAnnotationPresent(DBRef.class);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -177,6 +190,14 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#getDBRef()
|
||||
*/
|
||||
public DBRef getDBRef() {
|
||||
return findAnnotation(DBRef.class);
|
||||
return getField().getAnnotation(DBRef.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#usePropertyAccess()
|
||||
*/
|
||||
public boolean usePropertyAccess() {
|
||||
return CAUSE_FIELD.equals(getField());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,13 +126,13 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
|
||||
|
||||
public void onAfterDelete(DBObject dbo) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onAfterConvert({})", dbo);
|
||||
LOG.debug("onAfterDelete({})", dbo);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBeforeDelete(DBObject dbo) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onAfterConvert({})", dbo);
|
||||
LOG.debug("onBeforeDelete({})", dbo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapping.event;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.data.auditing.AuditingHandler;
|
||||
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
|
||||
@@ -26,22 +25,20 @@ import org.springframework.util.Assert;
|
||||
* Event listener to populate auditing related fields on an entity about to be saved.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class AuditingEventListener implements ApplicationListener<BeforeConvertEvent<Object>> {
|
||||
|
||||
private final ObjectFactory<IsNewAwareAuditingHandler> auditingHandlerFactory;
|
||||
private final IsNewAwareAuditingHandler auditingHandler;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AuditingEventListener} using the given {@link MappingContext} and {@link AuditingHandler}
|
||||
* provided by the given {@link ObjectFactory}.
|
||||
* Creates a new {@link AuditingEventListener} using the given {@link MappingContext} and {@link AuditingHandler}.
|
||||
*
|
||||
* @param auditingHandlerFactory must not be {@literal null}.
|
||||
* @param auditingHandler must not be {@literal null}.
|
||||
*/
|
||||
public AuditingEventListener(ObjectFactory<IsNewAwareAuditingHandler> auditingHandlerFactory) {
|
||||
public AuditingEventListener(IsNewAwareAuditingHandler auditingHandler) {
|
||||
|
||||
Assert.notNull(auditingHandlerFactory, "IsNewAwareAuditingHandler must not be null!");
|
||||
this.auditingHandlerFactory = auditingHandlerFactory;
|
||||
Assert.notNull(auditingHandler, "IsNewAwareAuditingHandler must not be null!");
|
||||
this.auditingHandler = auditingHandler;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -51,6 +48,6 @@ public class AuditingEventListener implements ApplicationListener<BeforeConvertE
|
||||
public void onApplicationEvent(BeforeConvertEvent<Object> event) {
|
||||
|
||||
Object entity = event.getSource();
|
||||
auditingHandlerFactory.getObject().markAudited(entity);
|
||||
auditingHandler.markAudited(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,10 @@ import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bson.BSON;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Shape;
|
||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||
import org.springframework.data.mongodb.core.geo.Sphere;
|
||||
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.ObjectUtils;
|
||||
|
||||
@@ -384,21 +383,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
*/
|
||||
public Criteria withinSphere(Circle circle) {
|
||||
Assert.notNull(circle);
|
||||
criteria.put("$within", new GeoCommand(new Sphere(circle)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Criteria#withinSphere(Circle)
|
||||
* @param circle
|
||||
* @return
|
||||
* @deprecated As of 1.5, Use {@link #withinSphere(Circle)}. This method is scheduled to be removed in the next major
|
||||
* release.
|
||||
*/
|
||||
@Deprecated
|
||||
public Criteria withinSphere(org.springframework.data.mongodb.core.geo.Circle circle) {
|
||||
Assert.notNull(circle);
|
||||
criteria.put("$within", new GeoCommand(new Sphere(circle)));
|
||||
criteria.put("$within", new BasicDBObject("$centerSphere", circle.asList()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -412,7 +397,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
public Criteria within(Shape shape) {
|
||||
|
||||
Assert.notNull(shape);
|
||||
criteria.put("$within", new GeoCommand(shape));
|
||||
criteria.put("$within", new BasicDBObject(shape.getCommand(), shape.asList()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -425,7 +410,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
*/
|
||||
public Criteria near(Point point) {
|
||||
Assert.notNull(point);
|
||||
criteria.put("$near", point);
|
||||
criteria.put("$near", point.asList());
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -439,7 +424,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
*/
|
||||
public Criteria nearSphere(Point point) {
|
||||
Assert.notNull(point);
|
||||
criteria.put("$nearSphere", point);
|
||||
criteria.put("$nearSphere", point.asList());
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.geo.Shape;
|
||||
import org.springframework.data.mongodb.core.geo.Sphere;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Wrapper around a {@link Shape} to allow appropriate query rendering.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @since 1.5
|
||||
*/
|
||||
public class GeoCommand {
|
||||
|
||||
private final Shape shape;
|
||||
private final String command;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GeoCommand}.
|
||||
*
|
||||
* @param shape must not be {@literal null}.
|
||||
*/
|
||||
public GeoCommand(Shape shape) {
|
||||
|
||||
Assert.notNull(shape, "Shape must not be null!");
|
||||
|
||||
this.shape = shape;
|
||||
this.command = getCommand(shape);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the shape
|
||||
*/
|
||||
public Shape getShape() {
|
||||
return shape;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the command
|
||||
*/
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MongoDB command for the given {@link Shape}.
|
||||
*
|
||||
* @param shape must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private String getCommand(Shape shape) {
|
||||
|
||||
Assert.notNull(shape, "Shape must not be null!");
|
||||
|
||||
if (shape instanceof Box) {
|
||||
return org.springframework.data.mongodb.core.geo.Box.COMMAND;
|
||||
} else if (shape instanceof Circle || shape instanceof org.springframework.data.mongodb.core.geo.Circle) {
|
||||
return org.springframework.data.mongodb.core.geo.Circle.COMMAND;
|
||||
} else if (shape instanceof Polygon) {
|
||||
return org.springframework.data.mongodb.core.geo.Polygon.COMMAND;
|
||||
} else if (shape instanceof Sphere) {
|
||||
return org.springframework.data.mongodb.core.geo.Sphere.COMMAND;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown shape: " + shape);
|
||||
}
|
||||
}
|
||||
@@ -15,14 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.geo.CustomMetric;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.core.geo.CustomMetric;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.Metric;
|
||||
import org.springframework.data.mongodb.core.geo.Metrics;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
@@ -343,7 +341,6 @@ public final class NearQuery {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public DBObject toDBObject() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
@@ -364,8 +361,7 @@ public final class NearQuery {
|
||||
dbObject.put("num", num);
|
||||
}
|
||||
|
||||
dbObject.put("near", Arrays.asList(point.getX(), point.getY()));
|
||||
|
||||
dbObject.put("near", point.asList());
|
||||
dbObject.put("spherical", spherical);
|
||||
|
||||
return dbObject;
|
||||
|
||||
@@ -196,18 +196,6 @@ public class Update {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update using {@code $addToSet} modifier. <br/>
|
||||
* Allows creation of {@code $push} command for single or multiple (using {@code $each}) values
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
* @since 1.5
|
||||
*/
|
||||
public AddToSetBuilder addToSet(String key) {
|
||||
return new AddToSetBuilder(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update using the {@literal $addToSet} update modifier
|
||||
*
|
||||
@@ -420,7 +408,7 @@ public class Update {
|
||||
/**
|
||||
* Builder for creating {@code $push} modifiers
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Christop Strobl
|
||||
*/
|
||||
public class PushOperatorBuilder {
|
||||
|
||||
@@ -454,41 +442,4 @@ public class Update {
|
||||
return Update.this.push(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for creating {@code $addToSet} modifier.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 1.5
|
||||
*/
|
||||
public class AddToSetBuilder {
|
||||
|
||||
private final String key;
|
||||
|
||||
public AddToSetBuilder(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagates {@code $each} to {@code $addToSet}
|
||||
*
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public Update each(Object... values) {
|
||||
return Update.this.addToSet(this.key, new Each(values));
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagates {@link #value(Object)} to {@code $addToSet}
|
||||
*
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public Update value(Object value) {
|
||||
return Update.this.addToSet(this.key, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2013 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,7 +32,6 @@ import com.mongodb.gridfs.GridFSFile;
|
||||
* @author Oliver Gierke
|
||||
* @author Philipp Schneider
|
||||
* @author Thomas Darimont
|
||||
* @author Martin Baumgartner
|
||||
*/
|
||||
public interface GridFsOperations extends ResourcePatternResolver {
|
||||
|
||||
@@ -45,24 +44,6 @@ public interface GridFsOperations extends ResourcePatternResolver {
|
||||
*/
|
||||
GridFSFile store(InputStream content, String filename);
|
||||
|
||||
/**
|
||||
* Stores the given content into a file with the given name.
|
||||
*
|
||||
* @param content must not be {@literal null}.
|
||||
* @param metadata can be {@literal null}.
|
||||
* @return the {@link GridFSFile} just created
|
||||
*/
|
||||
GridFSFile store(InputStream content, Object metadata);
|
||||
|
||||
/**
|
||||
* Stores the given content into a file with the given name.
|
||||
*
|
||||
* @param content must not be {@literal null}.
|
||||
* @param metadata can be {@literal null}.
|
||||
* @return the {@link GridFSFile} just created
|
||||
*/
|
||||
GridFSFile store(InputStream content, DBObject metadata);
|
||||
|
||||
/**
|
||||
* Stores the given content into a file with the given name and content type.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2013 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.
|
||||
@@ -44,7 +44,6 @@ import com.mongodb.gridfs.GridFSInputFile;
|
||||
* @author Oliver Gierke
|
||||
* @author Philipp Schneider
|
||||
* @author Thomas Darimont
|
||||
* @author Martin Baumgartner
|
||||
*/
|
||||
public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver {
|
||||
|
||||
@@ -90,25 +89,6 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver
|
||||
return store(content, filename, (Object) null);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.Object)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public GridFSFile store(InputStream content, Object metadata) {
|
||||
return store(content, null, metadata);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, com.mongodb.DBObject)
|
||||
*/
|
||||
@Override
|
||||
public GridFSFile store(InputStream content, DBObject metadata) {
|
||||
return store(content, null, metadata);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, java.lang.String)
|
||||
@@ -122,6 +102,7 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver
|
||||
* @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, java.lang.Object)
|
||||
*/
|
||||
public GridFSFile store(InputStream content, String filename, Object metadata) {
|
||||
|
||||
return store(content, filename, null, metadata);
|
||||
}
|
||||
|
||||
@@ -156,12 +137,10 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver
|
||||
public GridFSFile store(InputStream content, String filename, String contentType, DBObject metadata) {
|
||||
|
||||
Assert.notNull(content);
|
||||
Assert.hasText(filename);
|
||||
|
||||
GridFSInputFile file = getGridFs().createFile(content);
|
||||
|
||||
if (filename != null) {
|
||||
file.setFilename(filename);
|
||||
}
|
||||
file.setFilename(filename);
|
||||
|
||||
if (metadata != null) {
|
||||
file.setMetaData(metadata);
|
||||
|
||||
@@ -1,28 +1,13 @@
|
||||
/*
|
||||
* Copyright 2011-2014 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.repository;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
|
||||
/**
|
||||
* Annotation to be used for disambiguing method parameters that shall be used to trigger geo near queries. By default
|
||||
@@ -35,4 +20,5 @@ import org.springframework.data.geo.Point;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.PARAMETER)
|
||||
public @interface Near {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2013 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.
|
||||
@@ -29,7 +29,6 @@ import org.springframework.data.annotation.QueryAnnotation;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@@ -60,12 +59,4 @@ public @interface Query {
|
||||
* @return
|
||||
*/
|
||||
boolean count() default false;
|
||||
|
||||
/**
|
||||
* Returns whether the query should delete matching documents.
|
||||
*
|
||||
* @since 1.5
|
||||
* @return
|
||||
*/
|
||||
boolean delete() default false;
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 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.repository.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandler;
|
||||
import org.springframework.data.mongodb.config.MongoNamespaceHandler;
|
||||
import org.springframework.data.repository.config.RepositoryBeanDefinitionParser;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
|
||||
/**
|
||||
* {@link NamespaceHandler} to register repository configuration.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoRepositoryConfigNamespaceHandler extends MongoNamespaceHandler {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.config.MongoNamespaceHandler#init()
|
||||
*/
|
||||
@Override
|
||||
public void init() {
|
||||
|
||||
RepositoryConfigurationExtension extension = new MongoRepositoryConfigurationExtension();
|
||||
RepositoryBeanDefinitionParser repositoryBeanDefinitionParser = new RepositoryBeanDefinitionParser(extension);
|
||||
|
||||
registerBeanDefinitionParser("repositories", repositoryBeanDefinitionParser);
|
||||
|
||||
super.init();
|
||||
}
|
||||
}
|
||||
@@ -15,19 +15,13 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.config;
|
||||
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.data.config.ParsingUtils;
|
||||
import org.springframework.data.mongodb.config.BeanNames;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationSource;
|
||||
import org.springframework.data.repository.config.XmlRepositoryConfigurationSource;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
@@ -41,8 +35,6 @@ public class MongoRepositoryConfigurationExtension extends RepositoryConfigurati
|
||||
private static final String MONGO_TEMPLATE_REF = "mongo-template-ref";
|
||||
private static final String CREATE_QUERY_INDEXES = "create-query-indexes";
|
||||
|
||||
private boolean fallbackMappingContextCreated = false;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModulePrefix()
|
||||
@@ -60,18 +52,6 @@ public class MongoRepositoryConfigurationExtension extends RepositoryConfigurati
|
||||
return MongoRepositoryFactoryBean.class.getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.RepositoryConfigurationSource)
|
||||
*/
|
||||
@Override
|
||||
public void postProcess(BeanDefinitionBuilder builder, RepositoryConfigurationSource source) {
|
||||
|
||||
if (fallbackMappingContextCreated) {
|
||||
builder.addPropertyReference("mappingContext", BeanNames.MAPPING_CONTEXT_BEAN_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.XmlRepositoryConfigurationSource)
|
||||
@@ -97,21 +77,4 @@ public class MongoRepositoryConfigurationExtension extends RepositoryConfigurati
|
||||
builder.addPropertyReference("mongoOperations", attributes.getString("mongoTemplateRef"));
|
||||
builder.addPropertyValue("createIndexesForQueryMethods", attributes.getBoolean("createIndexesForQueryMethods"));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#registerBeansForRoot(org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.data.repository.config.RepositoryConfigurationSource)
|
||||
*/
|
||||
@Override
|
||||
public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) {
|
||||
|
||||
if (!registry.containsBeanDefinition(BeanNames.MAPPING_CONTEXT_BEAN_NAME)) {
|
||||
|
||||
RootBeanDefinition definition = new RootBeanDefinition(MongoMappingContext.class);
|
||||
definition.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
definition.setSource(configurationSource.getSource());
|
||||
|
||||
registry.registerBeanDefinition(BeanNames.MAPPING_CONTEXT_BEAN_NAME, definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,15 +20,13 @@ import java.util.List;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.domain.SliceImpl;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.GeoPage;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResult;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
@@ -36,14 +34,11 @@ import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.WriteResult;
|
||||
|
||||
/**
|
||||
* Base class for {@link RepositoryQuery} implementations for Mongo.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
|
||||
@@ -86,18 +81,14 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
|
||||
Object result = null;
|
||||
|
||||
if (isDeleteQuery()) {
|
||||
result = new DeleteExecution().execute(query);
|
||||
} else if (method.isGeoNearQuery() && method.isPageQuery()) {
|
||||
if (method.isGeoNearQuery() && method.isPageQuery()) {
|
||||
|
||||
MongoParameterAccessor countAccessor = new MongoParametersParameterAccessor(method, parameters);
|
||||
Query countQuery = createCountQuery(new ConvertingParameterAccessor(operations.getConverter(), countAccessor));
|
||||
|
||||
result = new GeoNearExecution(accessor).execute(query, countQuery);
|
||||
} else if (method.isGeoNearQuery()) {
|
||||
result = new GeoNearExecution(accessor).execute(query);
|
||||
} else if (method.isSliceQuery()) {
|
||||
result = new SlicedExecution(accessor.getPageable()).execute(query);
|
||||
return new GeoNearExecution(accessor).execute(query);
|
||||
} else if (method.isCollectionQuery()) {
|
||||
result = new CollectionExecution(accessor.getPageable()).execute(query);
|
||||
} else if (method.isPageQuery()) {
|
||||
@@ -146,14 +137,6 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
*/
|
||||
protected abstract boolean isCountQuery();
|
||||
|
||||
/**
|
||||
* Return weather the query should delete matching documents.
|
||||
*
|
||||
* @return
|
||||
* @since 1.5
|
||||
*/
|
||||
protected abstract boolean isDeleteQuery();
|
||||
|
||||
private abstract class Execution {
|
||||
|
||||
abstract Object execute(Query query);
|
||||
@@ -190,41 +173,6 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Execution} for {@link Slice} query methods.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
|
||||
final class SlicedExecution extends Execution {
|
||||
|
||||
private final Pageable pageable;
|
||||
|
||||
SlicedExecution(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
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
Object execute(Query query) {
|
||||
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
int pageSize = pageable.getPageSize();
|
||||
Pageable slicePageable = new PageRequest(pageable.getPageNumber(), pageSize + 1, pageable.getSort());
|
||||
|
||||
List result = operations.find(query.with(slicePageable), metadata.getJavaType(), metadata.getCollectionName());
|
||||
|
||||
boolean hasNext = result.size() > pageSize;
|
||||
|
||||
return new SliceImpl<Object>(hasNext ? result.subList(0, pageSize) : result, pageable, hasNext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Execution} for pagination queries.
|
||||
*
|
||||
@@ -293,7 +241,6 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
final class GeoNearExecution extends Execution {
|
||||
|
||||
private final MongoParameterAccessor accessor;
|
||||
@@ -325,12 +272,11 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
long count = operations.count(countQuery, metadata.getCollectionName());
|
||||
|
||||
return new org.springframework.data.mongodb.core.geo.GeoPage<Object>(doExecuteQuery(query),
|
||||
accessor.getPageable(), count);
|
||||
return new GeoPage<Object>(doExecuteQuery(query), accessor.getPageable(), count);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private org.springframework.data.mongodb.core.geo.GeoResults<Object> doExecuteQuery(Query query) {
|
||||
private GeoResults<Object> doExecuteQuery(Query query) {
|
||||
|
||||
Point nearLocation = accessor.getGeoNearLocation();
|
||||
NearQuery nearQuery = NearQuery.near(nearLocation);
|
||||
@@ -350,8 +296,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
}
|
||||
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
return (org.springframework.data.mongodb.core.geo.GeoResults<Object>) operations.geoNear(nearQuery,
|
||||
metadata.getJavaType(), metadata.getCollectionName());
|
||||
return (GeoResults<Object>) operations.geoNear(nearQuery, metadata.getJavaType(), metadata.getCollectionName());
|
||||
}
|
||||
|
||||
private boolean isListOfGeoResult() {
|
||||
@@ -366,33 +311,4 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
return componentType == null ? false : GeoResult.class.equals(componentType.getType());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Execution} removing documents matching the query.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
final class DeleteExecution extends Execution {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.query.Query)
|
||||
*/
|
||||
@Override
|
||||
Object execute(Query query) {
|
||||
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
return deleteAndConvertResult(query, metadata);
|
||||
}
|
||||
|
||||
private Object deleteAndConvertResult(Query query, MongoEntityMetadata<?> metadata) {
|
||||
|
||||
if (method.isCollectionQuery()) {
|
||||
return operations.findAllAndRemove(query, metadata.getJavaType());
|
||||
}
|
||||
|
||||
WriteResult writeResult = operations.remove(query, metadata.getCollectionName());
|
||||
return writeResult != null ? writeResult.getN() : 0L;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.core.convert.MongoWriter;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,8 +20,8 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.mongodb.repository.Near;
|
||||
import org.springframework.data.mongodb.repository.query.MongoParameters.MongoParameter;
|
||||
import org.springframework.data.repository.query.Parameter;
|
||||
@@ -64,11 +64,10 @@ public class MongoParameters extends Parameters<MongoParameters, MongoParameter>
|
||||
this.nearIndex = nearIndex;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "deprecation" })
|
||||
@SuppressWarnings("unchecked")
|
||||
private final int getNearIndex(List<Class<?>> parameterTypes) {
|
||||
|
||||
for (Class<?> reference : Arrays.asList(Point.class, org.springframework.data.mongodb.core.geo.Point.class,
|
||||
double[].class)) {
|
||||
for (Class<?> reference : Arrays.asList(Point.class, double[].class)) {
|
||||
|
||||
int nearIndex = parameterTypes.indexOf(reference);
|
||||
|
||||
@@ -162,7 +161,7 @@ public class MongoParameters extends Parameters<MongoParameters, MongoParameter>
|
||||
*/
|
||||
@Override
|
||||
public boolean isSpecialParameter() {
|
||||
return super.isSpecialParameter() || Distance.class.isAssignableFrom(getType()) || isNearParameter();
|
||||
return super.isSpecialParameter() || getType().equals(Distance.class) || isNearParameter();
|
||||
}
|
||||
|
||||
private boolean isNearParameter() {
|
||||
@@ -175,7 +174,7 @@ public class MongoParameters extends Parameters<MongoParameters, MongoParameter>
|
||||
}
|
||||
|
||||
private boolean isPoint() {
|
||||
return Point.class.isAssignableFrom(getType()) || getType().equals(double[].class);
|
||||
return getType().equals(Point.class) || getType().equals(double[].class);
|
||||
}
|
||||
|
||||
private boolean hasNearAnnotation() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,11 +24,11 @@ import java.util.Iterator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Shape;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.context.PersistentPropertyPath;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
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;
|
||||
|
||||
@@ -15,16 +15,15 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.data.geo.GeoPage;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.geo.GeoPage;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResult;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
@@ -42,8 +41,8 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class MongoQueryMethod extends QueryMethod {
|
||||
|
||||
@SuppressWarnings("unchecked") private static final List<Class<? extends Serializable>> GEO_NEAR_RESULTS = Arrays
|
||||
.asList(GeoResult.class, GeoResults.class, GeoPage.class);
|
||||
@SuppressWarnings("unchecked") private static final List<Class<?>> GEO_NEAR_RESULTS = Arrays.asList(GeoResult.class,
|
||||
GeoResults.class, GeoPage.class);
|
||||
|
||||
private final Method method;
|
||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
@@ -153,15 +152,11 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
|
||||
private boolean isGeoNearQuery(Method method) {
|
||||
|
||||
Class<?> returnType = method.getReturnType();
|
||||
|
||||
for (Class<?> type : GEO_NEAR_RESULTS) {
|
||||
if (type.isAssignableFrom(returnType)) {
|
||||
return true;
|
||||
}
|
||||
if (GEO_NEAR_RESULTS.contains(method.getReturnType())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Iterable.class.isAssignableFrom(returnType)) {
|
||||
if (Iterable.class.isAssignableFrom(method.getReturnType())) {
|
||||
TypeInformation<?> from = ClassTypeInformation.fromReturnTypeOf(method);
|
||||
return GeoResult.class.equals(from.getComponentType().getType());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -19,16 +19,19 @@ import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.util.JSONParseException;
|
||||
|
||||
/**
|
||||
* {@link RepositoryQuery} implementation for Mongo.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class PartTreeMongoQuery extends AbstractMongoQuery {
|
||||
|
||||
@@ -67,7 +70,24 @@ public class PartTreeMongoQuery extends AbstractMongoQuery {
|
||||
protected Query createQuery(ConvertingParameterAccessor accessor) {
|
||||
|
||||
MongoQueryCreator creator = new MongoQueryCreator(tree, accessor, context, isGeoNearQuery);
|
||||
return creator.createQuery();
|
||||
Query query = creator.createQuery();
|
||||
|
||||
String fieldSpec = this.getQueryMethod().getFieldSpecification();
|
||||
|
||||
if (!StringUtils.hasText(fieldSpec)) {
|
||||
return query;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
BasicQuery result = new BasicQuery(query.getQueryObject().toString(), fieldSpec);
|
||||
result.setSortObject(query.getSortObject());
|
||||
return result;
|
||||
|
||||
} catch (JSONParseException o_O) {
|
||||
throw new IllegalStateException(String.format("Invalid query or field specification in %s!", getQueryMethod(),
|
||||
o_O));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -87,13 +107,4 @@ public class PartTreeMongoQuery extends AbstractMongoQuery {
|
||||
protected boolean isCountQuery() {
|
||||
return tree.isCountProjection();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery#isDeleteQuery()
|
||||
*/
|
||||
@Override
|
||||
protected boolean isDeleteQuery() {
|
||||
return tree.isDelete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2013 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.
|
||||
@@ -30,32 +30,18 @@ import com.mongodb.util.JSON;
|
||||
* Query to use a plain JSON String to create the {@link Query} to actually execute.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
|
||||
private static final String COUND_AND_DELETE = "Manually defined query for %s cannot be both a count and delete query at the same time!";
|
||||
private static final Pattern PLACEHOLDER = Pattern.compile("\\?(\\d+)");
|
||||
private static final Logger LOG = LoggerFactory.getLogger(StringBasedMongoQuery.class);
|
||||
|
||||
private final String query;
|
||||
private final String fieldSpec;
|
||||
private final boolean isCountQuery;
|
||||
private final boolean isDeleteQuery;
|
||||
|
||||
/**
|
||||
* Creates a new {@link StringBasedMongoQuery} for the given {@link MongoQueryMethod} and {@link MongoOperations}.
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param mongoOperations must not be {@literal null}.
|
||||
*/
|
||||
public StringBasedMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations) {
|
||||
this(method.getAnnotatedQuery(), method, mongoOperations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link StringBasedMongoQuery} for the given {@link String}, {@link MongoQueryMethod} and
|
||||
* {@link MongoOperations}.
|
||||
* Creates a new {@link StringBasedMongoQuery}.
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param template must not be {@literal null}.
|
||||
@@ -67,11 +53,10 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
this.query = query;
|
||||
this.fieldSpec = method.getFieldSpecification();
|
||||
this.isCountQuery = method.hasAnnotatedQuery() ? method.getQueryAnnotation().count() : false;
|
||||
this.isDeleteQuery = method.hasAnnotatedQuery() ? method.getQueryAnnotation().delete() : false;
|
||||
}
|
||||
|
||||
if (isCountQuery && isDeleteQuery) {
|
||||
throw new IllegalArgumentException(String.format(COUND_AND_DELETE, method));
|
||||
}
|
||||
public StringBasedMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations) {
|
||||
this(method.getAnnotatedQuery(), method, mongoOperations);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -110,15 +95,6 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
return isCountQuery;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery#isDeleteQuery()
|
||||
*/
|
||||
@Override
|
||||
protected boolean isDeleteQuery() {
|
||||
return this.isDeleteQuery;
|
||||
}
|
||||
|
||||
private String replacePlaceholders(String input, ConvertingParameterAccessor accessor) {
|
||||
|
||||
Matcher matcher = PLACEHOLDER.matcher(input);
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.data.mongodb.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.repository.Repository;
|
||||
@@ -35,7 +34,6 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
|
||||
|
||||
private MongoOperations operations;
|
||||
private boolean createIndexesForQueryMethods = false;
|
||||
private boolean mappingContextConfigured = false;
|
||||
|
||||
/**
|
||||
* Configures the {@link MongoOperations} to be used.
|
||||
@@ -44,6 +42,7 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
|
||||
*/
|
||||
public void setMongoOperations(MongoOperations operations) {
|
||||
this.operations = operations;
|
||||
setMappingContext(operations.getConverter().getMappingContext());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,17 +54,6 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
|
||||
this.createIndexesForQueryMethods = createIndexesForQueryMethods;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#setMappingContext(org.springframework.data.mapping.context.MappingContext)
|
||||
*/
|
||||
@Override
|
||||
protected void setMappingContext(MappingContext<?, ?> mappingContext) {
|
||||
|
||||
super.setMappingContext(mappingContext);
|
||||
this.mappingContextConfigured = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -107,9 +95,5 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
|
||||
|
||||
super.afterPropertiesSet();
|
||||
Assert.notNull(operations, "MongoTemplate must not be null!");
|
||||
|
||||
if (!mappingContextConfigured) {
|
||||
setMappingContext(operations.getConverter().getMappingContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
http\://www.springframework.org/schema/data/mongo=org.springframework.data.mongodb.repository.config.MongoRepositoryConfigNamespaceHandler
|
||||
http\://www.springframework.org/schema/data/mongo=org.springframework.data.mongodb.config.MongoNamespaceHandler
|
||||
|
||||
@@ -34,9 +34,6 @@ import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
|
||||
*/
|
||||
public class AuditingIntegrationTests {
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-577, DATAMONGO-800, DATAMONGO-883
|
||||
*/
|
||||
@Test
|
||||
public void enablesAuditingAndSetsPropertiesAccordingly() throws Exception {
|
||||
|
||||
@@ -61,13 +58,8 @@ public class AuditingIntegrationTests {
|
||||
|
||||
class Entity {
|
||||
|
||||
@Id Long id;
|
||||
@CreatedDate DateTime created;
|
||||
DateTime modified;
|
||||
|
||||
@LastModifiedDate
|
||||
public DateTime getModified() {
|
||||
return modified;
|
||||
}
|
||||
@LastModifiedDate DateTime modified;
|
||||
@Id Long id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* Copyright 2013 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.
|
||||
@@ -19,8 +19,6 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -30,15 +28,16 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.data.mongodb.core.AuditablePerson;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
/**
|
||||
@@ -58,16 +57,16 @@ public class AuditingViaJavaConfigRepositoriesTests {
|
||||
@Configuration
|
||||
@EnableMongoAuditing(auditorAwareRef = "auditorProvider")
|
||||
@EnableMongoRepositories(basePackageClasses = AuditablePersonRepository.class, considerNestedRepositories = true)
|
||||
static class Config extends AbstractMongoConfiguration {
|
||||
static class Config {
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
return "database";
|
||||
@Bean
|
||||
public MongoOperations mongoTemplate() throws Exception {
|
||||
return new MongoTemplate(new SimpleMongoDbFactory(new MongoClient(), "database"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mongo mongo() throws Exception {
|
||||
return new MongoClient();
|
||||
@Bean
|
||||
public MongoMappingContext mappingContext() {
|
||||
return new MongoMappingContext();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -83,21 +82,19 @@ public class AuditingViaJavaConfigRepositoriesTests {
|
||||
this.auditor = auditablePersonRepository.save(new AuditablePerson("auditor"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-792, DATAMONGO-883
|
||||
*/
|
||||
@Test
|
||||
public void basicAuditing() {
|
||||
|
||||
doReturn(this.auditor).when(this.auditorAware).getCurrentAuditor();
|
||||
|
||||
AuditablePerson savedUser = auditablePersonRepository.save(new AuditablePerson("user"));
|
||||
AuditablePerson user = new AuditablePerson("user");
|
||||
|
||||
AuditablePerson savedUser = auditablePersonRepository.save(user);
|
||||
System.out.println(savedUser);
|
||||
|
||||
AuditablePerson createdBy = savedUser.getCreatedBy();
|
||||
|
||||
assertThat(createdBy, is(notNullValue()));
|
||||
assertThat(createdBy.getFirstname(), is(this.auditor.getFirstname()));
|
||||
assertThat(savedUser.getCreatedAt(), is(notNullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,40 +102,16 @@ public class AuditingViaJavaConfigRepositoriesTests {
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
public void auditingUsesFallbackMappingContextIfNoneConfiguredWithRepositories() {
|
||||
new AnnotationConfigApplicationContext(SimpleConfigWithRepositories.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-843
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
public void auditingUsesFallbackMappingContextIfNoneConfigured() {
|
||||
new AnnotationConfigApplicationContext(SimpleConfig.class);
|
||||
public void defaultsMappingContextIfNoneConfigured() {
|
||||
new AnnotationConfigApplicationContext(SampleConfig.class);
|
||||
}
|
||||
|
||||
@Repository
|
||||
static interface AuditablePersonRepository extends MongoRepository<AuditablePerson, String> {}
|
||||
|
||||
@Configuration
|
||||
@EnableMongoRepositories
|
||||
@EnableMongoAuditing
|
||||
static class SimpleConfigWithRepositories {
|
||||
static class SampleConfig {
|
||||
|
||||
@Bean
|
||||
public MongoTemplate mongoTemplate() throws UnknownHostException {
|
||||
return new MongoTemplate(new SimpleMongoDbFactory(new MongoClient(), "database"));
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableMongoAuditing
|
||||
static class SimpleConfig {
|
||||
|
||||
@Bean
|
||||
public MongoTemplate mongoTemplate() throws UnknownHostException {
|
||||
return new MongoTemplate(new SimpleMongoDbFactory(new MongoClient(), "database"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2013 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.
|
||||
@@ -21,9 +21,11 @@ import static org.junit.Assert.*;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
@@ -45,17 +47,13 @@ import com.mongodb.DBObject;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class MappingMongoConverterParserIntegrationTests {
|
||||
|
||||
DefaultListableBeanFactory factory;
|
||||
@Rule public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
factory = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/converter.xml"));
|
||||
}
|
||||
DefaultListableBeanFactory factory;
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-243
|
||||
@@ -63,6 +61,7 @@ public class MappingMongoConverterParserIntegrationTests {
|
||||
@Test
|
||||
public void allowsDbFactoryRefAttribute() {
|
||||
|
||||
loadValidConfiguration();
|
||||
factory.getBeanDefinition("converter");
|
||||
factory.getBean("converter");
|
||||
}
|
||||
@@ -73,6 +72,7 @@ public class MappingMongoConverterParserIntegrationTests {
|
||||
@Test
|
||||
public void hasCustomTypeMapper() {
|
||||
|
||||
loadValidConfiguration();
|
||||
MappingMongoConverter converter = factory.getBean("converter", MappingMongoConverter.class);
|
||||
MongoTypeMapper customMongoTypeMapper = factory.getBean(CustomMongoTypeMapper.class);
|
||||
|
||||
@@ -85,6 +85,7 @@ public class MappingMongoConverterParserIntegrationTests {
|
||||
@Test
|
||||
public void scansForConverterAndSetsUpCustomConversionsAccordingly() {
|
||||
|
||||
loadValidConfiguration();
|
||||
CustomConversions conversions = factory.getBean(CustomConversions.class);
|
||||
assertThat(conversions.hasCustomWriteTarget(Person.class), is(true));
|
||||
assertThat(conversions.hasCustomWriteTarget(Account.class), is(true));
|
||||
@@ -96,7 +97,8 @@ public class MappingMongoConverterParserIntegrationTests {
|
||||
@Test
|
||||
public void activatesAbbreviatingPropertiesCorrectly() {
|
||||
|
||||
BeanDefinition definition = factory.getBeanDefinition("abbreviatingConverter.mongoMappingContext");
|
||||
loadValidConfiguration();
|
||||
BeanDefinition definition = factory.getBeanDefinition("abbreviatingConverter.mappingContext");
|
||||
Object value = definition.getPropertyValues().getPropertyValue("fieldNamingStrategy").getValue();
|
||||
|
||||
assertThat(value, is(instanceOf(BeanDefinition.class)));
|
||||
@@ -104,6 +106,32 @@ public class MappingMongoConverterParserIntegrationTests {
|
||||
assertThat(strategy.getBeanClassName(), is(CamelCaseAbbreviatingFieldNamingStrategy.class.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-892
|
||||
*/
|
||||
@Test
|
||||
public void shouldThrowBeanDefinitionParsingExceptionIfConverterDefinedAsNestedBean() {
|
||||
|
||||
exception.expect(BeanDefinitionParsingException.class);
|
||||
exception.expectMessage("Mongo Converter must not be defined as nested bean.");
|
||||
|
||||
loadNestedBeanConfiguration();
|
||||
}
|
||||
|
||||
private void loadValidConfiguration() {
|
||||
this.loadConfiguration("namespace/converter.xml");
|
||||
}
|
||||
|
||||
private void loadNestedBeanConfiguration() {
|
||||
this.loadConfiguration("namespace/converter-nested-bean-definition.xml");
|
||||
}
|
||||
|
||||
private void loadConfiguration(String configLocation) {
|
||||
factory = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
|
||||
reader.loadBeanDefinitions(new ClassPathResource(configLocation));
|
||||
}
|
||||
|
||||
@Component
|
||||
public static class SampleConverter implements Converter<Person, DBObject> {
|
||||
public DBObject convert(Person source) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
* Copyright 2012-2013 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.
|
||||
@@ -34,7 +34,6 @@ import org.springframework.core.io.ClassPathResource;
|
||||
* @see DATAMONGO-36
|
||||
* @author Maciej Walkowiak
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingMongoConverterParserValidationIntegrationTests {
|
||||
|
||||
@@ -47,43 +46,31 @@ public class MappingMongoConverterParserValidationIntegrationTests {
|
||||
reader = new XmlBeanDefinitionReader(factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-36
|
||||
*/
|
||||
@Test
|
||||
public void validatingEventListenerCreatedWithDefaultConfig() {
|
||||
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-default.xml"));
|
||||
assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER_BEAN_NAME), is(not(nullValue())));
|
||||
assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER), is(not(nullValue())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-36
|
||||
*/
|
||||
@Test
|
||||
public void validatingEventListenerCreatedWhenValidationEnabled() {
|
||||
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-validation-enabled.xml"));
|
||||
assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER_BEAN_NAME), is(not(nullValue())));
|
||||
assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER), is(not(nullValue())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-36
|
||||
*/
|
||||
@Test(expected = NoSuchBeanDefinitionException.class)
|
||||
public void validatingEventListenersIsNotCreatedWhenDisabled() {
|
||||
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-validation-disabled.xml"));
|
||||
factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER_BEAN_NAME);
|
||||
factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-36
|
||||
*/
|
||||
@Test
|
||||
public void validatingEventListenerCreatedWithCustomTypeMapperConfig() {
|
||||
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-custom-typeMapper.xml"));
|
||||
assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER_BEAN_NAME), is(not(nullValue())));
|
||||
assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER), is(not(nullValue())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
|
||||
@@ -29,10 +26,9 @@ import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
*/
|
||||
public class AuditablePerson {
|
||||
|
||||
private @Id String id;
|
||||
@Id private String id;
|
||||
private String firstname;
|
||||
private @DBRef @CreatedBy AuditablePerson createdBy;
|
||||
private @CreatedDate Date createdAt;
|
||||
@DBRef @CreatedBy private AuditablePerson createdBy;
|
||||
|
||||
public AuditablePerson() {}
|
||||
|
||||
@@ -63,8 +59,4 @@ public class AuditablePerson {
|
||||
public void setCreatedBy(AuditablePerson createdBy) {
|
||||
this.createdBy = createdBy;
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2013 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,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
@@ -26,11 +27,11 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.convert.AbstractMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoTypeMapper;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
|
||||
@@ -34,7 +34,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -187,6 +186,8 @@ public class MongoTemplateTests {
|
||||
template.dropCollection(DocumentWithCollectionOfSimpleType.class);
|
||||
template.dropCollection(DocumentWithMultipleCollections.class);
|
||||
template.dropCollection(DocumentWithDBRefCollection.class);
|
||||
template.dropCollection(SomeContent.class);
|
||||
template.dropCollection(SomeTemplate.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -299,6 +300,9 @@ public class MongoTemplateTests {
|
||||
@Test
|
||||
public void rejectsDuplicateIdInInsertAll() {
|
||||
|
||||
thrown.expect(DataIntegrityViolationException.class);
|
||||
thrown.expectMessage("E11000 duplicate key error index: database.person.$_id_");
|
||||
|
||||
MongoTemplate template = new MongoTemplate(factory);
|
||||
template.setWriteResultChecking(WriteResultChecking.EXCEPTION);
|
||||
|
||||
@@ -310,15 +314,7 @@ public class MongoTemplateTests {
|
||||
records.add(person);
|
||||
records.add(person);
|
||||
|
||||
try {
|
||||
template.insertAll(records);
|
||||
fail("Expected DataIntegrityViolationException!");
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
assertThat(
|
||||
e.getMessage(),
|
||||
CoreMatchers
|
||||
.startsWith("Insert list failed: E11000 duplicate key error index: database.person.$_id_ dup key: { : ObjectId"));
|
||||
}
|
||||
template.insertAll(records);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2492,29 +2488,6 @@ public class MongoTemplateTests {
|
||||
assertThat(result.get(0).dbRefProperty.field, is(sample.field));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-566
|
||||
*/
|
||||
@Test
|
||||
public void testFindAllAndRemoveFullyReturnsAndRemovesDocuments() {
|
||||
|
||||
Sample spring = new Sample("100", "spring");
|
||||
Sample data = new Sample("200", "data");
|
||||
Sample mongodb = new Sample("300", "mongodb");
|
||||
template.insert(Arrays.asList(spring, data, mongodb), Sample.class);
|
||||
|
||||
Query qry = query(where("field").in("spring", "mongodb"));
|
||||
List<Sample> result = template.findAllAndRemove(qry, Sample.class);
|
||||
|
||||
assertThat(result, hasSize(2));
|
||||
|
||||
assertThat(
|
||||
template.getDb().getCollection("sample")
|
||||
.find(new BasicDBObject("field", new BasicDBObject("$in", Arrays.asList("spring", "mongodb")))).count(),
|
||||
is(0));
|
||||
assertThat(template.getDb().getCollection("sample").find(new BasicDBObject("field", "data")).count(), is(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-880
|
||||
*/
|
||||
@@ -2581,22 +2554,148 @@ public class MongoTemplateTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-471
|
||||
* @see DATAMONGO-888
|
||||
*/
|
||||
@Test
|
||||
public void updateMultiShouldAddValuesCorrectlyWhenUsingAddToSetWithEach() {
|
||||
public void sortOnIdFieldPropertyShouldBeMappedCorrectly() {
|
||||
|
||||
DocumentWithCollectionOfSimpleType document = new DocumentWithCollectionOfSimpleType();
|
||||
document.values = Arrays.asList("spring");
|
||||
template.save(document);
|
||||
DoucmentWithNamedIdField one = new DoucmentWithNamedIdField();
|
||||
one.someIdKey = "1";
|
||||
one.value = "a";
|
||||
|
||||
Query query = query(where("id").is(document.id));
|
||||
assumeThat(template.findOne(query, DocumentWithCollectionOfSimpleType.class).values, hasSize(1));
|
||||
DoucmentWithNamedIdField two = new DoucmentWithNamedIdField();
|
||||
two.someIdKey = "2";
|
||||
two.value = "b";
|
||||
|
||||
Update update = new Update().addToSet("values").each("data", "mongodb");
|
||||
template.updateMulti(query, update, DocumentWithCollectionOfSimpleType.class);
|
||||
template.save(one);
|
||||
template.save(two);
|
||||
|
||||
Query query = query(where("_id").in("1", "2")).with(new Sort(Direction.DESC, "someIdKey"));
|
||||
assertThat(template.find(query, DoucmentWithNamedIdField.class), contains(two, one));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-888
|
||||
*/
|
||||
@Test
|
||||
public void sortOnAnnotatedFieldPropertyShouldBeMappedCorrectly() {
|
||||
|
||||
DoucmentWithNamedIdField one = new DoucmentWithNamedIdField();
|
||||
one.someIdKey = "1";
|
||||
one.value = "a";
|
||||
|
||||
DoucmentWithNamedIdField two = new DoucmentWithNamedIdField();
|
||||
two.someIdKey = "2";
|
||||
two.value = "b";
|
||||
|
||||
template.save(one);
|
||||
template.save(two);
|
||||
|
||||
Query query = query(where("_id").in("1", "2")).with(new Sort(Direction.DESC, "value"));
|
||||
assertThat(template.find(query, DoucmentWithNamedIdField.class), contains(two, one));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-913
|
||||
*/
|
||||
@Test
|
||||
public void shouldRetrieveInitializedValueFromDbRefAssociationAfterLoad() {
|
||||
|
||||
SomeContent content = new SomeContent();
|
||||
content.id = "content-1";
|
||||
content.name = "Content 1";
|
||||
content.text = "Some text";
|
||||
|
||||
template.save(content);
|
||||
|
||||
SomeTemplate tmpl = new SomeTemplate();
|
||||
tmpl.id = "template-1";
|
||||
tmpl.content = content;
|
||||
|
||||
template.save(tmpl);
|
||||
|
||||
SomeTemplate result = template.findOne(query(where("content").is(tmpl.getContent())), SomeTemplate.class);
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertThat(result.getContent(), is(notNullValue()));
|
||||
assertThat(result.getContent().getId(), is(notNullValue()));
|
||||
assertThat(result.getContent().getName(), is(notNullValue()));
|
||||
assertThat(result.getContent().getText(), is(content.getText()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-913
|
||||
*/
|
||||
@Test
|
||||
public void shouldReuseExistingDBRefInQueryFromDbRefAssociationAfterLoad() {
|
||||
|
||||
SomeContent content = new SomeContent();
|
||||
content.id = "content-1";
|
||||
content.name = "Content 1";
|
||||
content.text = "Some text";
|
||||
|
||||
template.save(content);
|
||||
|
||||
SomeTemplate tmpl = new SomeTemplate();
|
||||
tmpl.id = "template-1";
|
||||
tmpl.content = content;
|
||||
|
||||
template.save(tmpl);
|
||||
|
||||
SomeTemplate result = template.findOne(query(where("content").is(tmpl.getContent())), SomeTemplate.class);
|
||||
|
||||
// Use lazy-loading-proxy in query
|
||||
result = template.findOne(query(where("content").is(result.getContent())), SomeTemplate.class);
|
||||
|
||||
assertNotNull(result.getContent().getName());
|
||||
assertThat(result.getContent().getName(), is(content.getName()));
|
||||
}
|
||||
|
||||
static class DoucmentWithNamedIdField {
|
||||
|
||||
@Id String someIdKey;
|
||||
|
||||
@Field(value = "val")//
|
||||
String value;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (someIdKey == null ? 0 : someIdKey.hashCode());
|
||||
result = prime * result + (value == null ? 0 : value.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof DoucmentWithNamedIdField)) {
|
||||
return false;
|
||||
}
|
||||
DoucmentWithNamedIdField other = (DoucmentWithNamedIdField) obj;
|
||||
if (someIdKey == null) {
|
||||
if (other.someIdKey != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!someIdKey.equals(other.someIdKey)) {
|
||||
return false;
|
||||
}
|
||||
if (value == null) {
|
||||
if (other.value != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!value.equals(other.value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
assertThat(template.findOne(query, DocumentWithCollectionOfSimpleType.class).values, hasSize(3));
|
||||
}
|
||||
|
||||
static class DocumentWithDBRefCollection {
|
||||
@@ -2793,6 +2892,15 @@ public class MongoTemplateTests {
|
||||
|
||||
String id;
|
||||
String text;
|
||||
String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
|
||||
@@ -49,12 +50,13 @@ import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.BasicDBObjectBuilder;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
@@ -89,10 +91,6 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
when(factory.getDb()).thenReturn(db);
|
||||
when(factory.getExceptionTranslator()).thenReturn(exceptionTranslator);
|
||||
when(db.getCollection(Mockito.any(String.class))).thenReturn(collection);
|
||||
when(collection.find(Mockito.any(DBObject.class))).thenReturn(cursor);
|
||||
when(cursor.limit(anyInt())).thenReturn(cursor);
|
||||
when(cursor.sort(Mockito.any(DBObject.class))).thenReturn(cursor);
|
||||
when(cursor.hint(anyString())).thenReturn(cursor);
|
||||
|
||||
this.mappingContext = new MongoMappingContext();
|
||||
this.converter = new MappingMongoConverter(new DefaultDbRefResolver(factory), mappingContext);
|
||||
@@ -235,7 +233,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
org.mockito.Matchers.isNull(DBObject.class), org.mockito.Matchers.isNull(DBObject.class), eq(false),
|
||||
captor.capture(), eq(false), eq(false));
|
||||
|
||||
Assert.assertThat(captor.getValue().get("$inc"), Is.<Object> is(new BasicDBObject("version", 1)));
|
||||
Assert.assertThat(captor.getValue().get("$inc"), Is.<Object> is(new BasicDBObject("version", 1L)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,44 +287,25 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-566
|
||||
* @see DATAMONGO-948
|
||||
*/
|
||||
@Test
|
||||
public void findAllAndRemoveShouldRetrieveMatchingDocumentsPriorToRemoval() {
|
||||
public void sortShouldBeTakenAsIsWhenExecutingQueryWithoutSpecificTypeInformation() {
|
||||
|
||||
BasicQuery query = new BasicQuery("{'foo':'bar'}");
|
||||
template.findAllAndRemove(query, VersionedEntity.class);
|
||||
verify(collection, times(1)).find(Matchers.eq(query.getQueryObject()));
|
||||
}
|
||||
when(db.getCollection(Mockito.any(String.class))).thenReturn(collection);
|
||||
when(collection.find(Mockito.any(DBObject.class))).thenReturn(cursor);
|
||||
when(cursor.sort(Mockito.any(DBObject.class))).thenReturn(cursor);
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-566
|
||||
*/
|
||||
@Test
|
||||
public void findAllAndRemoveShouldRemoveDocumentsReturedByFindQuery() {
|
||||
Query query = Query.query(Criteria.where("foo").is("bar")).with(new Sort("foo"));
|
||||
template.executeQuery(query, "collection1", new DocumentCallbackHandler() {
|
||||
|
||||
Mockito.when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
|
||||
Mockito.when(cursor.next()).thenReturn(new BasicDBObject("_id", Integer.valueOf(0)))
|
||||
.thenReturn(new BasicDBObject("_id", Integer.valueOf(1)));
|
||||
@Override
|
||||
public void processDocument(DBObject dbObject) {}
|
||||
});
|
||||
|
||||
ArgumentCaptor<DBObject> queryCaptor = ArgumentCaptor.forClass(DBObject.class);
|
||||
BasicQuery query = new BasicQuery("{'foo':'bar'}");
|
||||
template.findAllAndRemove(query, VersionedEntity.class);
|
||||
|
||||
verify(collection, times(1)).remove(queryCaptor.capture());
|
||||
|
||||
DBObject idField = DBObjectTestUtils.getAsDBObject(queryCaptor.getValue(), "_id");
|
||||
assertThat((Object[]) idField.get("$in"), is(new Object[] { Integer.valueOf(0), Integer.valueOf(1) }));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-566
|
||||
*/
|
||||
@Test
|
||||
public void findAllAndRemoveShouldNotTriggerRemoveIfFindResultIsEmpty() {
|
||||
|
||||
template.findAllAndRemove(new BasicQuery("{'foo':'bar'}"), VersionedEntity.class);
|
||||
verify(collection, never()).remove(Mockito.any(DBObject.class));
|
||||
ArgumentCaptor<DBObject> captor = ArgumentCaptor.forClass(DBObject.class);
|
||||
verify(cursor, times(1)).sort(captor.capture());
|
||||
assertThat(captor.getValue(), equalTo(new BasicDBObjectBuilder().add("foo", 1).get()));
|
||||
}
|
||||
|
||||
class AutogenerateableId {
|
||||
|
||||
@@ -23,7 +23,8 @@ public class PersonWithVersionPropertyOfTypeLong {
|
||||
String firstName;
|
||||
int age;
|
||||
|
||||
@Version Long version;
|
||||
@Version
|
||||
Long version;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -33,14 +33,13 @@ import com.mongodb.DBCursor;
|
||||
* Unit tests for {@link QueryCursorPreparer}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class QueryCursorPreparerUnitTests {
|
||||
|
||||
@Mock
|
||||
MongoDbFactory factory;
|
||||
@Mock
|
||||
DBCursor cursor;
|
||||
@Mock MongoDbFactory factory;
|
||||
@Mock DBCursor cursor;
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-185
|
||||
@@ -50,7 +49,7 @@ public class QueryCursorPreparerUnitTests {
|
||||
|
||||
Query query = query(where("foo").is("bar")).withHint("hint");
|
||||
|
||||
CursorPreparer preparer = new MongoTemplate(factory).new QueryCursorPreparer(query);
|
||||
CursorPreparer preparer = new MongoTemplate(factory).new QueryCursorPreparer(query, null);
|
||||
preparer.prepare(cursor);
|
||||
|
||||
verify(cursor).hint("hint");
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationTests.CarDescriptor.Entry;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.util.Version;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -822,6 +823,40 @@ public class AggregationTests {
|
||||
assertThat(invoice.getTotalAmount(), is(closeTo(9.877, 000001)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-924
|
||||
*/
|
||||
@Test
|
||||
public void shouldAllowGroupingByAliasedFieldDefinedInFormerAggregationStage() {
|
||||
|
||||
mongoTemplate.dropCollection(CarPerson.class);
|
||||
|
||||
CarPerson person1 = new CarPerson("first1", "last1", new CarDescriptor.Entry("MAKE1", "MODEL1", 2000),
|
||||
new CarDescriptor.Entry("MAKE1", "MODEL2", 2001), new CarDescriptor.Entry("MAKE2", "MODEL3", 2010),
|
||||
new CarDescriptor.Entry("MAKE3", "MODEL4", 2014));
|
||||
|
||||
CarPerson person2 = new CarPerson("first2", "last2", new CarDescriptor.Entry("MAKE3", "MODEL4", 2014));
|
||||
|
||||
CarPerson person3 = new CarPerson("first3", "last3", new CarDescriptor.Entry("MAKE2", "MODEL5", 2011));
|
||||
|
||||
mongoTemplate.save(person1);
|
||||
mongoTemplate.save(person2);
|
||||
mongoTemplate.save(person3);
|
||||
|
||||
TypedAggregation<CarPerson> agg = Aggregation.newAggregation(CarPerson.class,
|
||||
unwind("descriptors.carDescriptor.entries"), //
|
||||
project() //
|
||||
.and("descriptors.carDescriptor.entries.make").as("make") //
|
||||
.and("descriptors.carDescriptor.entries.model").as("model") //
|
||||
.and("firstName").as("firstName") //
|
||||
.and("lastName").as("lastName"), //
|
||||
group("make"));
|
||||
|
||||
AggregationResults<DBObject> result = mongoTemplate.aggregate(agg, DBObject.class);
|
||||
|
||||
assertThat(result.getMappedResults(), hasSize(3));
|
||||
}
|
||||
|
||||
private void assertLikeStats(LikeStats like, String id, long count) {
|
||||
|
||||
assertThat(like, is(notNullValue()));
|
||||
@@ -938,4 +973,52 @@ public class AggregationTests {
|
||||
this.createDate = createDate;
|
||||
}
|
||||
}
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.Document
|
||||
static class CarPerson {
|
||||
|
||||
@Id private String id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private Descriptors descriptors;
|
||||
|
||||
public CarPerson(String firstname, String lastname, Entry... entries) {
|
||||
this.firstName = firstname;
|
||||
this.lastName = lastname;
|
||||
|
||||
this.descriptors = new Descriptors();
|
||||
|
||||
this.descriptors.carDescriptor = new CarDescriptor(entries);
|
||||
}
|
||||
}
|
||||
|
||||
static class Descriptors {
|
||||
private CarDescriptor carDescriptor;
|
||||
}
|
||||
|
||||
static class CarDescriptor {
|
||||
|
||||
private List<Entry> entries = new ArrayList<AggregationTests.CarDescriptor.Entry>();
|
||||
|
||||
public CarDescriptor(Entry... entries) {
|
||||
|
||||
for (Entry entry : entries) {
|
||||
this.entries.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
static class Entry {
|
||||
private String make;
|
||||
private String model;
|
||||
private int year;
|
||||
|
||||
public Entry() {}
|
||||
|
||||
public Entry(String make, String model, int year) {
|
||||
this.make = make;
|
||||
this.model = model;
|
||||
this.year = year;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,4 +179,49 @@ public class AggregationUnitTests {
|
||||
DBObject fields = getAsDBObject(secondProjection, "$group");
|
||||
assertThat(fields.get("foosum"), is((Object) new BasicDBObject("$sum", "$foo")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-908
|
||||
*/
|
||||
@Test
|
||||
public void shouldSupportReferingToNestedPropertiesInGroupOperation() {
|
||||
|
||||
DBObject agg = newAggregation( //
|
||||
project("cmsParameterId", "rules"), //
|
||||
unwind("rules"), //
|
||||
group("cmsParameterId", "rules.ruleType").count().as("totol") //
|
||||
).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(agg, is(notNullValue()));
|
||||
|
||||
DBObject group = ((List<DBObject>) agg.get("pipeline")).get(2);
|
||||
DBObject fields = getAsDBObject(group, "$group");
|
||||
DBObject id = getAsDBObject(fields, "_id");
|
||||
|
||||
assertThat(id.get("ruleType"), is((Object) "$rules.ruleType"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-924
|
||||
*/
|
||||
@Test
|
||||
public void referencingProjectionAliasesFromPreviousStepShouldReferToTheSameFieldTarget() {
|
||||
|
||||
DBObject agg = newAggregation( //
|
||||
project().and("foo.bar").as("ba") //
|
||||
, project().and("ba").as("b") //
|
||||
).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
DBObject projection0 = extractPipelineElement(agg, 0, "$project");
|
||||
assertThat(projection0, is((DBObject) new BasicDBObject("ba", "$foo.bar")));
|
||||
|
||||
DBObject projection1 = extractPipelineElement(agg, 1, "$project");
|
||||
assertThat(projection1, is((DBObject) new BasicDBObject("b", "$ba")));
|
||||
}
|
||||
|
||||
private DBObject extractPipelineElement(DBObject agg, int index, String operation) {
|
||||
|
||||
List<DBObject> pipeline = (List<DBObject>) agg.get("pipeline");
|
||||
return (DBObject) pipeline.get(index).get(operation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2014 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.
|
||||
@@ -17,25 +17,40 @@ package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
|
||||
import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference;
|
||||
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||
import org.springframework.data.mongodb.core.convert.DbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link TypeBasedAggregationOperationContext}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class TypeBasedAggregationOperationContextUnitTests {
|
||||
@@ -89,6 +104,104 @@ public class TypeBasedAggregationOperationContextUnitTests {
|
||||
assertThat(context.getReference("id"), is(new FieldReference(new ExposedField(Fields.field("id", "_id"), true))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-912
|
||||
*/
|
||||
@Test
|
||||
public void shouldUseCustomConversionIfPresentAndConversionIsRequiredInFirstStage() {
|
||||
|
||||
CustomConversions customConversions = customAgeConversions();
|
||||
converter.setCustomConversions(customConversions);
|
||||
customConversions.registerConvertersIn((GenericConversionService) converter.getConversionService());
|
||||
|
||||
AggregationOperationContext context = getContext(FooPerson.class);
|
||||
|
||||
MatchOperation matchStage = match(Criteria.where("age").is(new Age(10)));
|
||||
ProjectionOperation projectStage = project("age", "name");
|
||||
|
||||
DBObject agg = newAggregation(matchStage, projectStage).toDbObject("test", context);
|
||||
|
||||
DBObject age = getValue((DBObject) getValue(getPipelineElementFromAggregationAt(agg, 0), "$match"), "age");
|
||||
assertThat(age, is((DBObject) new BasicDBObject("v", 10)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-912
|
||||
*/
|
||||
@Test
|
||||
public void shouldUseCustomConversionIfPresentAndConversionIsRequiredInLaterStage() {
|
||||
|
||||
CustomConversions customConversions = customAgeConversions();
|
||||
converter.setCustomConversions(customConversions);
|
||||
customConversions.registerConvertersIn((GenericConversionService) converter.getConversionService());
|
||||
|
||||
AggregationOperationContext context = getContext(FooPerson.class);
|
||||
|
||||
MatchOperation matchStage = match(Criteria.where("age").is(new Age(10)));
|
||||
ProjectionOperation projectStage = project("age", "name");
|
||||
|
||||
DBObject agg = newAggregation(projectStage, matchStage).toDbObject("test", context);
|
||||
|
||||
DBObject age = getValue((DBObject) getValue(getPipelineElementFromAggregationAt(agg, 1), "$match"), "age");
|
||||
assertThat(age, is((DBObject) new BasicDBObject("v", 10)));
|
||||
}
|
||||
|
||||
@Document(collection = "person")
|
||||
public static class FooPerson {
|
||||
|
||||
final ObjectId id;
|
||||
final String name;
|
||||
final Age age;
|
||||
|
||||
@PersistenceConstructor
|
||||
FooPerson(ObjectId id, String name, Age age) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Age {
|
||||
|
||||
final int value;
|
||||
|
||||
Age(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public CustomConversions customAgeConversions() {
|
||||
return new CustomConversions(Arrays.<Converter<?, ?>> asList(ageWriteConverter(), ageReadConverter()));
|
||||
}
|
||||
|
||||
Converter<Age, DBObject> ageWriteConverter() {
|
||||
return new Converter<Age, DBObject>() {
|
||||
@Override
|
||||
public DBObject convert(Age age) {
|
||||
return new BasicDBObject("v", age.value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Converter<DBObject, Age> ageReadConverter() {
|
||||
return new Converter<DBObject, Age>() {
|
||||
@Override
|
||||
public Age convert(DBObject dbObject) {
|
||||
return new Age(((Integer) dbObject.get("v")));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static DBObject getPipelineElementFromAggregationAt(DBObject agg, int index) {
|
||||
return ((List<DBObject>) agg.get("pipeline")).get(index);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T> T getValue(DBObject o, String key) {
|
||||
return (T) o.get(key);
|
||||
}
|
||||
|
||||
private TypeBasedAggregationOperationContext getContext(Class<?> type) {
|
||||
return new TypeBasedAggregationOperationContext(type, context, mapper);
|
||||
}
|
||||
|
||||
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 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.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.BoxToDbObjectConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.CircleToDbObjectConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToBoxConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToCircleConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToLegacyCircleConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToPointConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToPolygonConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.DbObjectToSphereConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.GeoCommandToDbObjectConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.LegacyCircleToDbObjectConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.PointToDbObjectConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.PolygonToDbObjectConverter;
|
||||
import org.springframework.data.mongodb.core.convert.GeoConverters.SphereToDbObjectConverter;
|
||||
import org.springframework.data.mongodb.core.geo.Sphere;
|
||||
import org.springframework.data.mongodb.core.query.GeoCommand;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GeoConverters}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class GeoConvertersUnitTests {
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsBoxToDbObjectAndBackCorrectly() {
|
||||
|
||||
Box box = new Box(new Point(1, 2), new Point(3, 4));
|
||||
|
||||
DBObject dbo = BoxToDbObjectConverter.INSTANCE.convert(box);
|
||||
Box result = DbObjectToBoxConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(result, is(box));
|
||||
assertThat(result.getClass().equals(org.springframework.data.mongodb.core.geo.Box.class), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsCircleToDbObjectAndBackCorrectlyNeutralDistance() {
|
||||
|
||||
Circle circle = new Circle(new Point(1, 2), 3);
|
||||
|
||||
DBObject dbo = CircleToDbObjectConverter.INSTANCE.convert(circle);
|
||||
Circle result = DbObjectToCircleConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(result, is(circle));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsCircleToDbObjectAndBackCorrectlyMilesDistance() {
|
||||
|
||||
Distance radius = new Distance(3, Metrics.MILES);
|
||||
Circle circle = new Circle(new Point(1, 2), radius);
|
||||
|
||||
DBObject dbo = CircleToDbObjectConverter.INSTANCE.convert(circle);
|
||||
Circle result = DbObjectToCircleConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(result, is(circle));
|
||||
assertThat(result.getRadius(), is(radius));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsLegacyCircleToDbObjectAndBackCorrectly() {
|
||||
|
||||
org.springframework.data.mongodb.core.geo.Circle circle = new org.springframework.data.mongodb.core.geo.Circle(
|
||||
new Point(1, 2), 3);
|
||||
|
||||
DBObject dbo = LegacyCircleToDbObjectConverter.INSTANCE.convert(circle);
|
||||
org.springframework.data.mongodb.core.geo.Circle result = DbObjectToLegacyCircleConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(result, is(circle));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsPolygonToDbObjectAndBackCorrectly() {
|
||||
|
||||
Polygon polygon = new Polygon(new Point(1, 2), new Point(2, 3), new Point(3, 4), new Point(5, 6));
|
||||
|
||||
DBObject dbo = PolygonToDbObjectConverter.INSTANCE.convert(polygon);
|
||||
Polygon result = DbObjectToPolygonConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(result, is(polygon));
|
||||
assertThat(result.getClass().equals(org.springframework.data.mongodb.core.geo.Polygon.class), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsSphereToDbObjectAndBackCorrectlyWithNeutralDistance() {
|
||||
|
||||
Sphere sphere = new Sphere(new Point(1, 2), 3);
|
||||
|
||||
DBObject dbo = SphereToDbObjectConverter.INSTANCE.convert(sphere);
|
||||
Sphere result = DbObjectToSphereConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(result, is(sphere));
|
||||
assertThat(result.getClass().equals(org.springframework.data.mongodb.core.geo.Sphere.class), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsSphereToDbObjectAndBackCorrectlyWithKilometerDistance() {
|
||||
|
||||
Distance radius = new Distance(3, Metrics.KILOMETERS);
|
||||
Sphere sphere = new Sphere(new Point(1, 2), radius);
|
||||
|
||||
DBObject dbo = SphereToDbObjectConverter.INSTANCE.convert(sphere);
|
||||
Sphere result = DbObjectToSphereConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(result, is(sphere));
|
||||
assertThat(result.getRadius(), is(radius));
|
||||
assertThat(result.getClass().equals(org.springframework.data.mongodb.core.geo.Sphere.class), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsPointToListAndBackCorrectly() {
|
||||
|
||||
Point point = new Point(1, 2);
|
||||
|
||||
DBObject dbo = PointToDbObjectConverter.INSTANCE.convert(point);
|
||||
Point result = DbObjectToPointConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(result, is(point));
|
||||
assertThat(result.getClass().equals(org.springframework.data.mongodb.core.geo.Point.class), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void convertsGeoCommandToDbObjectCorrectly() {
|
||||
|
||||
Box box = new Box(new double[] { 1, 2 }, new double[] { 3, 4 });
|
||||
GeoCommand cmd = new GeoCommand(box);
|
||||
|
||||
DBObject dbo = GeoCommandToDbObjectConverter.INSTANCE.convert(cmd);
|
||||
|
||||
assertThat(dbo, is(notNullValue()));
|
||||
|
||||
DBObject boxObject = (DBObject) dbo.get("$box");
|
||||
|
||||
assertThat(boxObject,
|
||||
is((Object) Arrays.asList(GeoConverters.toList(box.getFirst()), GeoConverters.toList(box.getSecond()))));
|
||||
}
|
||||
}
|
||||
@@ -41,10 +41,8 @@ import java.util.TreeMap;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
@@ -55,19 +53,11 @@ import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.geo.Shape;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mapping.model.MappingInstantiationException;
|
||||
import org.springframework.data.mongodb.core.DBObjectTestUtils;
|
||||
import org.springframework.data.mongodb.core.convert.DBObjectAccessorUnitTests.NestedType;
|
||||
import org.springframework.data.mongodb.core.convert.DBObjectAccessorUnitTests.ProjectingType;
|
||||
import org.springframework.data.mongodb.core.geo.Sphere;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
@@ -661,7 +651,9 @@ public class MappingMongoConverterUnitTests {
|
||||
public void readsMapListNestedValuesCorrectly() {
|
||||
|
||||
BasicDBList list = new BasicDBList();
|
||||
list.add(new BasicDBObject("Hello", "World"));
|
||||
BasicDBObject nested = new BasicDBObject();
|
||||
nested.append("Hello", "World");
|
||||
list.add(nested);
|
||||
DBObject source = new BasicDBObject("mapOfObjects", new BasicDBObject("Foo", list));
|
||||
|
||||
ClassWithMapProperty result = converter.read(ClassWithMapProperty.class, source);
|
||||
@@ -1398,6 +1390,7 @@ public class MappingMongoConverterUnitTests {
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-812
|
||||
* @see DATAMONGO-893
|
||||
*/
|
||||
@Test
|
||||
public void convertsListToBasicDBListAndRetainsTypeInformationForComplexObjects() {
|
||||
@@ -1407,7 +1400,7 @@ public class MappingMongoConverterUnitTests {
|
||||
address.street = "Foo";
|
||||
|
||||
Object result = converter.convertToMongoType(Collections.singletonList(address),
|
||||
ClassTypeInformation.from(Address.class));
|
||||
ClassTypeInformation.from(InterfaceType.class));
|
||||
|
||||
assertThat(result, is(instanceOf(BasicDBList.class)));
|
||||
|
||||
@@ -1535,277 +1528,6 @@ public class MappingMongoConverterUnitTests {
|
||||
assertThat(entry.get("foo"), is((Object) "Dave"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void shouldWriteEntityWithGeoBoxCorrectly() {
|
||||
|
||||
ClassWithGeoBox object = new ClassWithGeoBox();
|
||||
object.box = new Box(new Point(1, 2), new Point(3, 4));
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
assertThat(dbo, is(notNullValue()));
|
||||
assertThat(dbo.get("box"), is(instanceOf(DBObject.class)));
|
||||
assertThat(dbo.get("box"), is((Object) new BasicDBObject().append("first", toDbObject(object.box.getFirst()))
|
||||
.append("second", toDbObject(object.box.getSecond()))));
|
||||
}
|
||||
|
||||
private static DBObject toDbObject(Point point) {
|
||||
return new BasicDBObject("x", point.getX()).append("y", point.getY());
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void shouldReadEntityWithGeoBoxCorrectly() {
|
||||
|
||||
ClassWithGeoBox object = new ClassWithGeoBox();
|
||||
object.box = new Box(new Point(1, 2), new Point(3, 4));
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
ClassWithGeoBox result = converter.read(ClassWithGeoBox.class, dbo);
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertThat(result.box, is(object.box));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void shouldWriteEntityWithGeoPolygonCorrectly() {
|
||||
|
||||
ClassWithGeoPolygon object = new ClassWithGeoPolygon();
|
||||
object.polygon = new Polygon(new Point(1, 2), new Point(3, 4), new Point(4, 5));
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
assertThat(dbo, is(notNullValue()));
|
||||
|
||||
assertThat(dbo.get("polygon"), is(instanceOf(DBObject.class)));
|
||||
DBObject polygonDbo = (DBObject) dbo.get("polygon");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<DBObject> points = (List<DBObject>) polygonDbo.get("points");
|
||||
|
||||
assertThat(points, hasSize(3));
|
||||
assertThat(points, Matchers.<DBObject> hasItems(toDbObject(object.polygon.getPoints().get(0)),
|
||||
toDbObject(object.polygon.getPoints().get(1)), toDbObject(object.polygon.getPoints().get(2))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void shouldReadEntityWithGeoPolygonCorrectly() {
|
||||
|
||||
ClassWithGeoPolygon object = new ClassWithGeoPolygon();
|
||||
object.polygon = new Polygon(new Point(1, 2), new Point(3, 4), new Point(4, 5));
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
ClassWithGeoPolygon result = converter.read(ClassWithGeoPolygon.class, dbo);
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertThat(result.polygon, is(object.polygon));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void shouldWriteEntityWithGeoCircleCorrectly() {
|
||||
|
||||
ClassWithGeoCircle object = new ClassWithGeoCircle();
|
||||
Circle circle = new Circle(new Point(1, 2), 3);
|
||||
Distance radius = circle.getRadius();
|
||||
object.circle = circle;
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
assertThat(dbo, is(notNullValue()));
|
||||
assertThat(dbo.get("circle"), is(instanceOf(DBObject.class)));
|
||||
assertThat(
|
||||
dbo.get("circle"),
|
||||
is((Object) new BasicDBObject("center", new BasicDBObject("x", circle.getCenter().getX()).append("y", circle
|
||||
.getCenter().getY())).append("radius", radius.getNormalizedValue()).append("metric",
|
||||
radius.getMetric().toString())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void shouldReadEntityWithGeoCircleCorrectly() {
|
||||
|
||||
ClassWithGeoCircle object = new ClassWithGeoCircle();
|
||||
object.circle = new Circle(new Point(1, 2), 3);
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
ClassWithGeoCircle result = converter.read(ClassWithGeoCircle.class, dbo);
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertThat(result.circle, is(result.circle));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void shouldWriteEntityWithGeoLegacyCircleCorrectly() {
|
||||
|
||||
ClassWithGeoLegacyCircle object = new ClassWithGeoLegacyCircle();
|
||||
org.springframework.data.mongodb.core.geo.Circle circle = new org.springframework.data.mongodb.core.geo.Circle(
|
||||
new Point(1, 2), 3);
|
||||
object.circle = circle;
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
assertThat(dbo, is(notNullValue()));
|
||||
assertThat(dbo.get("circle"), is(instanceOf(DBObject.class)));
|
||||
assertThat(dbo.get("circle"), is((Object) new BasicDBObject("center", new BasicDBObject("x", circle.getCenter()
|
||||
.getX()).append("y", circle.getCenter().getY())).append("radius", circle.getRadius())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void shouldReadEntityWithGeoLegacyCircleCorrectly() {
|
||||
|
||||
ClassWithGeoLegacyCircle object = new ClassWithGeoLegacyCircle();
|
||||
object.circle = new org.springframework.data.mongodb.core.geo.Circle(new Point(1, 2), 3);
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
ClassWithGeoLegacyCircle result = converter.read(ClassWithGeoLegacyCircle.class, dbo);
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertThat(result.circle, is(result.circle));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void shouldWriteEntityWithGeoSphereCorrectly() {
|
||||
|
||||
ClassWithGeoSphere object = new ClassWithGeoSphere();
|
||||
Sphere sphere = new Sphere(new Point(1, 2), 3);
|
||||
Distance radius = sphere.getRadius();
|
||||
object.sphere = sphere;
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
assertThat(dbo, is(notNullValue()));
|
||||
assertThat(dbo.get("sphere"), is(instanceOf(DBObject.class)));
|
||||
assertThat(
|
||||
dbo.get("sphere"),
|
||||
is((Object) new BasicDBObject("center", new BasicDBObject("x", sphere.getCenter().getX()).append("y", sphere
|
||||
.getCenter().getY())).append("radius", radius.getNormalizedValue()).append("metric",
|
||||
radius.getMetric().toString())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void shouldWriteEntityWithGeoSphereWithMetricDistanceCorrectly() {
|
||||
|
||||
ClassWithGeoSphere object = new ClassWithGeoSphere();
|
||||
Sphere sphere = new Sphere(new Point(1, 2), new Distance(3, Metrics.KILOMETERS));
|
||||
Distance radius = sphere.getRadius();
|
||||
object.sphere = sphere;
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
assertThat(dbo, is(notNullValue()));
|
||||
assertThat(dbo.get("sphere"), is(instanceOf(DBObject.class)));
|
||||
assertThat(
|
||||
dbo.get("sphere"),
|
||||
is((Object) new BasicDBObject("center", new BasicDBObject("x", sphere.getCenter().getX()).append("y", sphere
|
||||
.getCenter().getY())).append("radius", radius.getNormalizedValue()).append("metric",
|
||||
radius.getMetric().toString())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void shouldReadEntityWithGeoSphereCorrectly() {
|
||||
|
||||
ClassWithGeoSphere object = new ClassWithGeoSphere();
|
||||
object.sphere = new Sphere(new Point(1, 2), 3);
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
ClassWithGeoSphere result = converter.read(ClassWithGeoSphere.class, dbo);
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertThat(result.sphere, is(object.sphere));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void shouldWriteEntityWithGeoShapeCorrectly() {
|
||||
|
||||
ClassWithGeoShape object = new ClassWithGeoShape();
|
||||
Sphere sphere = new Sphere(new Point(1, 2), 3);
|
||||
Distance radius = sphere.getRadius();
|
||||
object.shape = sphere;
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
assertThat(dbo, is(notNullValue()));
|
||||
assertThat(dbo.get("shape"), is(instanceOf(DBObject.class)));
|
||||
assertThat(
|
||||
dbo.get("shape"),
|
||||
is((Object) new BasicDBObject("center", new BasicDBObject("x", sphere.getCenter().getX()).append("y", sphere
|
||||
.getCenter().getY())).append("radius", radius.getNormalizedValue()).append("metric",
|
||||
radius.getMetric().toString())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void shouldReadEntityWithGeoShapeCorrectly() {
|
||||
|
||||
ClassWithGeoShape object = new ClassWithGeoShape();
|
||||
Sphere sphere = new Sphere(new Point(1, 2), 3);
|
||||
object.shape = sphere;
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
converter.write(object, dbo);
|
||||
|
||||
ClassWithGeoShape result = converter.read(ClassWithGeoShape.class, dbo);
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertThat(result.shape, is((Shape) sphere));
|
||||
}
|
||||
|
||||
static class GenericType<T> {
|
||||
T content;
|
||||
}
|
||||
@@ -1833,7 +1555,11 @@ public class MappingMongoConverterUnitTests {
|
||||
abstract void method();
|
||||
}
|
||||
|
||||
static class Address {
|
||||
static interface InterfaceType {
|
||||
|
||||
}
|
||||
|
||||
static class Address implements InterfaceType {
|
||||
String street;
|
||||
String city;
|
||||
}
|
||||
@@ -2021,35 +1747,4 @@ public class MappingMongoConverterUnitTests {
|
||||
return m_property;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithGeoBox {
|
||||
|
||||
Box box;
|
||||
}
|
||||
|
||||
class ClassWithGeoCircle {
|
||||
|
||||
Circle circle;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
class ClassWithGeoLegacyCircle {
|
||||
|
||||
org.springframework.data.mongodb.core.geo.Circle circle;
|
||||
}
|
||||
|
||||
class ClassWithGeoSphere {
|
||||
|
||||
Sphere sphere;
|
||||
}
|
||||
|
||||
class ClassWithGeoPolygon {
|
||||
|
||||
Polygon polygon;
|
||||
}
|
||||
|
||||
class ClassWithGeoShape {
|
||||
|
||||
Shape shape;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2014 by the original author(s).
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,22 +21,13 @@ import static org.junit.Assert.*;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.geo.Shape;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
|
||||
import org.springframework.data.mongodb.core.geo.Sphere;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MongoConverters}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class MongoConvertersUnitTests {
|
||||
|
||||
@@ -50,74 +41,4 @@ public class MongoConvertersUnitTests {
|
||||
BigDecimal reference = StringToBigDecimalConverter.INSTANCE.convert(value);
|
||||
assertThat(reference, is(bigDecimal));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsBoxToDbObjectAndBackCorrectly() {
|
||||
|
||||
Box box = new Box(new Point(1, 2), new Point(3, 4));
|
||||
|
||||
DBObject dbo = GeoConverters.BoxToDbObjectConverter.INSTANCE.convert(box);
|
||||
Shape shape = GeoConverters.DbObjectToBoxConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(shape, is((org.springframework.data.geo.Shape) box));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsCircleToDbObjectAndBackCorrectly() {
|
||||
|
||||
Circle circle = new Circle(new Point(1, 2), 3);
|
||||
|
||||
DBObject dbo = GeoConverters.CircleToDbObjectConverter.INSTANCE.convert(circle);
|
||||
Shape shape = GeoConverters.DbObjectToCircleConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(shape, is((org.springframework.data.geo.Shape) circle));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsPolygonToDbObjectAndBackCorrectly() {
|
||||
|
||||
Polygon polygon = new Polygon(new Point(1, 2), new Point(2, 3), new Point(3, 4), new Point(5, 6));
|
||||
|
||||
DBObject dbo = GeoConverters.PolygonToDbObjectConverter.INSTANCE.convert(polygon);
|
||||
Shape shape = GeoConverters.DbObjectToPolygonConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(shape, is((org.springframework.data.geo.Shape) polygon));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsSphereToDbObjectAndBackCorrectly() {
|
||||
|
||||
Sphere sphere = new Sphere(new Point(1, 2), 3);
|
||||
|
||||
DBObject dbo = GeoConverters.SphereToDbObjectConverter.INSTANCE.convert(sphere);
|
||||
org.springframework.data.geo.Shape shape = GeoConverters.DbObjectToSphereConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(shape, is((org.springframework.data.geo.Shape) sphere));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-858
|
||||
*/
|
||||
@Test
|
||||
public void convertsPointToListAndBackCorrectly() {
|
||||
|
||||
Point point = new Point(1, 2);
|
||||
|
||||
DBObject dbo = GeoConverters.PointToDbObjectConverter.INSTANCE.convert(point);
|
||||
org.springframework.data.geo.Point converted = GeoConverters.DbObjectToPointConverter.INSTANCE.convert(dbo);
|
||||
|
||||
assertThat(converted, is((org.springframework.data.geo.Point) point));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,11 +34,14 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.DBObjectTestUtils;
|
||||
import org.springframework.data.mongodb.core.Person;
|
||||
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
@@ -48,6 +51,7 @@ import org.springframework.data.mongodb.core.query.Query;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.BasicDBObjectBuilder;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.QueryBuilder;
|
||||
|
||||
@@ -568,10 +572,53 @@ public class QueryMapperUnitTests {
|
||||
assertThat(mappedFields, is(notNullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-893
|
||||
*/
|
||||
@Test
|
||||
public void classInformationShouldNotBePresentInDBObjectUsedInFinderMethods() {
|
||||
|
||||
EmbeddedClass embedded = new EmbeddedClass();
|
||||
embedded.id = "1";
|
||||
|
||||
EmbeddedClass embedded2 = new EmbeddedClass();
|
||||
embedded2.id = "2";
|
||||
Query query = query(where("embedded").in(Arrays.asList(embedded, embedded2)));
|
||||
|
||||
DBObject dbo = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(Foo.class));
|
||||
assertThat(dbo.toString(), equalTo("{ \"embedded\" : { \"$in\" : [ { \"_id\" : \"1\"} , { \"_id\" : \"2\"}]}}"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-647
|
||||
*/
|
||||
@Test
|
||||
public void customizedFieldNameShouldBeMappedCorrectlyWhenApplyingSort() {
|
||||
|
||||
Query query = query(where("field").is("bar")).with(new Sort(Direction.DESC, "field"));
|
||||
DBObject dbo = mapper.getMappedObject(query.getSortObject(), context.getPersistentEntity(CustomizedField.class));
|
||||
assertThat(dbo, equalTo(new BasicDBObjectBuilder().add("foo", -1).get()));
|
||||
}
|
||||
|
||||
@Document
|
||||
public class Foo {
|
||||
@Id private ObjectId id;
|
||||
EmbeddedClass embedded;
|
||||
}
|
||||
|
||||
public class EmbeddedClass {
|
||||
public String id;
|
||||
}
|
||||
|
||||
class IdWrapper {
|
||||
Object id;
|
||||
}
|
||||
|
||||
class ClassWithEmbedded {
|
||||
@Id String id;
|
||||
Sample sample;
|
||||
}
|
||||
|
||||
class ClassWithDefaultId {
|
||||
|
||||
String id;
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.collection.IsIterableContainingInOrder;
|
||||
import org.hamcrest.core.IsEqual;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -37,12 +38,16 @@ import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.convert.WritingConverter;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.DBObjectTestUtils;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.BasicDBObjectBuilder;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.DBRef;
|
||||
|
||||
@@ -412,42 +417,112 @@ public class UpdateMapperUnitTests {
|
||||
assertThat(inClause, IsIterableContainingInOrder.<Object> contains(1L, 2L));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DATAMONG0-471
|
||||
* @see DATAMONGO-897
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Test
|
||||
public void testUpdateShouldApply$addToSetCorrectlyWhenUsedWith$each() {
|
||||
public void updateOnDbrefPropertyOfInterfaceTypeWithoutExplicitGetterForIdShouldBeMappedCorrectly() {
|
||||
|
||||
Update update = new Update().addToSet("values").each("spring", "data", "mongodb");
|
||||
Update update = new Update().set("referencedDocument", new InterfaceDocumentDefinitionImpl("1", "Foo"));
|
||||
DBObject mappedObject = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(ListModel.class));
|
||||
context.getPersistentEntity(DocumentWithReferenceToInterfaceImpl.class));
|
||||
|
||||
DBObject addToSet = getAsDBObject(mappedObject, "$addToSet");
|
||||
DBObject values = getAsDBObject(addToSet, "values");
|
||||
BasicDBList each = getAsDBList(values, "$each");
|
||||
DBObject $set = DBObjectTestUtils.getAsDBObject(mappedObject, "$set");
|
||||
Object model = $set.get("referencedDocument");
|
||||
|
||||
assertThat(each.toMap(), (Matcher) allOf(hasValue("spring"), hasValue("data"), hasValue("mongodb")));
|
||||
DBRef expectedDBRef = new DBRef(factory.getDb(), "interfaceDocumentDefinitionImpl", "1");
|
||||
assertThat(model, allOf(instanceOf(DBRef.class), IsEqual.<Object> equalTo(expectedDBRef)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONG0-471
|
||||
* @see DATAMONGO-847
|
||||
*/
|
||||
@Test
|
||||
public void testUpdateShouldRetainClassTypeInformationWhenUsing$addToSetWith$eachForCustomTypes() {
|
||||
public void updateMapperConvertsNestedQueryCorrectly() {
|
||||
|
||||
Update update = new Update().addToSet("models").each(new ModelImpl(2014), new ModelImpl(1), new ModelImpl(28));
|
||||
DBObject mappedObject = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(ModelWrapper.class));
|
||||
Update update = new Update().pull("list", Query.query(Criteria.where("value").in("foo", "bar")));
|
||||
DBObject mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(ParentClass.class));
|
||||
|
||||
DBObject addToSet = getAsDBObject(mappedObject, "$addToSet");
|
||||
DBObject $pull = DBObjectTestUtils.getAsDBObject(mappedUpdate, "$pull");
|
||||
DBObject list = DBObjectTestUtils.getAsDBObject($pull, "aliased");
|
||||
DBObject value = DBObjectTestUtils.getAsDBObject(list, "value");
|
||||
BasicDBList $in = DBObjectTestUtils.getAsDBList(value, "$in");
|
||||
|
||||
DBObject values = getAsDBObject(addToSet, "models");
|
||||
BasicDBList each = getAsDBList(values, "$each");
|
||||
assertThat($in, IsIterableContainingInOrder.<Object> contains("foo", "bar"));
|
||||
}
|
||||
|
||||
for (Object updateValue : each) {
|
||||
assertThat(((DBObject) updateValue).get("_class").toString(),
|
||||
equalTo("org.springframework.data.mongodb.core.convert.UpdateMapperUnitTests$ModelImpl"));
|
||||
/**
|
||||
* @see DATAMONGO-847
|
||||
*/
|
||||
@Test
|
||||
public void updateMapperConvertsPullWithNestedQuerfyOnDBRefCorrectly() {
|
||||
|
||||
Update update = new Update().pull("dbRefAnnotatedList", Query.query(Criteria.where("id").is("1")));
|
||||
DBObject mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(DocumentWithDBRefCollection.class));
|
||||
|
||||
DBObject $pull = DBObjectTestUtils.getAsDBObject(mappedUpdate, "$pull");
|
||||
DBObject list = DBObjectTestUtils.getAsDBObject($pull, "dbRefAnnotatedList");
|
||||
|
||||
assertThat(list, equalTo(new BasicDBObjectBuilder().add("_id", "1").get()));
|
||||
}
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.Document(collection = "DocumentWithReferenceToInterface")
|
||||
static interface DocumentWithReferenceToInterface {
|
||||
|
||||
String getId();
|
||||
|
||||
InterfaceDocumentDefinitionWithoutId getReferencedDocument();
|
||||
|
||||
}
|
||||
|
||||
static interface InterfaceDocumentDefinitionWithoutId {
|
||||
|
||||
String getValue();
|
||||
}
|
||||
|
||||
static class InterfaceDocumentDefinitionImpl implements InterfaceDocumentDefinitionWithoutId {
|
||||
|
||||
@Id String id;
|
||||
String value;
|
||||
|
||||
public InterfaceDocumentDefinitionImpl(String id, String value) {
|
||||
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class DocumentWithReferenceToInterfaceImpl implements DocumentWithReferenceToInterface {
|
||||
|
||||
private @Id String id;
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef//
|
||||
private InterfaceDocumentDefinitionWithoutId referencedDocument;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setModel(InterfaceDocumentDefinitionWithoutId referencedDocument) {
|
||||
this.referencedDocument = referencedDocument;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterfaceDocumentDefinitionWithoutId getReferencedDocument() {
|
||||
return this.referencedDocument;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -465,12 +540,6 @@ public class UpdateMapperUnitTests {
|
||||
|
||||
public class ModelWrapper {
|
||||
Model model;
|
||||
|
||||
public ModelWrapper() {}
|
||||
|
||||
public ModelWrapper(Model model) {
|
||||
this.model = model;
|
||||
}
|
||||
}
|
||||
|
||||
static class ListModelWrapper {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 by the original author(s).
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,13 +19,14 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.geo.Box;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Box}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class BoxUnitTests {
|
||||
|
||||
Box first = new Box(new Point(1d, 1d), new Point(2d, 2d));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -25,7 +25,6 @@ import org.junit.Test;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class CircleUnitTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,44 +15,36 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.geo;
|
||||
|
||||
import static org.springframework.data.mongodb.core.geo.Metrics.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.geo.Metrics.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.geo.Metric;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Distance}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class DistanceUnitTests {
|
||||
|
||||
@Test
|
||||
public void defaultsMetricToNeutralOne() {
|
||||
|
||||
assertThat(new Distance(2.5).getMetric(), is((Metric) org.springframework.data.geo.Metrics.NEUTRAL));
|
||||
assertThat(new Distance(2.5, null).getMetric(), is((Metric) org.springframework.data.geo.Metrics.NEUTRAL));
|
||||
assertThat(new Distance(2.5).getMetric(), is((Metric) Metrics.NEUTRAL));
|
||||
assertThat(new Distance(2.5, null).getMetric(), is((Metric) Metrics.NEUTRAL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsDistancesWithoutExplicitMetric() {
|
||||
|
||||
Distance left = new Distance(2.5, KILOMETERS);
|
||||
Distance right = new Distance(2.5, KILOMETERS);
|
||||
|
||||
assertThat(left.add(right), is(new org.springframework.data.geo.Distance(5.0, KILOMETERS)));
|
||||
assertThat(left.add(right), is(new Distance(5.0, KILOMETERS)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsDistancesWithExplicitMetric() {
|
||||
|
||||
Distance left = new Distance(2.5, KILOMETERS);
|
||||
Distance right = new Distance(2.5, KILOMETERS);
|
||||
|
||||
assertThat(left.add(right, MILES), is(new org.springframework.data.geo.Distance(3.106856281073925, MILES)));
|
||||
assertThat(left.add(right, MILES), is(new Distance(3.106856281073925, MILES)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,9 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.geo;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
@@ -25,7 +24,6 @@ import org.junit.Test;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class GeoResultUnitTests {
|
||||
|
||||
GeoResult<String> first = new GeoResult<String>("Foo", new Distance(2.5));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -26,9 +26,7 @@ import org.junit.Test;
|
||||
* Unit tests for {@link GeoResults}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class GeoResultsUnitTests {
|
||||
|
||||
@Test
|
||||
@@ -39,6 +37,6 @@ public class GeoResultsUnitTests {
|
||||
GeoResult<Object> second = new GeoResult<Object>(new Object(), new Distance(5));
|
||||
GeoResults<Object> geoResults = new GeoResults<Object>(Arrays.asList(first, second));
|
||||
|
||||
assertThat(geoResults.getAverageDistance(), is(new org.springframework.data.geo.Distance(3.5)));
|
||||
assertThat(geoResults.getAverageDistance(), is(new Distance(3.5)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* Copyright 2013 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.
|
||||
@@ -24,7 +24,6 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.config.AbstractIntegrationTests;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
@@ -42,7 +41,6 @@ import com.mongodb.WriteConcern;
|
||||
*
|
||||
* @author Laurent Canet
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class GeoSpatialIndexTests extends AbstractIntegrationTests {
|
||||
|
||||
@@ -131,10 +129,10 @@ public class GeoSpatialIndexTests extends AbstractIntegrationTests {
|
||||
|
||||
static class GeoSpatialEntity2D {
|
||||
public String id;
|
||||
@GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2D) public org.springframework.data.geo.Point location;
|
||||
@GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2D) public Point location;
|
||||
|
||||
public GeoSpatialEntity2D(double x, double y) {
|
||||
this.location = new org.springframework.data.geo.Point(x, y);
|
||||
this.location = new Point(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2014 the original author or authors.
|
||||
* Copyright 2010-2013 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.
|
||||
@@ -31,12 +31,6 @@ import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.mongodb.config.AbstractIntegrationTests;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.IndexOperations;
|
||||
@@ -60,7 +54,6 @@ import com.mongodb.WriteConcern;
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class GeoSpatialTests extends AbstractIntegrationTests {
|
||||
|
||||
@@ -98,13 +91,11 @@ public class GeoSpatialTests extends AbstractIntegrationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void geoNear() {
|
||||
|
||||
NearQuery geoNear = NearQuery.near(-73, 40, Metrics.KILOMETERS).num(10).maxDistance(150);
|
||||
|
||||
GeoResults<Venue> result = template.geoNear(geoNear, Venue.class);
|
||||
|
||||
assertThat(result.getContent().size(), is(not(0)));
|
||||
assertThat(result.getAverageDistance().getMetric(), is((Metric) Metrics.KILOMETERS));
|
||||
}
|
||||
|
||||
@@ -1,31 +1,16 @@
|
||||
/*
|
||||
* Copyright 2011-2014 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.geo;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Point}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class PointUnitTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -25,7 +25,6 @@ import org.junit.Test;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class PolygonUnitTests {
|
||||
|
||||
Point first = new Point(1, 1);
|
||||
|
||||
@@ -24,7 +24,8 @@ import org.springframework.data.annotation.PersistenceConstructor;
|
||||
*/
|
||||
public class PersonCustomIdName extends BasePerson {
|
||||
|
||||
@Id private String lastName;
|
||||
@Id
|
||||
private String lastName;
|
||||
|
||||
public PersonCustomIdName(Integer ssn, String firstName) {
|
||||
this.ssn = ssn;
|
||||
|
||||
@@ -23,7 +23,8 @@ import org.springframework.data.annotation.Id;
|
||||
@Document
|
||||
public class PersonMultiDimArrays extends BasePerson {
|
||||
|
||||
@Id private String id;
|
||||
@Id
|
||||
private String id;
|
||||
private String[][] grid;
|
||||
|
||||
public PersonMultiDimArrays(Integer ssn, String firstName, String lastName, String[][] grid) {
|
||||
|
||||
@@ -16,13 +16,15 @@
|
||||
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class PersonWithDbRef extends BasePerson {
|
||||
|
||||
@DBRef private GeoLocation home;
|
||||
@DBRef
|
||||
private GeoLocation home;
|
||||
|
||||
public PersonWithDbRef(Integer ssn, String firstName, String lastName, GeoLocation home) {
|
||||
super(ssn, firstName, lastName);
|
||||
|
||||
@@ -5,7 +5,8 @@ package org.springframework.data.mongodb.core.mapping;
|
||||
*/
|
||||
public class PersonWithLongDBRef extends BasePerson {
|
||||
|
||||
@DBRef private PersonPojoLongId personPojoLongId;
|
||||
@DBRef
|
||||
private PersonPojoLongId personPojoLongId;
|
||||
|
||||
public PersonWithLongDBRef(Integer ssn, String firstName, String lastName, PersonPojoLongId personPojoLongId) {
|
||||
super(ssn, firstName, lastName);
|
||||
|
||||
@@ -23,8 +23,6 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
|
||||
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory;
|
||||
@@ -35,7 +33,6 @@ import org.springframework.data.support.IsNewStrategyFactory;
|
||||
* Unit tests for {@link AuditingEventListener}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AuditingEventListenerUnitTests {
|
||||
@@ -55,26 +52,14 @@ public class AuditingEventListenerUnitTests {
|
||||
doNothing().when(handler).markCreated(Mockito.any(Object.class));
|
||||
doNothing().when(handler).markModified(Mockito.any(Object.class));
|
||||
|
||||
listener = new AuditingEventListener(new ObjectFactory<IsNewAwareAuditingHandler>() {
|
||||
|
||||
@Override
|
||||
public IsNewAwareAuditingHandler getObject() throws BeansException {
|
||||
return handler;
|
||||
}
|
||||
});
|
||||
listener = new AuditingEventListener(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-577
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullAuditingHandler() {
|
||||
new AuditingEventListener(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-577
|
||||
*/
|
||||
@Test
|
||||
public void triggersCreationMarkForObjectWithEmptyId() {
|
||||
|
||||
@@ -85,9 +70,6 @@ public class AuditingEventListenerUnitTests {
|
||||
verify(handler, times(0)).markModified(any(Sample.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-577
|
||||
*/
|
||||
@Test
|
||||
public void triggersModificationMarkForObjectWithSetId() {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2014 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.
|
||||
@@ -37,6 +37,7 @@ import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.convert.DbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.geo.Box;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -50,6 +51,7 @@ import com.mongodb.Mongo;
|
||||
* Integration test for {@link MongoTemplate}'s Map-Reduce operations
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
@@ -276,6 +278,31 @@ public class MapReduceTests {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-938
|
||||
*/
|
||||
@Test
|
||||
public void mapReduceShouldUseQueryMapper() {
|
||||
|
||||
DBCollection c = mongoTemplate.getDb().getCollection("jmrWithGeo");
|
||||
|
||||
c.save(new BasicDBObject("x", new String[] { "a", "b" }).append("loc", new double[] { 0, 0 }));
|
||||
c.save(new BasicDBObject("x", new String[] { "b", "c" }).append("loc", new double[] { 0, 0 }));
|
||||
c.save(new BasicDBObject("x", new String[] { "c", "d" }).append("loc", new double[] { 0, 0 }));
|
||||
|
||||
Query query = new Query(where("x").ne(new String[] { "a", "b" }).and("loc")
|
||||
.within(new Box(new double[] { 0, 0 }, new double[] { 1, 1 })));
|
||||
|
||||
MapReduceResults<ValueObject> results = template.mapReduce(query, "jmrWithGeo", mapFunction, reduceFunction,
|
||||
ValueObject.class);
|
||||
|
||||
Map<String, Float> m = copyToMap(results);
|
||||
assertEquals(3, m.size());
|
||||
assertEquals(1, m.get("b").intValue());
|
||||
assertEquals(2, m.get("c").intValue());
|
||||
assertEquals(1, m.get("d").intValue());
|
||||
}
|
||||
|
||||
private void performMapReduce(boolean inline, boolean withQuery) {
|
||||
createMapReduceData();
|
||||
MapReduceResults<ValueObject> results;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user