Skip to content

Commit 42672a6

Browse files
committed
DATAMONGO-1518 - Polishing.
Rename ICULocale to CollationLocale. Introduce interface for ComparisonLevel construction and let ICUComparisonLevel types implement that interface. Make value types immutable where possible. Provide static instances for default comparison level instances. Replace collation conversion IndexConverters with Collation.from(…).toMongoCollation() converter. Introduce missing generic types. Replace Optional.get() with Optional.map(…).orElse(…). Update reference documentation. Original pull request: spring-projects#459.
1 parent 0b169d5 commit 42672a6

15 files changed

+460
-357
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/Collation.java

+250-169
Large diffs are not rendered by default.

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java

+28-23
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,33 @@
2424
*
2525
* @author Thomas Risberg
2626
* @author Christoph Strobl
27+
* @author Mark Paluch
2728
*/
2829
public class CollectionOptions {
2930

3031
private Integer maxDocuments;
3132
private Integer size;
3233
private Boolean capped;
33-
private Collation collation;
34+
private Optional<Collation> collation;
3435

3536
/**
3637
* Constructs a new <code>CollectionOptions</code> instance.
37-
*
38-
* @param size the collection size in bytes, this data space is preallocated
38+
*
39+
* @param size the collection size in bytes, this data space is preallocated.
3940
* @param maxDocuments the maximum number of documents in the collection.
4041
* @param capped true to created a "capped" collection (fixed size with auto-FIFO behavior based on insertion order),
4142
* false otherwise.
4243
*/
4344
public CollectionOptions(Integer size, Integer maxDocuments, Boolean capped) {
45+
this(size, maxDocuments, capped, Optional.empty());
46+
}
47+
48+
private CollectionOptions(Integer size, Integer maxDocuments, Boolean capped, Optional<Collation> collation) {
4449

4550
this.maxDocuments = maxDocuments;
4651
this.size = size;
4752
this.capped = capped;
53+
this.collation = collation;
4854
}
4955

5056
private CollectionOptions() {}
@@ -66,16 +72,24 @@ public static CollectionOptions just(Collation collation) {
6672
}
6773

6874
/**
69-
* Create new {@link CollectionOptions} with already given settings and capped set to {@literal true}.
75+
* Create new empty {@link CollectionOptions}.
7076
*
7177
* @return new {@link CollectionOptions}.
7278
* @since 2.0
7379
*/
74-
public CollectionOptions capped() {
80+
public static CollectionOptions empty() {
81+
return new CollectionOptions();
82+
}
7583

76-
CollectionOptions options = new CollectionOptions(size, maxDocuments, true);
77-
options.setCollation(collation);
78-
return options;
84+
/**
85+
* Create new {@link CollectionOptions} with already given settings and capped set to {@literal true}.
86+
*
87+
* @param size the collection size in bytes, this data space is preallocated.
88+
* @return new {@link CollectionOptions}.
89+
* @since 2.0
90+
*/
91+
public CollectionOptions capped(int size) {
92+
return new CollectionOptions(size, maxDocuments, true, collation);
7993
}
8094

8195
/**
@@ -86,10 +100,7 @@ public CollectionOptions capped() {
86100
* @since 2.0
87101
*/
88102
public CollectionOptions maxDocuments(Integer maxDocuments) {
89-
90-
CollectionOptions options = new CollectionOptions(size, maxDocuments, capped);
91-
options.setCollation(collation);
92-
return options;
103+
return new CollectionOptions(size, maxDocuments, capped, collation);
93104
}
94105

95106
/**
@@ -99,11 +110,8 @@ public CollectionOptions maxDocuments(Integer maxDocuments) {
99110
* @return new {@link CollectionOptions}.
100111
* @since 2.0
101112
*/
102-
public CollectionOptions size(Integer size) {
103-
104-
CollectionOptions options = new CollectionOptions(size, maxDocuments, capped);
105-
options.setCollation(collation);
106-
return options;
113+
public CollectionOptions size(int size) {
114+
return new CollectionOptions(size, maxDocuments, capped, collation);
107115
}
108116

109117
/**
@@ -114,10 +122,7 @@ public CollectionOptions size(Integer size) {
114122
* @since 2.0
115123
*/
116124
public CollectionOptions collation(Collation collation) {
117-
118-
CollectionOptions options = new CollectionOptions(size, maxDocuments, capped);
119-
options.setCollation(collation);
120-
return options;
125+
return new CollectionOptions(size, maxDocuments, capped, Optional.ofNullable(collation));
121126
}
122127

123128
public Integer getMaxDocuments() {
@@ -151,7 +156,7 @@ public void setCapped(Boolean capped) {
151156
* @since 2.0
152157
*/
153158
public void setCollation(Collation collation) {
154-
this.collation = collation;
159+
this.collation = Optional.ofNullable(collation);
155160
}
156161

157162
/**
@@ -161,6 +166,6 @@ public void setCollation(Collation collation) {
161166
* @since 2.0
162167
*/
163168
public Optional<Collation> getCollation() {
164-
return Optional.ofNullable(collation);
169+
return collation;
165170
}
166171
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndModifyOptions.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@
2424
*/
2525
public class FindAndModifyOptions {
2626

27-
boolean returnNew;
28-
boolean upsert;
29-
boolean remove;
27+
private boolean returnNew;
28+
private boolean upsert;
29+
private boolean remove;
3030

3131
private Collation collation;
3232

3333
/**
3434
* Static factory method to create a FindAndModifyOptions instance
35-
*
35+
*
3636
* @return a new instance
3737
*/
3838
public static FindAndModifyOptions options() {
@@ -46,9 +46,8 @@ public static FindAndModifyOptions options() {
4646
*/
4747
public static FindAndModifyOptions of(FindAndModifyOptions source) {
4848

49-
5049
FindAndModifyOptions options = new FindAndModifyOptions();
51-
if(source == null) {
50+
if (source == null) {
5251
return options;
5352
}
5453

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/IndexConverters.java

+2-34
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@
2525
import org.springframework.util.ObjectUtils;
2626

2727
import com.mongodb.client.model.Collation;
28-
import com.mongodb.client.model.CollationAlternate;
29-
import com.mongodb.client.model.CollationCaseFirst;
30-
import com.mongodb.client.model.CollationMaxVariable;
31-
import com.mongodb.client.model.CollationStrength;
3228
import com.mongodb.client.model.IndexOptions;
3329

3430
/**
@@ -129,39 +125,11 @@ public static Collation fromDocument(Document source) {
129125
return null;
130126
}
131127

132-
com.mongodb.client.model.Collation.Builder collationBuilder = Collation.builder();
133-
134-
collationBuilder.locale(source.getString("locale"));
135-
if (source.containsKey("caseLevel")) {
136-
collationBuilder.caseLevel(source.getBoolean("caseLevel"));
137-
}
138-
if (source.containsKey("caseFirst")) {
139-
collationBuilder.collationCaseFirst(CollationCaseFirst.fromString(source.getString("caseFirst")));
140-
}
141-
if (source.containsKey("strength")) {
142-
collationBuilder.collationStrength(CollationStrength.fromInt(source.getInteger("strength")));
143-
}
144-
if (source.containsKey("numericOrdering")) {
145-
collationBuilder.numericOrdering(source.getBoolean("numericOrdering"));
146-
}
147-
if (source.containsKey("alternate")) {
148-
collationBuilder.collationAlternate(CollationAlternate.fromString(source.getString("alternate")));
149-
}
150-
if (source.containsKey("maxVariable")) {
151-
collationBuilder.collationMaxVariable(CollationMaxVariable.fromString(source.getString("maxVariable")));
152-
}
153-
if (source.containsKey("backwards")) {
154-
collationBuilder.backwards(source.getBoolean("backwards"));
155-
}
156-
if (source.containsKey("normalization")) {
157-
collationBuilder.normalization(source.getBoolean("normalization"));
158-
}
159-
160-
return collationBuilder.build();
128+
return org.springframework.data.mongodb.core.Collation.from(source).toMongoCollation();
161129
}
162130

163131
private static Converter<Document, IndexInfo> getDocumentIndexInfoConverter() {
164-
return ix -> IndexInfo.indexInfoOf(ix);
132+
return IndexInfo::indexInfoOf;
165133
}
166134

167135
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

+24-39
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,8 @@
2020
import static org.springframework.data.util.Optionals.*;
2121

2222
import java.io.IOException;
23-
import java.util.ArrayList;
24-
import java.util.Collection;
25-
import java.util.Collections;
26-
import java.util.HashMap;
27-
import java.util.HashSet;
28-
import java.util.Iterator;
29-
import java.util.LinkedHashSet;
30-
import java.util.List;
31-
import java.util.Map;
23+
import java.util.*;
3224
import java.util.Map.Entry;
33-
import java.util.Optional;
34-
import java.util.Scanner;
35-
import java.util.Set;
3625
import java.util.concurrent.TimeUnit;
3726

3827
import org.bson.Document;
@@ -60,6 +49,7 @@
6049
import org.springframework.data.geo.GeoResult;
6150
import org.springframework.data.geo.GeoResults;
6251
import org.springframework.data.geo.Metric;
52+
import org.springframework.data.mapping.PersistentEntity;
6353
import org.springframework.data.mapping.PersistentPropertyAccessor;
6454
import org.springframework.data.mapping.context.MappingContext;
6555
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
@@ -722,7 +712,7 @@ public <T> T findAndModify(Query query, Update update, FindAndModifyOptions opti
722712

723713
Optionals.ifAllPresent(query.getCollation(), optionsToUse.getCollation(), (l, r) -> {
724714
throw new IllegalArgumentException(
725-
"Both Query and FindAndModifyOptions define the collation. Please provide the collation only via one of the two.");
715+
"Both Query and FindAndModifyOptions define a collation. Please provide the collation only via one of the two.");
726716
});
727717

728718
query.getCollation().ifPresent(optionsToUse::collation);
@@ -885,7 +875,7 @@ private void initializeVersionProperty(Object entity) {
885875

886876
Optional<? extends MongoPersistentEntity<?>> persistentEntity = getPersistentEntity(entity.getClass());
887877

888-
ifAllPresent(persistentEntity, persistentEntity.flatMap(it -> it.getVersionProperty()), (l, r) -> {
878+
ifAllPresent(persistentEntity, persistentEntity.flatMap(PersistentEntity::getVersionProperty), (l, r) -> {
889879
ConvertingPropertyAccessor accessor = new ConvertingPropertyAccessor(l.getPropertyAccessor(entity),
890880
mongoConverter.getConversionService());
891881
accessor.setProperty(r, Optional.of(0));
@@ -972,7 +962,7 @@ public void save(Object objectToSave, String collectionName) {
972962
Assert.hasText(collectionName, "Collection name must not be null or empty!");
973963

974964
Optional<? extends MongoPersistentEntity<?>> entity = getPersistentEntity(objectToSave.getClass());
975-
Optional<MongoPersistentProperty> versionProperty = entity.flatMap(it -> it.getVersionProperty());
965+
Optional<MongoPersistentProperty> versionProperty = entity.flatMap(PersistentEntity::getVersionProperty);
976966

977967
mapIfAllPresent(entity, versionProperty, //
978968
(l, r) -> doSaveVersioned(objectToSave, l, collectionName))//
@@ -1225,18 +1215,19 @@ public UpdateResult doInCollection(MongoCollection<Document> collection)
12251215
private void increaseVersionForUpdateIfNecessary(Optional<? extends MongoPersistentEntity<?>> persistentEntity,
12261216
Update update) {
12271217

1228-
ifAllPresent(persistentEntity, persistentEntity.flatMap(it -> it.getVersionProperty()), (entity, property) -> {
1229-
String versionFieldName = property.getFieldName();
1230-
if (!update.modifies(versionFieldName)) {
1231-
update.inc(versionFieldName, 1L);
1232-
}
1233-
});
1218+
ifAllPresent(persistentEntity, persistentEntity.flatMap(PersistentEntity::getVersionProperty),
1219+
(entity, property) -> {
1220+
String versionFieldName = property.getFieldName();
1221+
if (!update.modifies(versionFieldName)) {
1222+
update.inc(versionFieldName, 1L);
1223+
}
1224+
});
12341225
}
12351226

12361227
private boolean documentContainsVersionProperty(Document document,
12371228
Optional<? extends MongoPersistentEntity<?>> persistentEntity) {
12381229

1239-
return mapIfAllPresent(persistentEntity, persistentEntity.flatMap(it -> it.getVersionProperty()), //
1230+
return mapIfAllPresent(persistentEntity, persistentEntity.flatMap(PersistentEntity::getVersionProperty), //
12401231
(entity, property) -> document.containsKey(property.getFieldName()))//
12411232
.orElse(false);
12421233
}
@@ -1458,7 +1449,7 @@ public <T> MapReduceResults<T> mapReduce(Query query, String inputCollectionName
14581449

14591450
Optionals.ifAllPresent(collation, mapReduceOptions.getCollation(), (l, r) -> {
14601451
throw new IllegalArgumentException(
1461-
"Both Query and MapReduceOptions define the collation. Please provide the collation only via one of the two.");
1452+
"Both Query and MapReduceOptions define a collation. Please provide the collation only via one of the two.");
14621453
});
14631454

14641455
if (mapReduceOptions.getCollation().isPresent()) {
@@ -1482,9 +1473,7 @@ public <T> MapReduceResults<T> mapReduce(Query query, String inputCollectionName
14821473
}
14831474
}
14841475

1485-
if (collation.isPresent()) {
1486-
result = result.collation(collation.map(Collation::toMongoCollation).get());
1487-
}
1476+
result = collation.map(Collation::toMongoCollation).map(result::collation).orElse(result);
14881477

14891478
List<T> mappedResults = new ArrayList<T>();
14901479
DocumentCallback<T> callback = new ReadDocumentCallback<T>(mongoConverter, entityClass, inputCollectionName);
@@ -2297,7 +2286,7 @@ public Document doInCollection(MongoCollection<Document> collection) throws Mong
22972286
if (LOGGER.isDebugEnabled()) {
22982287

22992288
LOGGER.debug("findOne using query: {} fields: {} in db.collection: {}", serializeToJsonSafely(query),
2300-
serializeToJsonSafely(fields.orElseGet(() -> new Document())), collection.getNamespace().getFullName());
2289+
serializeToJsonSafely(fields.orElseGet(Document::new)), collection.getNamespace().getFullName());
23012290
}
23022291

23032292
if (fields.isPresent()) {
@@ -2336,11 +2325,7 @@ public FindIterable<Document> doInCollection(MongoCollection<Document> collectio
23362325

23372326
FindIterable<Document> iterable = collection.find(query);
23382327

2339-
if (fields.filter(val -> !val.isEmpty()).isPresent()) {
2340-
iterable = iterable.projection(fields.get());
2341-
}
2342-
2343-
return iterable;
2328+
return fields.filter(val -> !val.isEmpty()).map(iterable::projection).orElse(iterable);
23442329
}
23452330
}
23462331

@@ -2399,7 +2384,7 @@ public Document doInCollection(MongoCollection<Document> collection) throws Mong
23992384
opts.upsert(true);
24002385
}
24012386
opts.projection(fields);
2402-
if (options.returnNew) {
2387+
if (options.isReturnNew()) {
24032388
opts.returnDocument(ReturnDocument.AFTER);
24042389
}
24052390

@@ -2506,16 +2491,16 @@ public FindIterable<Document> prepare(FindIterable<Document> cursor) {
25062491
return cursor;
25072492
}
25082493

2509-
if (query.getSkip() <= 0 && query.getLimit() <= 0 && query.getSortObject() == null
2510-
&& !StringUtils.hasText(query.getHint()) && !query.getMeta().hasValues()) {
2494+
if (query.getSkip() <= 0 && query.getLimit() <= 0
2495+
&& (query.getSortObject() == null || query.getSortObject().isEmpty()) && !StringUtils.hasText(query.getHint())
2496+
&& !query.getMeta().hasValues() && !query.getCollation().isPresent()) {
25112497
return cursor;
25122498
}
25132499

2514-
FindIterable<Document> cursorToUse = cursor;
2500+
FindIterable<Document> cursorToUse;
2501+
2502+
cursorToUse = query.getCollation().map(Collation::toMongoCollation).map(cursor::collation).orElse(cursor);
25152503

2516-
if (query.getCollation().isPresent()) {
2517-
cursorToUse = cursorToUse.collation(query.getCollation().map(val -> val.toMongoCollation()).get());
2518-
}
25192504
try {
25202505
if (query.getSkip() > 0) {
25212506
cursorToUse = cursorToUse.skip((int) query.getSkip());

0 commit comments

Comments
 (0)