Skip to content

Commit 5cca849

Browse files
committed
DATAMONGO-1761 - Polishing.
Refactor MongoConverter.mapValueToTargetType to imperative method instead of returning a function for easier consumption. Adapt return types in Javadoc to the actual return type. Remove undocumented type parameters. Add overload using reified entity and return type generics. Slight documentation tweaks. Original pull request: spring-projects#494. Related pull request: spring-projects#514.
1 parent 45fa1e5 commit 5cca849

20 files changed

+251
-164
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/CodecRegistryProvider.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017 the original author or authors.
2+
* Copyright 2017-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,9 +23,13 @@
2323
import org.springframework.util.Assert;
2424

2525
/**
26+
* Provider interface to obtain {@link CodecRegistry} from the underlying MongoDB Java driver.
27+
*
2628
* @author Christoph Strobl
29+
* @author Mark Paluch
2730
* @since 2.1
2831
*/
32+
@FunctionalInterface
2933
public interface CodecRegistryProvider {
3034

3135
/**
@@ -50,7 +54,7 @@ default boolean hasCodecFor(Class<?> type) {
5054
/**
5155
* Get the {@link Codec} registered for the given {@literal type} or an {@link Optional#empty() empty Optional}
5256
* instead.
53-
*
57+
*
5458
* @param type must not be {@literal null}.
5559
* @param <T>
5660
* @return never {@literal null}.

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDbFactory.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2013 the original author or authors.
2+
* Copyright 2011-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,23 +25,24 @@
2525

2626
/**
2727
* Interface for factories creating {@link DB} instances.
28-
*
28+
*
2929
* @author Mark Pollack
3030
* @author Thomas Darimont
31+
* @author Christoph Strobl
3132
*/
3233
public interface MongoDbFactory extends CodecRegistryProvider {
3334

3435
/**
3536
* Creates a default {@link DB} instance.
36-
*
37+
*
3738
* @return
3839
* @throws DataAccessException
3940
*/
4041
MongoDatabase getDb() throws DataAccessException;
4142

4243
/**
4344
* Creates a {@link DB} instance to access the database with the given name.
44-
*
45+
*
4546
* @param dbName must not be {@literal null} or empty.
4647
* @return
4748
* @throws DataAccessException
@@ -50,13 +51,18 @@ public interface MongoDbFactory extends CodecRegistryProvider {
5051

5152
/**
5253
* Exposes a shared {@link MongoExceptionTranslator}.
53-
*
54+
*
5455
* @return will never be {@literal null}.
5556
*/
5657
PersistenceExceptionTranslator getExceptionTranslator();
5758

5859
DB getLegacyDb();
5960

61+
/**
62+
* Get the underlying {@link CodecRegistry} used by the MongoDB Java driver.
63+
*
64+
* @return never {@literal null}.
65+
*/
6066
@Override
6167
default CodecRegistry getCodecRegistry() {
6268
return getDb().getCodecRegistry();

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseFactory.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 the original author or authors.
2+
* Copyright 2016-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -56,6 +56,11 @@ public interface ReactiveMongoDatabaseFactory extends CodecRegistryProvider {
5656
*/
5757
PersistenceExceptionTranslator getExceptionTranslator();
5858

59+
/**
60+
* Get the underlying {@link CodecRegistry} used by the reactive MongoDB Java driver.
61+
*
62+
* @return never {@literal null}.
63+
*/
5964
@Override
6065
default CodecRegistry getCodecRegistry() {
6166
return getMongoDatabase().getCodecRegistry();

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017 the original author or authors.
2+
* Copyright 2017-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -258,7 +258,7 @@ interface DistinctWithProjection {
258258
* to obtain the domain type. <br />
259259
* Using {@link Object} also works for non strictly typed fields. Eg. a mixture different types like fields using
260260
* {@link String} in one {@link org.bson.Document} while {@link Long} in another.</dd>
261-
* <dt>Any Simple type like {@link String}, {@link Long}, ...</dt>
261+
* <dt>Any Simple type like {@link String} or {@link Long}.</dt>
262262
* <dd>The result is mapped directly by the MongoDB Java driver and the {@link org.bson.codecs.CodeCodec Codecs} in
263263
* place. This works only for results where all documents considered for the operation use the very same type for
264264
* the field.</dd>

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017 the original author or authors.
2+
* Copyright 2017-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -209,12 +209,13 @@ public boolean exists() {
209209
* (non-Javadoc)
210210
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.FindDistinct#distinct(java.lang.String)
211211
*/
212+
@SuppressWarnings("unchecked")
212213
@Override
213214
public TerminatingDistinct<Object> distinct(String field) {
214215

215216
Assert.notNull(field, "Field must not be null!");
216217

217-
return new DistinctOperationSupport<>(this, field);
218+
return new DistinctOperationSupport(this, field);
218219
}
219220

220221
private List<T> doFind(@Nullable CursorPreparer preparer) {
@@ -287,9 +288,9 @@ CursorPreparer limit(int limit) {
287288
static class DistinctOperationSupport<T> implements TerminatingDistinct<T> {
288289

289290
private final String field;
290-
private final ExecutableFindSupport delegate;
291+
private final ExecutableFindSupport<T> delegate;
291292

292-
public DistinctOperationSupport(ExecutableFindSupport delegate, String field) {
293+
public DistinctOperationSupport(ExecutableFindSupport<T> delegate, String field) {
293294

294295
this.delegate = delegate;
295296
this.field = field;
@@ -300,11 +301,12 @@ public DistinctOperationSupport(ExecutableFindSupport delegate, String field) {
300301
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.DistinctWithProjection#as(java.lang.Class)
301302
*/
302303
@Override
304+
@SuppressWarnings("unchecked")
303305
public <R> TerminatingDistinct<R> as(Class<R> resultType) {
304306

305307
Assert.notNull(resultType, "ResultType must not be null!");
306308

307-
return new DistinctOperationSupport((ExecutableFindSupport) delegate.as(resultType), field);
309+
return new DistinctOperationSupport<>((ExecutableFindSupport) delegate.as(resultType), field);
308310
}
309311

310312
/*
@@ -316,7 +318,7 @@ public TerminatingDistinct<T> matching(Query query) {
316318

317319
Assert.notNull(query, "Query must not be null!");
318320

319-
return new DistinctOperationSupport((ExecutableFindSupport) delegate.matching(query), field);
321+
return new DistinctOperationSupport<>((ExecutableFindSupport<T>) delegate.matching(query), field);
320322
}
321323

322324
/*

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,6 @@ <T> List<T> findDistinct(Query query, String field, String collectionName, Class
761761
* @param field the name of the field to inspect for distinct values. Must not be {@literal null}.
762762
* @param collection the explicit name of the actual {@link MongoCollection}. Must not be {@literal null}.
763763
* @param resultClass the result type. Must not be {@literal null}.
764-
* @param <T>
765764
* @return never {@literal null}.
766765
* @since 2.1
767766
*/

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

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010-2017 the original author or authors.
2+
* Copyright 2010-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -121,7 +121,6 @@
121121
import org.springframework.util.ResourceUtils;
122122
import org.springframework.util.StringUtils;
123123

124-
import com.mongodb.Function;
125124
import com.mongodb.MongoClient;
126125
import com.mongodb.MongoException;
127126
import com.mongodb.ReadPreference;
@@ -803,7 +802,7 @@ public <T> T findById(Object id, Class<T> entityClass, String collectionName) {
803802
}
804803

805804
/*
806-
* (non-Javadoc)
805+
* (non-Javadoc)
807806
* @see org.springframework.data.mongodb.core.MongoOperations#findDistinct(org.springframework.data.mongodb.core.query.Query, java.lang.String, java.lang.Class, java.lang.Class)
808807
*/
809808
@Override
@@ -816,6 +815,7 @@ public <T> List<T> findDistinct(Query query, String field, Class<?> entityClass,
816815
* @see org.springframework.data.mongodb.core.MongoOperations#findDistinct(org.springframework.data.mongodb.core.query.Query, java.lang.String, java.lang.String, java.lang.Class, java.lang.Class)
817816
*/
818817
@Override
818+
@SuppressWarnings("unchecked")
819819
public <T> List<T> findDistinct(Query query, String field, String collectionName, Class<?> entityClass,
820820
Class<T> resultClass) {
821821

@@ -830,20 +830,24 @@ public <T> List<T> findDistinct(Query query, String field, String collectionName
830830
Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), entity);
831831
String mappedFieldName = queryMapper.getMappedFields(new Document(field, 1), entity).keySet().iterator().next();
832832

833-
Class<?> mongoDriverCompatibleType = getMongoDbFactory().getCodecFor(resultClass).map(Codec::getEncoderClass)
833+
Class<T> mongoDriverCompatibleType = getMongoDbFactory().getCodecFor(resultClass).map(Codec::getEncoderClass)
834834
.orElse((Class) BsonValue.class);
835835

836836
MongoIterable<?> result = execute((db) -> {
837837

838-
DistinctIterable<?> iterable = db.getCollection(collectionName).distinct(mappedFieldName, mappedQuery,
838+
DistinctIterable<T> iterable = db.getCollection(collectionName).distinct(mappedFieldName, mappedQuery,
839839
mongoDriverCompatibleType);
840840

841-
return query.getCollation().isPresent()
842-
? iterable.collation(query.getCollation().map(Collation::toMongoCollation).get()) : iterable;
841+
return query.getCollation().map(Collation::toMongoCollation).map(iterable::collation).orElse(iterable);
843842
});
844843

845844
if (resultClass == Object.class || mongoDriverCompatibleType != resultClass) {
846-
result = result.map(mapDistinctResult(getMostSpecificConversionTargetType(resultClass, entityClass, field)));
845+
846+
MongoConverter converter = getConverter();
847+
DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
848+
849+
result = result.map((source) -> converter.mapValueToTargetType(source,
850+
getMostSpecificConversionTargetType(resultClass, entityClass, field), dbRefResolver));
847851
}
848852

849853
try {
@@ -860,7 +864,7 @@ public <T> List<T> findDistinct(Query query, String field, String collectionName
860864
* @return the most specific conversion target type depending on user preference and domain type property.
861865
* @since 2.1
862866
*/
863-
private Class<?> getMostSpecificConversionTargetType(Class<?> userType, Class<?> domainType, String field) {
867+
private static Class<?> getMostSpecificConversionTargetType(Class<?> userType, Class<?> domainType, String field) {
864868

865869
Class<?> conversionTargetType = userType;
866870
try {
@@ -879,16 +883,6 @@ private Class<?> getMostSpecificConversionTargetType(Class<?> userType, Class<?>
879883
return conversionTargetType;
880884
}
881885

882-
/**
883-
* @param targetType the desired conversion target type.
884-
* @return new {@link Function} converting {@link BsonValue} into desired target type.
885-
* @since 2.1
886-
*/
887-
private <S, T> Function<S, T> mapDistinctResult(Class<T> targetType) {
888-
return (source) -> getConverter().mapValueToTargetType(targetType, new DefaultDbRefResolver(mongoDbFactory))
889-
.apply(source);
890-
}
891-
892886
@Override
893887
public <T> GeoResults<T> geoNear(NearQuery near, Class<T> entityClass) {
894888
return geoNear(near, entityClass, determineCollectionName(entityClass));

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017 the original author or authors.
2+
* Copyright 2017-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017 the original author or authors.
2+
* Copyright 2017-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -217,6 +217,7 @@ private Flux<T> doFind(@Nullable FindPublisherPreparer preparer) {
217217
preparer != null ? preparer : getCursorPreparer(query));
218218
}
219219

220+
@SuppressWarnings("unchecked")
220221
private Flux<T> doFindDistinct(String field) {
221222

222223
return template.findDistinct(query, field, getCollectionName(), domainType,
@@ -259,19 +260,20 @@ public <R> TerminatingDistinct<R> as(Class<R> resultType) {
259260

260261
Assert.notNull(resultType, "ResultType must not be null!");
261262

262-
return new DistinctOperationSupport((ReactiveFindSupport) delegate.as(resultType), field);
263+
return new DistinctOperationSupport<>((ReactiveFindSupport) delegate.as(resultType), field);
263264
}
264265

265266
/*
266267
* (non-Javadoc)
267268
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.DistinctWithQuery#matching(org.springframework.data.mongodb.core.query.Query)
268269
*/
269270
@Override
271+
@SuppressWarnings("unchecked")
270272
public TerminatingDistinct<T> matching(Query query) {
271273

272274
Assert.notNull(query, "Query must not be null!");
273275

274-
return new DistinctOperationSupport((ReactiveFindSupport) delegate.matching(query), field);
276+
return new DistinctOperationSupport<>((ReactiveFindSupport<T>) delegate.matching(query), field);
275277
}
276278

277279
/*

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ <T> Mono<MongoCollection<Document>> createCollection(Class<T> entityClass,
379379

380380
/**
381381
* Finds the distinct values for a specified {@literal field} across a single {@link MongoCollection} or view and
382-
* returns the results in a {@link List}.
382+
* returns the results in a {@link Flux}.
383383
*
384384
* @param field the name of the field to inspect for distinct values. Must not be {@literal null}.
385385
* @param entityClass the domain type used for determining the actual {@link MongoCollection}. Must not be
@@ -394,7 +394,7 @@ default <T> Flux<T> findDistinct(String field, Class<?> entityClass, Class<T> re
394394

395395
/**
396396
* Finds the distinct values for a specified {@literal field} across a single {@link MongoCollection} or view and
397-
* returns the results in a {@link List}.
397+
* returns the results in a {@link Flux}.
398398
*
399399
* @param query filter {@link Query} to restrict search. Must not be {@literal null}.
400400
* @param field the name of the field to inspect for distinct values. Must not be {@literal null}.
@@ -408,7 +408,7 @@ default <T> Flux<T> findDistinct(String field, Class<?> entityClass, Class<T> re
408408

409409
/**
410410
* Finds the distinct values for a specified {@literal field} across a single {@link MongoCollection} or view and
411-
* returns the results in a {@link List}.
411+
* returns the results in a {@link Flux}.
412412
*
413413
* @param query filter {@link Query} to restrict search. Must not be {@literal null}.
414414
* @param field the name of the field to inspect for distinct values. Must not be {@literal null}.
@@ -423,14 +423,13 @@ <T> Flux<T> findDistinct(Query query, String field, String collectionName, Class
423423

424424
/**
425425
* Finds the distinct values for a specified {@literal field} across a single {@link MongoCollection} or view and
426-
* returns the results in a {@link List}.
426+
* returns the results in a {@link Flux}.
427427
*
428428
* @param query filter {@link Query} to restrict search. Must not be {@literal null}.
429429
* @param field the name of the field to inspect for distinct values. Must not be {@literal null}.
430430
* @param collection the explicit name of the actual {@link MongoCollection}. Must not be {@literal null}.
431431
* @param resultClass the result type. Must not be {@literal null}.
432-
* @param <T>
433-
* @return
432+
* @return never {@literal null}.
434433
* @since 2.1
435434
*/
436435
default <T> Flux<T> findDistinct(Query query, String field, String collection, Class<T> resultClass) {

0 commit comments

Comments
 (0)