diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/DurationStyle.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/DurationStyle.java
new file mode 100644
index 000000000..c7f702691
--- /dev/null
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/DurationStyle.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2012-2019 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
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.mongodb.core.index;
+
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import java.util.function.Function;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.springframework.lang.Nullable;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * Duration format styles.
+ *
+ * Fork of {@code org.springframework.boot.convert.DurationStyle}.
+ *
+ * @author Phillip Webb
+ * @since 2.2
+ */
+enum DurationStyle {
+
+ /**
+ * Simple formatting, for example '1s'.
+ */
+ SIMPLE("^([\\+\\-]?\\d+)([a-zA-Z]{0,2})$") {
+
+ @Override
+ public Duration parse(String value, @Nullable ChronoUnit unit) {
+ try {
+ Matcher matcher = matcher(value);
+ Assert.state(matcher.matches(), "Does not match simple duration pattern");
+ String suffix = matcher.group(2);
+ return (StringUtils.hasLength(suffix) ? Unit.fromSuffix(suffix) : Unit.fromChronoUnit(unit))
+ .parse(matcher.group(1));
+ } catch (Exception ex) {
+ throw new IllegalArgumentException("'" + value + "' is not a valid simple duration", ex);
+ }
+ }
+ },
+
+ /**
+ * ISO-8601 formatting.
+ */
+ ISO8601("^[\\+\\-]?P.*$") {
+
+ @Override
+ public Duration parse(String value, @Nullable ChronoUnit unit) {
+ try {
+ return Duration.parse(value);
+ } catch (Exception ex) {
+ throw new IllegalArgumentException("'" + value + "' is not a valid ISO-8601 duration", ex);
+ }
+ }
+ };
+
+ private final Pattern pattern;
+
+ DurationStyle(String pattern) {
+ this.pattern = Pattern.compile(pattern);
+ }
+
+ protected final boolean matches(String value) {
+ return this.pattern.matcher(value).matches();
+ }
+
+ protected final Matcher matcher(String value) {
+ return this.pattern.matcher(value);
+ }
+
+ /**
+ * Parse the given value to a duration.
+ *
+ * @param value the value to parse
+ * @return a duration
+ */
+ public Duration parse(String value) {
+ return parse(value, null);
+ }
+
+ /**
+ * Parse the given value to a duration.
+ *
+ * @param value the value to parse
+ * @param unit the duration unit to use if the value doesn't specify one ({@code null} will default to ms)
+ * @return a duration
+ */
+ public abstract Duration parse(String value, @Nullable ChronoUnit unit);
+
+ /**
+ * Detect the style then parse the value to return a duration.
+ *
+ * @param value the value to parse
+ * @return the parsed duration
+ * @throws IllegalStateException if the value is not a known style or cannot be parsed
+ */
+ public static Duration detectAndParse(String value) {
+ return detectAndParse(value, null);
+ }
+
+ /**
+ * Detect the style then parse the value to return a duration.
+ *
+ * @param value the value to parse
+ * @param unit the duration unit to use if the value doesn't specify one ({@code null} will default to ms)
+ * @return the parsed duration
+ * @throws IllegalStateException if the value is not a known style or cannot be parsed
+ */
+ public static Duration detectAndParse(String value, @Nullable ChronoUnit unit) {
+ return detect(value).parse(value, unit);
+ }
+
+ /**
+ * Detect the style from the given source value.
+ *
+ * @param value the source value
+ * @return the duration style
+ * @throws IllegalStateException if the value is not a known style
+ */
+ public static DurationStyle detect(String value) {
+ Assert.notNull(value, "Value must not be null");
+ for (DurationStyle candidate : values()) {
+ if (candidate.matches(value)) {
+ return candidate;
+ }
+ }
+ throw new IllegalArgumentException("'" + value + "' is not a valid duration");
+ }
+
+ /**
+ * Units that we support.
+ */
+ enum Unit {
+
+ /**
+ * Milliseconds.
+ */
+ MILLIS(ChronoUnit.MILLIS, "ms", Duration::toMillis),
+
+ /**
+ * Seconds.
+ */
+ SECONDS(ChronoUnit.SECONDS, "s", Duration::getSeconds),
+
+ /**
+ * Minutes.
+ */
+ MINUTES(ChronoUnit.MINUTES, "m", Duration::toMinutes),
+
+ /**
+ * Hours.
+ */
+ HOURS(ChronoUnit.HOURS, "h", Duration::toHours),
+
+ /**
+ * Days.
+ */
+ DAYS(ChronoUnit.DAYS, "d", Duration::toDays);
+
+ private final ChronoUnit chronoUnit;
+
+ private final String suffix;
+
+ private Function longValue;
+
+ Unit(ChronoUnit chronoUnit, String suffix, Function toUnit) {
+ this.chronoUnit = chronoUnit;
+ this.suffix = suffix;
+ this.longValue = toUnit;
+ }
+
+ public Duration parse(String value) {
+ return Duration.of(Long.valueOf(value), this.chronoUnit);
+ }
+
+ public long longValue(Duration value) {
+ return this.longValue.apply(value);
+ }
+
+ public static Unit fromChronoUnit(ChronoUnit chronoUnit) {
+ if (chronoUnit == null) {
+ return Unit.MILLIS;
+ }
+ for (Unit candidate : values()) {
+ if (candidate.chronoUnit == chronoUnit) {
+ return candidate;
+ }
+ }
+ throw new IllegalArgumentException("Unknown unit " + chronoUnit);
+ }
+
+ public static Unit fromSuffix(String suffix) {
+ for (Unit candidate : values()) {
+ if (candidate.suffix.equalsIgnoreCase(suffix)) {
+ return candidate;
+ }
+ }
+ throw new IllegalArgumentException("Unknown unit '" + suffix + "'");
+ }
+ }
+}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java
index 29b5756c1..5549260f6 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java
@@ -30,6 +30,7 @@ import java.lang.annotation.Target;
* @author Thomas Darimont
* @author Christoph Strobl
* @author Jordi Llach
+ * @author Mark Paluch
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@@ -136,27 +137,32 @@ public @interface Indexed {
int expireAfterSeconds() default -1;
/**
- * Alternative for {@link #expireAfterSeconds()} to configure the timeout after which the collection should expire.
- * Defaults to an empty String for no expiry. Accepts numeric values followed by their unit of measure (d(ays),
- * h(ours), m(inutes), s(seconds)) or a Spring {@literal template expression}. The expression can result in a a valid
- * expiration {@link String} following the conventions already mentioned or a {@link java.time.Duration}.
+ * Alternative for {@link #expireAfterSeconds()} to configure the timeout after which the document should expire.
+ * Defaults to an empty {@link String} for no expiry. Accepts numeric values followed by their unit of measure:
+ *
+ * d : Days
+ * h : Hours
+ * m : Minutes
+ * s : Seconds
+ * Alternatively: A Spring {@literal template expression}. The expression can result in a
+ * {@link java.time.Duration} or a valid expiration {@link String} according to the already mentioned
+ * conventions.
+ *
+ * Supports ISO-8601 style.
*
- *
- *
+ *
*
- * @Indexed(expireAfter = "10s")
- * String expireAfterTenSeconds;
+ * @Indexed(expireAfter = "10s") String expireAfterTenSeconds;
*
- * @Indexed(expireAfter = "1d")
- * String expireAfterOneDay;
+ * @Indexed(expireAfter = "1d") String expireAfterOneDay;
*
- * @Indexed(expireAfter = "#{@mySpringBean.timeout}")
- * String expireAfterTimeoutObtainedFromSpringBean;
- *
+ * @Indexed(expireAfter = "P2D") String expireAfterTwoDays;
+ *
+ * @Indexed(expireAfter = "#{@mySpringBean.timeout}") String expireAfterTimeoutObtainedFromSpringBean;
*
*
- * @return {@literal 0s} by default.
+ * @return empty by default.
* @since 2.2
*/
- String expireAfter() default "0s";
+ String expireAfter() default "";
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java
index fdcdd5d2e..041241c0f 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java
@@ -29,12 +29,11 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Sort;
import org.springframework.data.mapping.Association;
@@ -62,7 +61,6 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
-import org.springframework.util.NumberUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -81,7 +79,6 @@ import org.springframework.util.StringUtils;
public class MongoPersistentEntityIndexResolver implements IndexResolver {
private static final Logger LOGGER = LoggerFactory.getLogger(MongoPersistentEntityIndexResolver.class);
- private static final Pattern TIMEOUT_PATTERN = Pattern.compile("(\\d+)(\\W+)?([dhms])");
private static final SpelExpressionParser PARSER = new SpelExpressionParser();
private final MongoMappingContext mappingContext;
@@ -353,7 +350,6 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
return indexDefinitions;
}
- @SuppressWarnings("deprecation")
protected IndexDefinitionHolder createCompoundIndexDefinition(String dotPath, String collection, CompoundIndex index,
MongoPersistentEntity> entity) {
@@ -390,8 +386,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
return new org.bson.Document(dotPath, 1);
}
- Object keyDefToUse = evaluatePotentialTemplateExpression(keyDefinitionString,
- getEvaluationContextForProperty(entity));
+ Object keyDefToUse = evaluate(keyDefinitionString, getEvaluationContextForProperty(entity));
org.bson.Document dbo = (keyDefToUse instanceof org.bson.Document) ? (org.bson.Document) keyDefToUse
: org.bson.Document.parse(ObjectUtils.nullSafeToString(keyDefToUse));
@@ -450,11 +445,11 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
indexDefinition.expire(index.expireAfterSeconds(), TimeUnit.SECONDS);
}
- if (!index.expireAfter().isEmpty() && !index.expireAfter().equals("0s")) {
+ if (StringUtils.hasText(index.expireAfter())) {
if (index.expireAfterSeconds() >= 0) {
throw new IllegalStateException(String.format(
- "@Indexed already defines an expiration timeout of %s sec. via Indexed#expireAfterSeconds. Please make to use either expireAfterSeconds or expireAfter.",
+ "@Indexed already defines an expiration timeout of %s seconds via Indexed#expireAfterSeconds. Please make to use either expireAfterSeconds or expireAfter.",
index.expireAfterSeconds()));
}
@@ -480,7 +475,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
/**
* Get the {@link EvaluationContext} for a given {@link PersistentEntity entity} the default one.
- *
+ *
* @param persistentEntity can be {@literal null}
* @return
*/
@@ -546,10 +541,15 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
private String pathAwareIndexName(String indexName, String dotPath, @Nullable PersistentEntity, ?> entity,
@Nullable MongoPersistentProperty property) {
- String nameToUse = StringUtils.hasText(indexName)
- ? ObjectUtils
- .nullSafeToString(evaluatePotentialTemplateExpression(indexName, getEvaluationContextForProperty(entity)))
- : "";
+ String nameToUse = "";
+ if (StringUtils.hasText(indexName)) {
+
+ Object result = evaluate(indexName, getEvaluationContextForProperty(entity));
+
+ if (result != null) {
+ nameToUse = ObjectUtils.nullSafeToString(result);
+ }
+ }
if (!StringUtils.hasText(dotPath) || (property != null && dotPath.equals(property.getFieldName()))) {
return StringUtils.hasText(nameToUse) ? nameToUse : dotPath;
@@ -607,7 +607,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
*/
private static Duration computeIndexTimeout(String timeoutValue, EvaluationContext evaluationContext) {
- Object evaluatedTimeout = evaluatePotentialTemplateExpression(timeoutValue, evaluationContext);
+ Object evaluatedTimeout = evaluate(timeoutValue, evaluationContext);
if (evaluatedTimeout == null) {
return Duration.ZERO;
@@ -623,30 +623,11 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
return Duration.ZERO;
}
- Matcher matcher = TIMEOUT_PATTERN.matcher(val);
- if (matcher.find()) {
-
- Long timeout = NumberUtils.parseNumber(matcher.group(1), Long.class);
- String unit = matcher.group(3);
-
- switch (unit) {
- case "d":
- return Duration.ofDays(timeout);
- case "h":
- return Duration.ofHours(timeout);
- case "m":
- return Duration.ofMinutes(timeout);
- case "s":
- return Duration.ofSeconds(timeout);
- }
- }
-
- throw new IllegalArgumentException(
- String.format("Index timeout %s cannot be parsed. Please use the following pattern '\\d+\\W?[dhms]'.", val));
+ return DurationStyle.detectAndParse(val);
}
@Nullable
- private static Object evaluatePotentialTemplateExpression(String value, EvaluationContext evaluationContext) {
+ private static Object evaluate(String value, EvaluationContext evaluationContext) {
Expression expression = PARSER.parseExpression(value, ParserContext.TEMPLATE_EXPRESSION);
if (expression instanceof LiteralExpression) {
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java
index 76fc212f9..e2c8fe522 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java
@@ -15,8 +15,7 @@
*/
package org.springframework.data.mongodb.core.index;
-import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.*;
+import static org.springframework.data.mongodb.test.util.Assertions.*;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@@ -32,6 +31,7 @@ import java.util.Optional;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -46,7 +46,6 @@ import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
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.test.util.Assertions;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -99,7 +98,7 @@ public class IndexingIntegrationTests {
operations.getConverter().getMappingContext().getPersistentEntity(IndexedPerson.class);
- assertThat(hasIndex("_firstname", IndexedPerson.class), is(true));
+ assertThat(hasIndex("_firstname", IndexedPerson.class)).isTrue();
}
@Test // DATAMONGO-2188
@@ -114,7 +113,7 @@ public class IndexingIntegrationTests {
template.getConverter().getMappingContext().getPersistentEntity(IndexedPerson.class);
- assertThat(hasIndex("_firstname", MongoCollectionUtils.getPreferredCollectionName(IndexedPerson.class)), is(false));
+ assertThat(hasIndex("_firstname", MongoCollectionUtils.getPreferredCollectionName(IndexedPerson.class))).isFalse();
}
@Test // DATAMONGO-1163
@@ -123,7 +122,7 @@ public class IndexingIntegrationTests {
operations.getConverter().getMappingContext().getPersistentEntity(IndexedPerson.class);
- assertThat(hasIndex("_lastname", IndexedPerson.class), is(true));
+ assertThat(hasIndex("_lastname", IndexedPerson.class)).isTrue();
}
@Test // DATAMONGO-2112
@@ -140,8 +139,8 @@ public class IndexingIntegrationTests {
.findFirst();
});
- Assertions.assertThat(indexInfo).isPresent();
- Assertions.assertThat(indexInfo.get()).containsEntry("expireAfterSeconds", 11L);
+ assertThat(indexInfo).isPresent();
+ assertThat(indexInfo.get()).containsEntry("expireAfterSeconds", 11L);
}
@Target({ ElementType.FIELD })
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java
index 1b35616c0..7bac84fe0 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java
@@ -15,10 +15,8 @@
*/
package org.springframework.data.mongodb.core.index;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
-import static org.springframework.data.mongodb.test.util.IsBsonObject.*;
+import static org.springframework.data.mongodb.test.util.Assertions.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -27,11 +25,11 @@ import java.lang.annotation.Target;
import java.util.Collections;
import java.util.List;
-import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
+
import org.springframework.core.annotation.AliasFor;
import org.springframework.data.annotation.Id;
import org.springframework.data.geo.Point;
@@ -53,12 +51,15 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.util.ClassTypeInformation;
/**
+ * Tests for {@link MongoPersistentEntityIndexResolver}.
+ *
* @author Christoph Strobl
* @author Mark Paluch
*/
@RunWith(Suite.class)
@SuiteClasses({ IndexResolutionTests.class, GeoSpatialIndexResolutionTests.class, CompoundIndexResolutionTests.class,
TextIndexedResolutionTests.class, MixedIndexResolutionTests.class })
+@SuppressWarnings("unused")
public class MongoPersistentEntityIndexResolverUnitTests {
/**
@@ -75,7 +76,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
IndexOnLevelZero.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection("indexedProperty", "Zero", indexDefinitions.get(0));
}
@@ -84,7 +85,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(IndexOnLevelOne.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection("zero.indexedProperty", "One", indexDefinitions.get(0));
}
@@ -95,7 +96,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
IndexResolver indexResolver = IndexResolver.create(mappingContext);
Iterable extends IndexDefinition> definitions = indexResolver.resolveIndexFor(IndexOnLevelOne.class);
- assertThat(definitions.iterator().hasNext(), is(true));
+ assertThat(definitions).isNotEmpty();
}
@Test // DATAMONGO-899
@@ -103,7 +104,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(IndexOnLevelTwo.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection("one.zero.indexedProperty", "Two", indexDefinitions.get(0));
}
@@ -113,7 +114,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
IndexOnLevelOneWithExplicitlyNamedField.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection("customZero.customFieldName", "indexOnLevelOneWithExplicitlyNamedField",
indexDefinitions.get(0));
}
@@ -125,7 +126,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
IndexOnLevelZero.class);
IndexDefinition indexDefinition = indexDefinitions.get(0).getIndexDefinition();
- assertThat(indexDefinition.getIndexOptions(), equalTo(new org.bson.Document().append("name", "indexedProperty")));
+ assertThat(indexDefinition.getIndexOptions()).isEqualTo(new org.bson.Document("name", "indexedProperty"));
}
@Test // DATAMONGO-899
@@ -135,8 +136,8 @@ public class MongoPersistentEntityIndexResolverUnitTests {
WithOptionsOnIndexedProperty.class);
IndexDefinition indexDefinition = indexDefinitions.get(0).getIndexDefinition();
- assertThat(indexDefinition.getIndexOptions(), equalTo(new org.bson.Document().append("name", "indexedProperty")
- .append("unique", true).append("sparse", true).append("background", true).append("expireAfterSeconds", 10L)));
+ assertThat(indexDefinition.getIndexOptions()).isEqualTo(new org.bson.Document().append("name", "indexedProperty")
+ .append("unique", true).append("sparse", true).append("background", true).append("expireAfterSeconds", 10L));
}
@Test // DATAMONGO-1297
@@ -144,9 +145,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(WithDbRef.class);
- assertThat(indexDefinitions, hasSize(1));
- assertThat(indexDefinitions.get(0).getCollection(), equalTo("withDbRef"));
- assertThat(indexDefinitions.get(0).getIndexKeys(), equalTo(new org.bson.Document().append("indexedDbRef", 1)));
+ assertThat(indexDefinitions).hasSize(1);
+ assertThat(indexDefinitions.get(0).getCollection()).isEqualTo("withDbRef");
+ assertThat(indexDefinitions.get(0).getIndexKeys()).isEqualTo(new org.bson.Document("indexedDbRef", 1));
}
@Test // DATAMONGO-1297
@@ -155,10 +156,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
WrapperOfWithDbRef.class);
- assertThat(indexDefinitions, hasSize(1));
- assertThat(indexDefinitions.get(0).getCollection(), equalTo("wrapperOfWithDbRef"));
- assertThat(indexDefinitions.get(0).getIndexKeys(),
- equalTo(new org.bson.Document().append("nested.indexedDbRef", 1)));
+ assertThat(indexDefinitions).hasSize(1);
+ assertThat(indexDefinitions.get(0).getCollection()).isEqualTo("wrapperOfWithDbRef");
+ assertThat(indexDefinitions.get(0).getIndexKeys()).isEqualTo(new org.bson.Document("nested.indexedDbRef", 1));
}
@Test // DATAMONGO-1163
@@ -167,9 +167,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
IndexOnMetaAnnotatedField.class);
- assertThat(indexDefinitions, hasSize(1));
- assertThat(indexDefinitions.get(0).getCollection(), equalTo("indexOnMetaAnnotatedField"));
- assertThat(indexDefinitions.get(0).getIndexOptions(), equalTo(new org.bson.Document().append("name", "_name")));
+ assertThat(indexDefinitions).hasSize(1);
+ assertThat(indexDefinitions.get(0).getCollection()).isEqualTo("indexOnMetaAnnotatedField");
+ assertThat(indexDefinitions.get(0).getIndexOptions()).isEqualTo(new org.bson.Document("name", "_name"));
}
@Test // DATAMONGO-1373
@@ -178,13 +178,15 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
IndexedDocumentWithComposedAnnotations.class);
- assertThat(indexDefinitions, hasSize(2));
+ assertThat(indexDefinitions).hasSize(2);
IndexDefinitionHolder indexDefinitionHolder = indexDefinitions.get(1);
- assertThat(indexDefinitionHolder.getIndexKeys(), isBsonObject().containing("fieldWithMyIndexName", 1));
- assertThat(indexDefinitionHolder.getIndexOptions(),
- isBsonObject().containing("sparse", true).containing("unique", true).containing("name", "my_index_name"));
+ assertThat(indexDefinitionHolder.getIndexKeys()).containsEntry("fieldWithMyIndexName", 1);
+ assertThat(indexDefinitionHolder.getIndexOptions()) //
+ .containsEntry("sparse", true) //
+ .containsEntry("unique", true) //
+ .containsEntry("name", "my_index_name");
}
@Test // DATAMONGO-1373
@@ -193,13 +195,15 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
IndexedDocumentWithComposedAnnotations.class);
- assertThat(indexDefinitions, hasSize(2));
+ assertThat(indexDefinitions).hasSize(2);
IndexDefinitionHolder indexDefinitionHolder = indexDefinitions.get(0);
- assertThat(indexDefinitionHolder.getIndexKeys(), isBsonObject().containing("fieldWithDifferentIndexName", 1));
- assertThat(indexDefinitionHolder.getIndexOptions(),
- isBsonObject().containing("sparse", true).containing("name", "different_name").notContaining("unique"));
+ assertThat(indexDefinitionHolder.getIndexKeys()).containsEntry("fieldWithDifferentIndexName", 1);
+ assertThat(indexDefinitionHolder.getIndexOptions()) //
+ .containsEntry("sparse", true) //
+ .containsEntry("name", "different_name") //
+ .doesNotContainKey("unique");
}
@Test // DATAMONGO-2112
@@ -208,7 +212,16 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
WithExpireAfterAsPlainString.class);
- Assertions.assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("expireAfterSeconds", 600L);
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("expireAfterSeconds", 600L);
+ }
+
+ @Test // DATAMONGO-2112
+ public void shouldResolveTimeoutFromIso8601String() {
+
+ List indexDefinitions = prepareMappingContextAndResolveIndexForType(
+ WithIso8601Style.class);
+
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("expireAfterSeconds", 86400L);
}
@Test // DATAMONGO-2112
@@ -217,7 +230,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
WithExpireAfterAsExpression.class);
- Assertions.assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("expireAfterSeconds", 11L);
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("expireAfterSeconds", 11L);
}
@Test // DATAMONGO-2112
@@ -226,7 +239,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
WithExpireAfterAsExpressionResultingInDuration.class);
- Assertions.assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("expireAfterSeconds", 100L);
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("expireAfterSeconds", 100L);
}
@Test // DATAMONGO-2112
@@ -235,9 +248,8 @@ public class MongoPersistentEntityIndexResolverUnitTests {
MongoMappingContext mappingContext = prepareMappingContext(WithInvalidExpireAfter.class);
MongoPersistentEntityIndexResolver indexResolver = new MongoPersistentEntityIndexResolver(mappingContext);
- Assertions.assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> indexResolver
+ assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> indexResolver
.resolveIndexForEntity(mappingContext.getRequiredPersistentEntity(WithInvalidExpireAfter.class)));
-
}
@Test // DATAMONGO-2112
@@ -246,7 +258,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
MongoMappingContext mappingContext = prepareMappingContext(WithDuplicateExpiry.class);
MongoPersistentEntityIndexResolver indexResolver = new MongoPersistentEntityIndexResolver(mappingContext);
- Assertions.assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> indexResolver
+ assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> indexResolver
.resolveIndexForEntity(mappingContext.getRequiredPersistentEntity(WithDuplicateExpiry.class)));
}
@@ -256,7 +268,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
WithIndexNameAsExpression.class);
- Assertions.assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "my1st");
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "my1st");
}
@Document("Zero")
@@ -322,13 +334,13 @@ public class MongoPersistentEntityIndexResolverUnitTests {
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
@ComposedIndexedAnnotation(indexName = "different_name", beUnique = false)
- static @interface CustomIndexedAnnotation {
+ @interface CustomIndexedAnnotation {
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Indexed
- static @interface ComposedIndexedAnnotation {
+ @interface ComposedIndexedAnnotation {
@AliasFor(annotation = Indexed.class, attribute = "unique")
boolean beUnique() default true;
@@ -343,7 +355,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@org.springframework.data.mongodb.core.mapping.Field
- static @interface ComposedFieldAnnotation {
+ @interface ComposedFieldAnnotation {
@AliasFor(annotation = org.springframework.data.mongodb.core.mapping.Field.class, attribute = "value")
String name() default "_id";
@@ -354,6 +366,11 @@ public class MongoPersistentEntityIndexResolverUnitTests {
@Indexed(expireAfter = "10m") String withTimeout;
}
+ @Document
+ class WithIso8601Style {
+ @Indexed(expireAfter = "P1D") String withTimeout;
+ }
+
@Document
static class WithExpireAfterAsExpression {
@Indexed(expireAfter = "#{10 + 1 + 's'}") String withTimeout;
@@ -384,7 +401,6 @@ public class MongoPersistentEntityIndexResolverUnitTests {
@Retention(RetentionPolicy.RUNTIME)
@Indexed
@interface IndexedFieldAnnotation {
-
}
@Document
@@ -405,7 +421,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
GeoSpatialIndexOnLevelZero.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection("geoIndexedProperty", "Zero", indexDefinitions.get(0));
}
@@ -415,7 +431,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
GeoSpatialIndexOnLevelOne.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection("zero.geoIndexedProperty", "One", indexDefinitions.get(0));
}
@@ -425,7 +441,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
GeoSpatialIndexOnLevelTwo.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection("one.zero.geoIndexedProperty", "Two", indexDefinitions.get(0));
}
@@ -437,8 +453,8 @@ public class MongoPersistentEntityIndexResolverUnitTests {
IndexDefinition indexDefinition = indexDefinitions.get(0).getIndexDefinition();
- assertThat(indexDefinition.getIndexOptions(), equalTo(
- new org.bson.Document().append("name", "location").append("min", 1).append("max", 100).append("bits", 2)));
+ assertThat(indexDefinition.getIndexOptions()).isEqualTo(
+ new org.bson.Document().append("name", "location").append("min", 1).append("max", 100).append("bits", 2));
}
@Test // DATAMONGO-1373
@@ -449,10 +465,10 @@ public class MongoPersistentEntityIndexResolverUnitTests {
IndexDefinition indexDefinition = indexDefinitions.get(0).getIndexDefinition();
- assertThat(indexDefinition.getIndexKeys(),
- isBsonObject().containing("location", "geoHaystack").containing("What light?", 1));
- assertThat(indexDefinition.getIndexOptions(),
- isBsonObject().containing("name", "my_geo_index_name").containing("bucketSize", 2.0));
+ assertThat(indexDefinition.getIndexKeys()).containsEntry("location", "geoHaystack").containsEntry("What light?",
+ 1);
+ assertThat(indexDefinition.getIndexOptions()).containsEntry("name", "my_geo_index_name")
+ .containsEntry("bucketSize", 2.0);
}
@Test // DATAMONGO-2112
@@ -461,7 +477,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
GeoIndexWithNameAsExpression.class);
- Assertions.assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "my1st");
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "my1st");
}
@Document("Zero")
@@ -531,7 +547,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
CompoundIndexOnLevelZero.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection(new String[] { "foo", "bar" }, "CompoundIndexOnLevelZero", indexDefinitions.get(0));
}
@@ -542,9 +558,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
CompoundIndexOnLevelZero.class);
IndexDefinition indexDefinition = indexDefinitions.get(0).getIndexDefinition();
- assertThat(indexDefinition.getIndexOptions(), equalTo(new org.bson.Document().append("name", "compound_index")
- .append("unique", true).append("sparse", true).append("background", true)));
- assertThat(indexDefinition.getIndexKeys(), equalTo(new org.bson.Document().append("foo", 1).append("bar", -1)));
+ assertThat(indexDefinition.getIndexOptions()).isEqualTo(new org.bson.Document("name", "compound_index")
+ .append("unique", true).append("sparse", true).append("background", true));
+ assertThat(indexDefinition.getIndexKeys()).isEqualTo(new org.bson.Document().append("foo", 1).append("bar", -1));
}
@Test // DATAMONGO-909
@@ -554,9 +570,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
IndexDefinedOnSuperClass.class);
IndexDefinition indexDefinition = indexDefinitions.get(0).getIndexDefinition();
- assertThat(indexDefinition.getIndexOptions(), equalTo(new org.bson.Document().append("name", "compound_index")
- .append("unique", true).append("sparse", true).append("background", true)));
- assertThat(indexDefinition.getIndexKeys(), equalTo(new org.bson.Document().append("foo", 1).append("bar", -1)));
+ assertThat(indexDefinition.getIndexOptions()).isEqualTo(new org.bson.Document().append("name", "compound_index")
+ .append("unique", true).append("sparse", true).append("background", true));
+ assertThat(indexDefinition.getIndexKeys()).isEqualTo(new org.bson.Document().append("foo", 1).append("bar", -1));
}
@Test // DATAMONGO-827
@@ -566,9 +582,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
ComountIndexWithAutogeneratedName.class);
IndexDefinition indexDefinition = indexDefinitions.get(0).getIndexDefinition();
- assertThat(indexDefinition.getIndexOptions(),
- equalTo(new org.bson.Document().append("unique", true).append("sparse", true).append("background", true)));
- assertThat(indexDefinition.getIndexKeys(), equalTo(new org.bson.Document().append("foo", 1).append("bar", -1)));
+ assertThat(indexDefinition.getIndexOptions())
+ .isEqualTo(new org.bson.Document().append("unique", true).append("sparse", true).append("background", true));
+ assertThat(indexDefinition.getIndexKeys()).isEqualTo(new org.bson.Document().append("foo", 1).append("bar", -1));
}
@Test // DATAMONGO-929
@@ -577,7 +593,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
CompoundIndexOnLevelOne.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection(new String[] { "zero.foo", "zero.bar" }, "CompoundIndexOnLevelOne",
indexDefinitions.get(0));
}
@@ -588,7 +604,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
CompoundIndexOnLevelOneWithEmptyIndexDefinition.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection(new String[] { "zero" }, "CompoundIndexOnLevelZeroWithEmptyIndexDef",
indexDefinitions.get(0));
}
@@ -599,7 +615,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
SingleCompoundIndex.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection(new String[] { "foo", "bar" }, "CompoundIndexOnLevelZero", indexDefinitions.get(0));
}
@@ -609,10 +625,10 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
CompoundIndexDocumentWithComposedAnnotation.class);
- assertThat(indexDefinitions, hasSize(1));
- assertThat(indexDefinitions.get(0).getIndexKeys(), isBsonObject().containing("foo", 1).containing("bar", -1));
- assertThat(indexDefinitions.get(0).getIndexOptions(), isBsonObject().containing("name", "my_compound_index_name")
- .containing("unique", true).containing("background", true));
+ assertThat(indexDefinitions).hasSize(1);
+ assertThat(indexDefinitions.get(0).getIndexKeys()).containsEntry("foo", 1).containsEntry("bar", -1);
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "my_compound_index_name")
+ .containsEntry("unique", true).containsEntry("background", true);
}
@Test // DATAMONGO-2112
@@ -621,7 +637,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
CompoundIndexWithNameExpression.class);
- Assertions.assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "cmp2name");
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "cmp2name");
}
@Test // DATAMONGO-2112
@@ -630,7 +646,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
CompoundIndexWithDefExpression.class);
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection(new String[] { "foo", "bar" }, "compoundIndexWithDefExpression",
indexDefinitions.get(0));
}
@@ -660,22 +676,16 @@ public class MongoPersistentEntityIndexResolverUnitTests {
unique = true)
static class SingleCompoundIndex {}
- static class IndexDefinedOnSuperClass extends CompoundIndexOnLevelZero {
-
- }
+ static class IndexDefinedOnSuperClass extends CompoundIndexOnLevelZero {}
@Document("ComountIndexWithAutogeneratedName")
@CompoundIndexes({ @CompoundIndex(useGeneratedName = true, def = "{'foo': 1, 'bar': -1}", background = true,
sparse = true, unique = true) })
- static class ComountIndexWithAutogeneratedName {
-
- }
+ static class ComountIndexWithAutogeneratedName {}
@Document("WithComposedAnnotation")
@ComposedCompoundIndex
- static class CompoundIndexDocumentWithComposedAnnotation {
-
- }
+ static class CompoundIndexDocumentWithComposedAnnotation {}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
@@ -716,7 +726,8 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
TextIndexOnSinglePropertyInRoot.class);
- assertThat(indexDefinitions.size(), equalTo(1));
+
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection("bar", "textIndexOnSinglePropertyInRoot", indexDefinitions.get(0));
}
@@ -725,7 +736,8 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
TextIndexOnMutiplePropertiesInRoot.class);
- assertThat(indexDefinitions.size(), equalTo(1));
+
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection(new String[] { "foo", "bar" }, "textIndexOnMutiplePropertiesInRoot",
indexDefinitions.get(0));
}
@@ -735,7 +747,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
TextIndexOnNestedRoot.class);
- assertThat(indexDefinitions.size(), equalTo(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection(new String[] { "nested.foo" }, "textIndexOnNestedRoot", indexDefinitions.get(0));
}
@@ -744,12 +756,12 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
TextIndexOnNestedWithWeightRoot.class);
- assertThat(indexDefinitions.size(), equalTo(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection(new String[] { "nested.foo" }, "textIndexOnNestedWithWeightRoot",
indexDefinitions.get(0));
org.bson.Document weights = DocumentTestUtils.getAsDocument(indexDefinitions.get(0).getIndexOptions(), "weights");
- assertThat(weights.get("nested.foo"), is((Object) 5F));
+ assertThat(weights.get("nested.foo")).isEqualTo(5F);
}
@Test // DATAMONGO-937
@@ -757,13 +769,13 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
TextIndexOnNestedWithMostSpecificValueRoot.class);
- assertThat(indexDefinitions.size(), equalTo(1));
+ assertThat(indexDefinitions).hasSize(1);
assertIndexPathAndCollection(new String[] { "nested.foo", "nested.bar" },
"textIndexOnNestedWithMostSpecificValueRoot", indexDefinitions.get(0));
org.bson.Document weights = DocumentTestUtils.getAsDocument(indexDefinitions.get(0).getIndexOptions(), "weights");
- assertThat(weights.get("nested.foo"), is((Object) 5F));
- assertThat(weights.get("nested.bar"), is((Object) 10F));
+ assertThat(weights.get("nested.foo")).isEqualTo(5F);
+ assertThat(weights.get("nested.bar")).isEqualTo(10F);
}
@Test // DATAMONGO-937
@@ -771,7 +783,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
DocumentWithDefaultLanguage.class);
- assertThat(indexDefinitions.get(0).getIndexOptions().get("default_language"), is((Object) "spanish"));
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("default_language", "spanish");
}
@Test // DATAMONGO-937, DATAMONGO-1049
@@ -779,7 +791,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
DocumentWithLanguageOverride.class);
- assertThat(indexDefinitions.get(0).getIndexOptions().get("language_override"), is((Object) "lang"));
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("language_override", "lang");
}
@Test // DATAMONGO-1049
@@ -787,7 +799,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
DocumentWithLanguageOverrideOnNestedElement.class);
- assertThat(indexDefinitions.get(0).getIndexOptions().get("language_override"), is(nullValue()));
+ assertThat(indexDefinitions.get(0).getIndexOptions().get("language_override")).isNull();
}
@Test // DATAMONGO-1049
@@ -795,7 +807,8 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
DocumentWithNoTextIndexPropertyButReservedFieldLanguage.class);
- assertThat(indexDefinitions, is(empty()));
+
+ assertThat(indexDefinitions).isEmpty();
}
@Test // DATAMONGO-1049
@@ -803,7 +816,8 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
DocumentWithNoTextIndexPropertyButReservedFieldLanguageAnnotated.class);
- assertThat(indexDefinitions, is(empty()));
+
+ assertThat(indexDefinitions).isEmpty();
}
@Test // DATAMONGO-1049
@@ -811,7 +825,8 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
DocumentWithOverlappingLanguageProps.class);
- assertThat(indexDefinitions.get(0).getIndexOptions().get("language_override"), is((Object) "lang"));
+
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("language_override", "lang");
}
@Test // DATAMONGO-1373
@@ -821,7 +836,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
TextIndexedDocumentWithComposedAnnotation.class);
org.bson.Document weights = DocumentTestUtils.getAsDocument(indexDefinitions.get(0).getIndexOptions(), "weights");
- assertThat(weights, isBsonObject().containing("foo", 99f));
+ assertThat(weights).containsEntry("foo", 99f);
}
@Document
@@ -919,7 +934,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@TextIndexed
- static @interface ComposedTextIndexedAnnotation {
+ @interface ComposedTextIndexedAnnotation {
@AliasFor(annotation = TextIndexed.class, attribute = "weight")
float heavyweight() default 99f;
@@ -933,25 +948,27 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(MixedIndexRoot.class);
- assertThat(indexDefinitions, hasSize(2));
- assertThat(indexDefinitions.get(0).getIndexDefinition(), instanceOf(Index.class));
- assertThat(indexDefinitions.get(1).getIndexDefinition(), instanceOf(GeospatialIndex.class));
+ assertThat(indexDefinitions).hasSize(2);
+ assertThat(indexDefinitions.get(0).getIndexDefinition()).isInstanceOf(Index.class);
+ assertThat(indexDefinitions.get(1).getIndexDefinition()).isInstanceOf(GeospatialIndex.class);
}
@Test // DATAMONGO-899
public void cyclicPropertyReferenceOverDBRefShouldNotBeTraversed() {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(Inner.class);
- assertThat(indexDefinitions, hasSize(1));
- assertThat(indexDefinitions.get(0).getIndexDefinition().getIndexKeys(),
- equalTo(new org.bson.Document().append("outer", 1)));
+
+ assertThat(indexDefinitions).hasSize(1);
+ assertThat(indexDefinitions.get(0).getIndexDefinition().getIndexKeys())
+ .isEqualTo(new org.bson.Document().append("outer", 1));
}
@Test // DATAMONGO-899
public void associationsShouldNotBeTraversed() {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(Outer.class);
- assertThat(indexDefinitions, empty());
+
+ assertThat(indexDefinitions).isEmpty();
}
@Test // DATAMONGO-926
@@ -959,7 +976,8 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
CycleStartingInBetween.class);
- assertThat(indexDefinitions, hasSize(1));
+
+ assertThat(indexDefinitions).hasSize(1);
}
@Test // DATAMONGO-926
@@ -968,7 +986,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(CycleLevelZero.class);
assertIndexPathAndCollection("indexedProperty", "cycleLevelZero", indexDefinitions.get(0));
assertIndexPathAndCollection("cyclicReference.indexedProperty", "cycleLevelZero", indexDefinitions.get(1));
- assertThat(indexDefinitions, hasSize(2));
+ assertThat(indexDefinitions).hasSize(2);
}
@Test // DATAMONGO-926
@@ -976,7 +994,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(CycleOnLevelOne.class);
assertIndexPathAndCollection("reference.indexedProperty", "cycleOnLevelOne", indexDefinitions.get(0));
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
}
@Test // DATAMONGO-926
@@ -984,11 +1002,12 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
NoCycleButIdenticallyNamedProperties.class);
+
+ assertThat(indexDefinitions).hasSize(3);
assertIndexPathAndCollection("foo", "noCycleButIdenticallyNamedProperties", indexDefinitions.get(0));
assertIndexPathAndCollection("reference.foo", "noCycleButIdenticallyNamedProperties", indexDefinitions.get(1));
assertIndexPathAndCollection("reference.deep.foo", "noCycleButIdenticallyNamedProperties",
indexDefinitions.get(2));
- assertThat(indexDefinitions, hasSize(3));
}
@Test // DATAMONGO-949
@@ -997,7 +1016,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
SimilarityHolingBean.class);
assertIndexPathAndCollection("norm", "similarityHolingBean", indexDefinitions.get(0));
- assertThat(indexDefinitions, hasSize(1));
+ assertThat(indexDefinitions).hasSize(1);
}
@Test // DATAMONGO-962
@@ -1005,7 +1024,8 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
SelfCyclingViaCollectionType.class);
- assertThat(indexDefinitions, empty());
+
+ assertThat(indexDefinitions).isEmpty();
}
@Test // DATAMONGO-962
@@ -1013,14 +1033,15 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
MultipleObjectsOfSameType.class);
- assertThat(indexDefinitions, empty());
+
+ assertThat(indexDefinitions).isEmpty();
}
@Test // DATAMONGO-962
@SuppressWarnings({ "rawtypes", "unchecked" })
public void shouldCatchCyclicReferenceExceptionOnRoot() {
- MongoPersistentEntity entity = new BasicMongoPersistentEntity(ClassTypeInformation.from(Object.class));
+ MongoPersistentEntity entity = new BasicMongoPersistentEntity<>(ClassTypeInformation.from(Object.class));
MongoPersistentProperty propertyMock = mock(MongoPersistentProperty.class);
when(propertyMock.isEntity()).thenReturn(true);
@@ -1028,7 +1049,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
when(propertyMock.getActualType()).thenThrow(
new MongoPersistentEntityIndexResolver.CyclicPropertyReferenceException("foo", Object.class, "bar"));
- MongoPersistentEntity selfCyclingEntity = new BasicMongoPersistentEntity(
+ MongoPersistentEntity selfCyclingEntity = new BasicMongoPersistentEntity<>(
ClassTypeInformation.from(SelfCyclingViaCollectionType.class));
new MongoPersistentEntityIndexResolver(prepareMappingContext(SelfCyclingViaCollectionType.class))
@@ -1041,9 +1062,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
NoCycleManyPathsToDeepValueObject.class);
+ assertThat(indexDefinitions).hasSize(2);
assertIndexPathAndCollection("l3.valueObject.value", "rules", indexDefinitions.get(0));
assertIndexPathAndCollection("l2.l3.valueObject.value", "rules", indexDefinitions.get(1));
- assertThat(indexDefinitions, hasSize(2));
}
@Test // DATAMONGO-1025
@@ -1051,8 +1072,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
DocumentWithNestedDocumentHavingNamedCompoundIndex.class);
- assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"),
- equalTo("propertyOfTypeHavingNamedCompoundIndex.c_index"));
+
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name",
+ "propertyOfTypeHavingNamedCompoundIndex.c_index");
}
@Test // DATAMONGO-1025
@@ -1060,8 +1082,8 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
DocumentWithNestedTypeHavingNamedCompoundIndex.class);
- assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"),
- equalTo("propertyOfTypeHavingNamedCompoundIndex.c_index"));
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name",
+ "propertyOfTypeHavingNamedCompoundIndex.c_index");
}
@Test // DATAMONGO-1025
@@ -1069,8 +1091,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
DocumentWithNestedDocumentHavingNamedIndex.class);
- assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"),
- equalTo("propertyOfTypeHavingNamedIndex.property_index"));
+
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name",
+ "propertyOfTypeHavingNamedIndex.property_index");
}
@Test // DATAMONGO-1025
@@ -1078,8 +1101,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
DocumentWithNestedTypeHavingNamedIndex.class);
- assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"),
- equalTo("propertyOfTypeHavingNamedIndex.property_index"));
+
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name",
+ "propertyOfTypeHavingNamedIndex.property_index");
}
@Test // DATAMONGO-1025
@@ -1087,7 +1111,7 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
DocumentWithNamedIndex.class);
- assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"), equalTo("property_index"));
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "property_index");
}
@Test // DATAMONGO-1087
@@ -1096,9 +1120,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
MultiplePropertiesOfSameTypeWithMatchingStartLetters.class);
- assertThat(indexDefinitions, hasSize(2));
- assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"), equalTo("name.component"));
- assertThat((String) indexDefinitions.get(1).getIndexOptions().get("name"), equalTo("nameLast.component"));
+ assertThat(indexDefinitions).hasSize(2);
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "name.component");
+ assertThat(indexDefinitions.get(1).getIndexOptions()).containsEntry("name", "nameLast.component");
}
@Test // DATAMONGO-1087
@@ -1107,9 +1131,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
MultiplePropertiesOfSameTypeWithMatchingStartLettersOnNestedProperty.class);
- assertThat(indexDefinitions, hasSize(2));
- assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"), equalTo("component.nameLast"));
- assertThat((String) indexDefinitions.get(1).getIndexOptions().get("name"), equalTo("component.name"));
+ assertThat(indexDefinitions).hasSize(2);
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "component.nameLast");
+ assertThat(indexDefinitions.get(1).getIndexOptions()).containsEntry("name", "component.name");
}
@Test // DATAMONGO-1121
@@ -1118,11 +1142,10 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
OuterDocumentReferingToIndexedPropertyViaDifferentNonCyclingPaths.class);
- assertThat(indexDefinitions, hasSize(2));
- assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"), equalTo("path1.foo"));
- assertThat((String) indexDefinitions.get(1).getIndexOptions().get("name"),
- equalTo("path2.propertyWithIndexedStructure.foo"));
-
+ assertThat(indexDefinitions).hasSize(2);
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "path1.foo");
+ assertThat(indexDefinitions.get(1).getIndexOptions()).containsEntry("name",
+ "path2.propertyWithIndexedStructure.foo");
}
@Test // DATAMONGO-1263
@@ -1131,9 +1154,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
List indexDefinitions = prepareMappingContextAndResolveIndexForType(
EntityWithGenericTypeWrapperAsElement.class);
- assertThat(indexDefinitions, hasSize(1));
- assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"),
- equalTo("listWithGeneircTypeElement.entity.property_index"));
+ assertThat(indexDefinitions).hasSize(1);
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name",
+ "listWithGeneircTypeElement.entity.property_index");
}
@Document
@@ -1365,9 +1388,9 @@ public class MongoPersistentEntityIndexResolverUnitTests {
IndexDefinitionHolder holder) {
for (String expectedPath : expectedPaths) {
- assertThat(holder.getIndexDefinition().getIndexKeys().containsKey(expectedPath), equalTo(true));
+ assertThat(holder.getIndexDefinition().getIndexKeys()).containsKey(expectedPath);
}
- assertThat(holder.getCollection(), equalTo(expectedCollection));
+ assertThat(holder.getCollection()).isEqualTo(expectedCollection);
}
}
diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc
index 56d296206..a7098caa8 100644
--- a/src/main/asciidoc/new-features.adoc
+++ b/src/main/asciidoc/new-features.adoc
@@ -14,6 +14,7 @@
* Kotlin extension methods accepting `KClass` are deprecated now in favor of `reified` methods.
* Support of array filters in `Update` operations.
* <> from domain types.
+* SpEL support in for expressions in `@Indexed`.
[[new-features.2-1-0]]
== What's New in Spring Data MongoDB 2.1