From bdd5c9dec7bbccecc349388bd80d21d2823dd0df Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 31 Jul 2017 13:46:53 +0200 Subject: [PATCH] DATAMONGO-1762 - Add @Nullable and @NonNullApi annotations. Marked all packages with Spring Frameworks @NonNullApi. Added Spring's @Nullable to methods, parameters and fields that take or produce null values. Adapted using code to make sure the IDE can evaluate the null flow properly. Fixed Javadoc in places where an invalid null handling policy was advertised. Strengthened null requirements for types that expose null-instances. --- .../config/MongoCredentialPropertyEditor.java | 3 +- .../config/ReadPreferencePropertyEditor.java | 10 +- .../config/ServerAddressPropertyEditor.java | 6 +- .../config/WriteConcernPropertyEditor.java | 12 +- .../data/mongodb/config/package-info.java | 1 + .../data/mongodb/core/CollectionCallback.java | 8 +- .../data/mongodb/core/CollectionOptions.java | 22 +- .../data/mongodb/core/DbCallback.java | 18 +- .../data/mongodb/core/DbHolder.java | 66 --- .../mongodb/core/DefaultBulkOperations.java | 7 +- .../mongodb/core/DefaultIndexOperations.java | 10 +- .../core/DefaultIndexOperationsProvider.java | 14 +- .../core/DefaultReactiveIndexOperations.java | 7 +- .../mongodb/core/DefaultScriptOperations.java | 5 +- ...ExecutableAggregationOperationSupport.java | 5 +- .../mongodb/core/ExecutableFindOperation.java | 3 + .../core/ExecutableFindOperationSupport.java | 13 +- .../ExecutableInsertOperationSupport.java | 5 +- .../ExecutableRemoveOperationSupport.java | 3 +- .../core/ExecutableUpdateOperation.java | 2 + .../ExecutableUpdateOperationSupport.java | 11 +- .../mongodb/core/FindAndModifyOptions.java | 7 +- .../data/mongodb/core/IndexConverters.java | 6 +- .../data/mongodb/core/MongoAction.java | 32 +- .../data/mongodb/core/MongoAdmin.java | 23 +- .../mongodb/core/MongoClientFactoryBean.java | 31 +- .../core/MongoClientOptionsFactoryBean.java | 13 +- .../MongoDataIntegrityViolationException.java | 5 +- .../core/MongoExceptionTranslator.java | 4 +- .../data/mongodb/core/MongoOperations.java | 235 ++++++----- .../mongodb/core/MongoSynchronization.java | 29 -- .../data/mongodb/core/MongoTemplate.java | 397 ++++++++++++++---- .../core/ReactiveFindOperationSupport.java | 3 +- .../core/ReactiveMongoClientFactoryBean.java | 21 +- .../mongodb/core/ReactiveMongoOperations.java | 7 +- .../mongodb/core/ReactiveMongoTemplate.java | 62 +-- .../data/mongodb/core/ScriptOperations.java | 5 +- .../mongodb/core/SimpleMongoDbFactory.java | 3 +- .../SimpleReactiveMongoDatabaseFactory.java | 6 +- .../mongodb/core/WriteConcernResolver.java | 5 +- .../core/aggregation/AggregationOptions.java | 5 +- .../core/aggregation/ArrayOperators.java | 9 +- .../aggregation/ConditionalOperators.java | 18 +- .../aggregation/GraphLookupOperation.java | 21 +- .../core/aggregation/LookupOperation.java | 37 +- .../core/aggregation/UnwindOperation.java | 7 +- .../core/aggregation/package-info.java | 5 +- .../core/convert/AbstractMongoConverter.java | 24 +- .../mongodb/core/convert/DbRefResolver.java | 3 + .../core/convert/DefaultDbRefResolver.java | 11 +- .../convert/DocumentPropertyAccessor.java | 11 +- .../core/convert/MappingMongoConverter.java | 32 +- .../core/convert/MongoCustomConversions.java | 5 +- .../mongodb/core/convert/MongoWriter.java | 11 +- .../mongodb/core/convert/QueryMapper.java | 68 +-- .../mongodb/core/convert/UpdateMapper.java | 19 +- .../mongodb/core/convert/package-info.java | 1 + .../data/mongodb/core/geo/GeoJsonModule.java | 6 +- .../data/mongodb/core/geo/package-info.java | 1 + .../mongodb/core/index/GeospatialIndex.java | 13 +- .../data/mongodb/core/index/Index.java | 3 +- .../data/mongodb/core/index/IndexInfo.java | 6 +- .../mongodb/core/index/IndexPredicate.java | 7 +- .../core/index/TextIndexDefinition.java | 17 +- .../data/mongodb/core/index/package-info.java | 1 + .../mapping/BasicMongoPersistentEntity.java | 13 +- .../CachingMongoPersistentProperty.java | 13 +- .../core/mapping/MongoMappingContext.java | 5 +- .../event/AbstractMongoEventListener.java | 3 +- .../mapping/event/AuditingEventListener.java | 3 +- .../core/mapping/event/package-info.java | 1 + .../mongodb/core/mapping/package-info.java | 1 + .../data/mongodb/core/mapreduce/GroupBy.java | 5 +- .../core/mapreduce/GroupByResults.java | 4 +- .../core/mapreduce/MapReduceOptions.java | 11 +- .../mongodb/core/mapreduce/package-info.java | 1 + .../data/mongodb/core/package-info.java | 1 + .../data/mongodb/core/query/BasicQuery.java | 27 +- .../data/mongodb/core/query/Criteria.java | 8 +- .../core/query/CriteriaDefinition.java | 12 +- .../data/mongodb/core/query/Field.java | 5 +- .../data/mongodb/core/query/NearQuery.java | 41 +- .../data/mongodb/core/query/Query.java | 4 +- .../data/mongodb/core/query/TextCriteria.java | 7 +- .../data/mongodb/core/query/package-info.java | 1 + .../mongodb/core/script/package-info.java | 8 + .../data/mongodb/core/spel/package-info.java | 5 +- .../data/mongodb/gridfs/GridFsCriteria.java | 6 +- .../data/mongodb/gridfs/GridFsOperations.java | 28 +- .../data/mongodb/gridfs/GridFsTemplate.java | 23 +- .../data/mongodb/gridfs/package-info.java | 1 + .../data/mongodb/monitor/package-info.java | 1 + .../data/mongodb/package-info.java | 2 +- .../mongodb/repository/cdi/package-info.java | 1 + .../repository/config/package-info.java | 1 + .../data/mongodb/repository/package-info.java | 1 + .../repository/query/AbstractMongoQuery.java | 1 + .../repository/query/MongoParameters.java | 51 ++- .../repository/query/MongoQueryMethod.java | 3 +- .../repository/query/package-info.java | 1 + .../support/MongoAnnotationProcessor.java | 5 +- .../support/MongoRepositoryFactory.java | 3 +- .../support/MongoRepositoryFactoryBean.java | 10 +- .../ReactiveMongoRepositoryFactory.java | 3 +- .../ReactiveMongoRepositoryFactoryBean.java | 7 +- .../support/SpringDataMongodbQuery.java | 9 +- .../support/SpringDataMongodbSerializer.java | 11 +- .../repository/support/package-info.java | 1 + .../data/mongodb/util/package-info.java | 5 +- .../core/MongoOperationsUnitTests.java | 2 +- .../data/mongodb/core/MongoTemplateTests.java | 14 +- .../mongodb/core/MongoTemplateUnitTests.java | 23 +- .../GridFsTemplateIntegrationTests.java | 13 +- 113 files changed, 1126 insertions(+), 745 deletions(-) delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DbHolder.java delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoSynchronization.java create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/script/package-info.java diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java index 28ac83a29..b29236030 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java @@ -25,6 +25,7 @@ import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; import com.mongodb.MongoCredential; @@ -51,7 +52,7 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport { * @see java.beans.PropertyEditorSupport#setAsText(java.lang.String) */ @Override - public void setAsText(String text) throws IllegalArgumentException { + public void setAsText(@Nullable String text) throws IllegalArgumentException { if (!StringUtils.hasText(text)) { return; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadPreferencePropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadPreferencePropertyEditor.java index e5509e0ce..eb3a59d6c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadPreferencePropertyEditor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadPreferencePropertyEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,8 @@ package org.springframework.data.mongodb.config; import java.beans.PropertyEditorSupport; +import org.springframework.lang.Nullable; + import com.mongodb.ReadPreference; /** @@ -32,7 +34,7 @@ public class ReadPreferencePropertyEditor extends PropertyEditorSupport { * @see java.beans.PropertyEditorSupport#setAsText(java.lang.String) */ @Override - public void setAsText(String readPreferenceString) throws IllegalArgumentException { + public void setAsText(@Nullable String readPreferenceString) throws IllegalArgumentException { if (readPreferenceString == null) { return; @@ -59,8 +61,8 @@ public class ReadPreferencePropertyEditor extends PropertyEditorSupport { } else if ("NEAREST".equalsIgnoreCase(readPreferenceString)) { setValue(ReadPreference.nearest()); } else { - throw new IllegalArgumentException(String.format("Cannot find matching ReadPreference for %s", - readPreferenceString)); + throw new IllegalArgumentException( + String.format("Cannot find matching ReadPreference for %s", readPreferenceString)); } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ServerAddressPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ServerAddressPropertyEditor.java index 32383ba49..a61ba8ea4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ServerAddressPropertyEditor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ServerAddressPropertyEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 2011-2017 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. @@ -23,6 +23,7 @@ import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -34,6 +35,7 @@ import com.mongodb.ServerAddress; * @author Mark Pollack * @author Oliver Gierke * @author Thomas Darimont + * @author Christoph Strobl */ public class ServerAddressPropertyEditor extends PropertyEditorSupport { @@ -49,7 +51,7 @@ public class ServerAddressPropertyEditor extends PropertyEditorSupport { * @see java.beans.PropertyEditorSupport#setAsText(java.lang.String) */ @Override - public void setAsText(String replicaSetString) { + public void setAsText(@Nullable String replicaSetString) { if (!StringUtils.hasText(replicaSetString)) { setValue(null); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/WriteConcernPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/WriteConcernPropertyEditor.java index a98d5f6cb..a8d48832f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/WriteConcernPropertyEditor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/WriteConcernPropertyEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,9 @@ package org.springframework.data.mongodb.config; import java.beans.PropertyEditorSupport; +import org.springframework.lang.Nullable; +import org.springframework.util.StringUtils; + import com.mongodb.WriteConcern; /** @@ -26,6 +29,7 @@ import com.mongodb.WriteConcern; * string value. * * @author Mark Pollack + * @author Christoph Strobl */ public class WriteConcernPropertyEditor extends PropertyEditorSupport { @@ -33,7 +37,11 @@ public class WriteConcernPropertyEditor extends PropertyEditorSupport { * Parse a string to a List */ @Override - public void setAsText(String writeConcernString) { + public void setAsText(@Nullable String writeConcernString) { + + if (!StringUtils.hasText(writeConcernString)) { + return; + } WriteConcern writeConcern = WriteConcern.valueOf(writeConcernString); if (writeConcern != null) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/package-info.java index f098200af..5a1e5b725 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/package-info.java @@ -1,5 +1,6 @@ /** * Spring XML namespace configuration for MongoDB specific repositories. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.config; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionCallback.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionCallback.java index 28167e53b..444b0a8e8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionCallback.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 the original author or authors. + * Copyright 2010-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,13 @@ package org.springframework.data.mongodb.core; import org.bson.Document; import org.springframework.dao.DataAccessException; +import org.springframework.lang.Nullable; import com.mongodb.MongoException; import com.mongodb.client.MongoCollection; /** - * Callback interface for executing actions against a {@link MongoCollection} + * Callback interface for executing actions against a {@link MongoCollection}. * * @author Mark Pollak * @author Grame Rocher @@ -35,10 +36,11 @@ public interface CollectionCallback { /** * @param collection never {@literal null}. - * @return + * @return can be {@literal null}. * @throws MongoException * @throws DataAccessException */ + @Nullable T doInCollection(MongoCollection collection) throws MongoException, DataAccessException; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java index aec3dde14..7810ac115 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java @@ -18,6 +18,7 @@ package org.springframework.data.mongodb.core; import java.util.Optional; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -29,26 +30,27 @@ import org.springframework.util.Assert; */ public class CollectionOptions { - private Long maxDocuments; - private Long size; - private Boolean capped; - private Collation collation; + private @Nullable Long maxDocuments; + private @Nullable Long size; + private @Nullable Boolean capped; + private @Nullable Collation collation; /** * Constructs a new CollectionOptions instance. * - * @param size the collection size in bytes, this data space is preallocated. - * @param maxDocuments the maximum number of documents in the collection. + * @param size the collection size in bytes, this data space is preallocated. Can be {@literal null}. + * @param maxDocuments the maximum number of documents in the collection. Can be {@literal null}. * @param capped true to created a "capped" collection (fixed size with auto-FIFO behavior based on insertion order), - * false otherwise. + * false otherwise. Can be {@literal null}. * @deprecated since 2.0 please use {@link CollectionOptions#empty()} as entry point. */ @Deprecated - public CollectionOptions(Long size, Long maxDocuments, Boolean capped) { + public CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped) { this(size, maxDocuments, capped, null); } - private CollectionOptions(Long size, Long maxDocuments, Boolean capped, Collation collation) { + private CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped, + @Nullable Collation collation) { this.maxDocuments = maxDocuments; this.size = size; @@ -120,7 +122,7 @@ public class CollectionOptions { * @return new {@link CollectionOptions}. * @since 2.0 */ - public CollectionOptions collation(Collation collation) { + public CollectionOptions collation(@Nullable Collation collation) { return new CollectionOptions(size, maxDocuments, capped, collation); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DbCallback.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DbCallback.java index a8a32040c..54e85d9bd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DbCallback.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DbCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 the original author or authors. + * Copyright 2010-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,29 @@ package org.springframework.data.mongodb.core; import org.springframework.dao.DataAccessException; +import org.springframework.lang.Nullable; import com.mongodb.MongoException; import com.mongodb.client.MongoDatabase; /** + * Callback interface for executing actions against a {@link MongoDatabase}. * - * @param + * @author Mark Pollak + * @author Graeme Rocher + * @author Thomas Risberg + * @author Oliver Gierke + * @author John Brisbin + * @author Christoph Strobl */ public interface DbCallback { + /** + * @param db must not be {@literal null}. + * @return can be {@literal null}. + * @throws MongoException + * @throws DataAccessException + */ + @Nullable T doInDB(MongoDatabase db) throws MongoException, DataAccessException; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DbHolder.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DbHolder.java deleted file mode 100644 index 35dcb3723..000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DbHolder.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.springframework.data.mongodb.core; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import com.mongodb.DB; -import org.springframework.transaction.support.ResourceHolderSupport; -import org.springframework.util.Assert; - -class DbHolder extends ResourceHolderSupport { - private static final Object DEFAULT_KEY = new Object(); - - private final Map dbMap = new ConcurrentHashMap(); - - public DbHolder(DB db) { - addDB(db); - } - - public DbHolder(Object key, DB db) { - addDB(key, db); - } - - public DB getDB() { - return getDB(DEFAULT_KEY); - } - - public DB getDB(Object key) { - return this.dbMap.get(key); - } - - public DB getAnyDB() { - if (!this.dbMap.isEmpty()) { - return this.dbMap.values().iterator().next(); - } - return null; - } - - public void addDB(DB session) { - addDB(DEFAULT_KEY, session); - } - - public void addDB(Object key, DB session) { - Assert.notNull(key, "Key must not be null"); - Assert.notNull(session, "DB must not be null"); - this.dbMap.put(key, session); - } - - public DB removeDB(Object key) { - return this.dbMap.remove(key); - } - - public boolean containsDB(DB session) { - return this.dbMap.containsValue(session); - } - - public boolean isEmpty() { - return this.dbMap.isEmpty(); - } - - public boolean doesNotHoldNonDefaultDB() { - synchronized (this.dbMap) { - return this.dbMap.isEmpty() || (this.dbMap.size() == 1 && this.dbMap.containsKey(DEFAULT_KEY)); - } - } - -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultBulkOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultBulkOperations.java index f60517ac6..def566730 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultBulkOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultBulkOperations.java @@ -35,6 +35,7 @@ import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.util.Pair; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.BulkWriteException; @@ -67,7 +68,7 @@ class DefaultBulkOperations implements BulkOperations { private final List> models = new ArrayList<>(); private PersistenceExceptionTranslator exceptionTranslator; - private WriteConcern defaultWriteConcern; + private @Nullable WriteConcern defaultWriteConcern; private BulkWriteOptions bulkOptions; @@ -99,7 +100,7 @@ class DefaultBulkOperations implements BulkOperations { * * @param exceptionTranslator can be {@literal null}. */ - public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) { + public void setExceptionTranslator(@Nullable PersistenceExceptionTranslator exceptionTranslator) { this.exceptionTranslator = exceptionTranslator == null ? new MongoExceptionTranslator() : exceptionTranslator; } @@ -108,7 +109,7 @@ class DefaultBulkOperations implements BulkOperations { * * @param defaultWriteConcern can be {@literal null}. */ - void setDefaultWriteConcern(WriteConcern defaultWriteConcern) { + void setDefaultWriteConcern(@Nullable WriteConcern defaultWriteConcern) { this.defaultWriteConcern = defaultWriteConcern; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultIndexOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultIndexOperations.java index 51c0a31d0..5bab7a5b5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultIndexOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultIndexOperations.java @@ -29,6 +29,7 @@ import org.springframework.data.mongodb.core.index.IndexDefinition; import org.springframework.data.mongodb.core.index.IndexInfo; import org.springframework.data.mongodb.core.index.IndexOperations; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.MongoException; @@ -52,7 +53,7 @@ public class DefaultIndexOperations implements IndexOperations { private final MongoDbFactory mongoDbFactory; private final String collectionName; private final QueryMapper mapper; - private final Class type; + private final @Nullable Class type; /** * Creates a new {@link DefaultIndexOperations}. @@ -62,7 +63,6 @@ public class DefaultIndexOperations implements IndexOperations { * @param queryMapper must not be {@literal null}. */ public DefaultIndexOperations(MongoDbFactory mongoDbFactory, String collectionName, QueryMapper queryMapper) { - this(mongoDbFactory, collectionName, queryMapper, null); } @@ -76,7 +76,7 @@ public class DefaultIndexOperations implements IndexOperations { * @since 1.10 */ public DefaultIndexOperations(MongoDbFactory mongoDbFactory, String collectionName, QueryMapper queryMapper, - Class type) { + @Nullable Class type) { Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null!"); Assert.notNull(collectionName, "Collection name can not be null!"); @@ -116,7 +116,8 @@ public class DefaultIndexOperations implements IndexOperations { }); } - private MongoPersistentEntity lookupPersistentEntity(Class entityType, String collection) { + @Nullable + private MongoPersistentEntity lookupPersistentEntity(@Nullable Class entityType, String collection) { if (entityType != null) { return mapper.getMappingContext().getRequiredPersistentEntity(entityType); @@ -185,6 +186,7 @@ public class DefaultIndexOperations implements IndexOperations { }); } + @Nullable public T execute(CollectionCallback callback) { Assert.notNull(callback, "CollectionCallback must not be null!"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultIndexOperationsProvider.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultIndexOperationsProvider.java index 9412a3a65..3aa0d5c03 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultIndexOperationsProvider.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultIndexOperationsProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,10 +21,10 @@ import org.springframework.data.mongodb.core.index.IndexOperations; import org.springframework.data.mongodb.core.index.IndexOperationsProvider; /** - * {@link IndexOperationsProvider} to obtain {@link IndexOperations} from a given {@link MongoDbFactory}. TODO: Review - * me + * {@link IndexOperationsProvider} to obtain {@link IndexOperations} from a given {@link MongoDbFactory}. * * @author Mark Paluch + * @author Christoph Strobl * @since 2.0 */ class DefaultIndexOperationsProvider implements IndexOperationsProvider { @@ -34,12 +34,16 @@ class DefaultIndexOperationsProvider implements IndexOperationsProvider { /** * @param mongoDbFactory must not be {@literal null}. + * @param mapper must not be {@literal null}. */ DefaultIndexOperationsProvider(MongoDbFactory mongoDbFactory, QueryMapper mapper) { - this.mongoDbFactory = mongoDbFactory; this.mapper = mapper; + + this.mongoDbFactory = mongoDbFactory; + this.mapper = mapper; } - /* (non-Javadoc) + /* + * (non-Javadoc) * @see org.springframework.data.mongodb.core.index.IndexOperationsProvider#reactiveIndexOps(java.lang.String) */ @Override diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveIndexOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveIndexOperations.java index 4a545b3bb..4e2587dfb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveIndexOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveIndexOperations.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core; import org.springframework.data.mongodb.core.index.ReactiveIndexOperations; +import org.springframework.lang.Nullable; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -68,7 +69,7 @@ public class DefaultReactiveIndexOperations implements ReactiveIndexOperations { * @param type used for mapping potential partial index filter expression, must not be {@literal null}. */ public DefaultReactiveIndexOperations(ReactiveMongoOperations mongoOperations, String collectionName, - QueryMapper queryMapper, Class type) { + QueryMapper queryMapper, @Nullable Class type) { this(mongoOperations, collectionName, queryMapper, Optional.of(type)); } @@ -85,7 +86,8 @@ public class DefaultReactiveIndexOperations implements ReactiveIndexOperations { this.type = type; } - /* (non-Javadoc) + /* + * (non-Javadoc) * @see org.springframework.data.mongodb.core.index.ReactiveIndexOperations#ensureIndex(org.springframework.data.mongodb.core.index.IndexDefinition) */ public Mono ensureIndex(final IndexDefinition indexDefinition) { @@ -117,6 +119,7 @@ public class DefaultReactiveIndexOperations implements ReactiveIndexOperations { }).next(); } + @Nullable private MongoPersistentEntity lookupPersistentEntity(String collection) { Collection> entities = queryMapper.getMappingContext().getPersistentEntities(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultScriptOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultScriptOperations.java index 2e43f321f..1ff33ecb4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultScriptOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultScriptOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import org.bson.types.ObjectId; import org.springframework.dao.DataAccessException; import org.springframework.data.mongodb.core.script.ExecutableMongoScript; import org.springframework.data.mongodb.core.script.NamedMongoScript; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -56,7 +57,7 @@ class DefaultScriptOperations implements ScriptOperations { /** * Creates new {@link DefaultScriptOperations} using given {@link MongoOperations}. - * + * * @param mongoOperations must not be {@literal null}. */ public DefaultScriptOperations(MongoOperations mongoOperations) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableAggregationOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableAggregationOperationSupport.java index 19798440a..7db7197ec 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableAggregationOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableAggregationOperationSupport.java @@ -24,6 +24,7 @@ import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.AggregationResults; import org.springframework.data.mongodb.core.aggregation.TypedAggregation; import org.springframework.data.util.CloseableIterator; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -74,8 +75,8 @@ class ExecutableAggregationOperationSupport implements ExecutableAggregationOper @NonNull MongoTemplate template; @NonNull Class domainType; - Aggregation aggregation; - String collection; + @Nullable Aggregation aggregation; + @Nullable String collection; /* * (non-Javadoc) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java index 561fed3c0..a383f4470 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java @@ -22,6 +22,7 @@ import java.util.stream.Stream; import org.springframework.data.geo.GeoResults; import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.lang.Nullable; /** * {@link ExecutableFindOperation} allows creation and execution of MongoDB find operations in a fluent API style. @@ -83,6 +84,7 @@ public interface ExecutableFindOperation { * @return {@literal null} if no match found. * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. */ + @Nullable T oneValue(); /** @@ -99,6 +101,7 @@ public interface ExecutableFindOperation { * * @return {@literal null} if no match found. */ + @Nullable T firstValue(); /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupport.java index 494630d10..b0002344c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupport.java @@ -31,6 +31,7 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.SerializationUtils; import org.springframework.data.util.CloseableIterator; import org.springframework.data.util.StreamUtils; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -88,7 +89,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation { @NonNull MongoTemplate template; @NonNull Class domainType; Class returnType; - String collection; + @Nullable String collection; Query query; /* @@ -204,7 +205,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation { return template.exists(query, domainType, getCollectionName()); } - private List doFind(CursorPreparer preparer) { + private List doFind(@Nullable CursorPreparer preparer) { Document queryObject = query.getQueryObject(); Document fieldsObject = query.getFieldsObject(); @@ -217,8 +218,8 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation { return template.doStream(query, domainType, getCollectionName(), returnType); } - private CursorPreparer getCursorPreparer(Query query, CursorPreparer preparer) { - return query == null || preparer != null ? preparer : template.new QueryCursorPreparer(query, domainType); + private CursorPreparer getCursorPreparer(Query query, @Nullable CursorPreparer preparer) { + return preparer != null ? preparer : template.new QueryCursorPreparer(query, domainType); } private String getCollectionName() { @@ -236,10 +237,10 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation { */ static class DelegatingQueryCursorPreparer implements CursorPreparer { - private final CursorPreparer delegate; + private final @Nullable CursorPreparer delegate; private Optional limit = Optional.empty(); - DelegatingQueryCursorPreparer(CursorPreparer delegate) { + DelegatingQueryCursorPreparer(@Nullable CursorPreparer delegate) { this.delegate = delegate; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableInsertOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableInsertOperationSupport.java index 69dd94e13..afc35b643 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableInsertOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableInsertOperationSupport.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Collection; import org.springframework.data.mongodb.core.BulkOperations.BulkMode; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -75,8 +76,8 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation { @NonNull MongoTemplate template; @NonNull Class domainType; - String collection; - BulkMode bulkMode; + @Nullable String collection; + @Nullable BulkMode bulkMode; /* * (non-Javadoc) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableRemoveOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableRemoveOperationSupport.java index e700ee1db..d54043c6c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableRemoveOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableRemoveOperationSupport.java @@ -23,6 +23,7 @@ import lombok.experimental.FieldDefaults; import java.util.List; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -77,7 +78,7 @@ class ExecutableRemoveOperationSupport implements ExecutableRemoveOperation { @NonNull MongoTemplate template; @NonNull Class domainType; Query query; - String collection; + @Nullable String collection; /* * (non-Javadoc) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableUpdateOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableUpdateOperation.java index b8e34fcbb..159dff3f1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableUpdateOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableUpdateOperation.java @@ -21,6 +21,7 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import com.mongodb.client.result.UpdateResult; +import org.springframework.lang.Nullable; /** * {@link ExecutableUpdateOperation} allows creation and execution of MongoDB update / findAndModify operations in a @@ -148,6 +149,7 @@ public interface ExecutableUpdateOperation { * * @return {@literal null} if nothing found. */ + @Nullable T findAndModifyValue(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableUpdateOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableUpdateOperationSupport.java index 8527102c5..1102e100d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableUpdateOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableUpdateOperationSupport.java @@ -22,6 +22,7 @@ import lombok.experimental.FieldDefaults; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -76,9 +77,9 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation { @NonNull MongoTemplate template; @NonNull Class domainType; Query query; - Update update; - String collection; - FindAndModifyOptions options; + @Nullable Update update; + @Nullable String collection; + @Nullable FindAndModifyOptions options; /* * (non-Javadoc) @@ -160,8 +161,8 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation { * @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.TerminatingFindAndModify#findAndModifyValue() */ @Override - public T findAndModifyValue() { - return template.findAndModify(query, update, options, domainType, getCollectionName()); + public @Nullable T findAndModifyValue() { + return template.findAndModify(query, update, options != null ? options : new FindAndModifyOptions(), domainType, getCollectionName()); } private UpdateResult doUpdate(boolean multi, boolean upsert) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndModifyOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndModifyOptions.java index 26edb6644..a062dc55d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndModifyOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndModifyOptions.java @@ -18,6 +18,7 @@ package org.springframework.data.mongodb.core; import java.util.Optional; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Nullable; /** * @author Mark Pollak @@ -30,7 +31,7 @@ public class FindAndModifyOptions { private boolean upsert; private boolean remove; - private Collation collation; + private @Nullable Collation collation; /** * Static factory method to create a FindAndModifyOptions instance @@ -46,7 +47,7 @@ public class FindAndModifyOptions { * @return * @since 2.0 */ - public static FindAndModifyOptions of(FindAndModifyOptions source) { + public static FindAndModifyOptions of(@Nullable FindAndModifyOptions source) { FindAndModifyOptions options = new FindAndModifyOptions(); if (source == null) { @@ -83,7 +84,7 @@ public class FindAndModifyOptions { * @return * @since 2.0 */ - public FindAndModifyOptions collation(Collation collation) { + public FindAndModifyOptions collation(@Nullable Collation collation) { this.collation = collation; return this; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/IndexConverters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/IndexConverters.java index 961fe330b..fd0dd118b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/IndexConverters.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/IndexConverters.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 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. @@ -22,6 +22,7 @@ import org.bson.Document; import org.springframework.core.convert.converter.Converter; import org.springframework.data.mongodb.core.index.IndexDefinition; import org.springframework.data.mongodb.core.index.IndexInfo; +import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import com.mongodb.client.model.Collation; @@ -119,7 +120,8 @@ abstract class IndexConverters { }; } - public static Collation fromDocument(Document source) { + @Nullable + public static Collation fromDocument(@Nullable Document source) { if (source == null) { return null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAction.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAction.java index 6af857eca..ff0a92543 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAction.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2016 the original author or authors. + * Copyright 2011-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core; import org.bson.Document; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.WriteConcern; @@ -36,26 +37,28 @@ import com.mongodb.WriteConcern; public class MongoAction { private final String collectionName; - private final WriteConcern defaultWriteConcern; - private final Class entityType; private final MongoActionOperation mongoActionOperation; - private final Document query; - private final Document document; + + private final @Nullable WriteConcern defaultWriteConcern; + private final @Nullable Class entityType; + private final @Nullable Document query; + private final @Nullable Document document; /** * Create an instance of a {@link MongoAction}. * - * @param defaultWriteConcern the default write concern. - * @param mongoActionOperation action being taken against the collection + * @param defaultWriteConcern the default write concern. Can be {@literal null}. + * @param mongoActionOperation action being taken against the collection. Must not be {@literal null}. * @param collectionName the collection name, must not be {@literal null} or empty. - * @param entityType the POJO that is being operated against - * @param document the converted Document from the POJO or Spring Update object - * @param query the converted Document from the Spring Query object + * @param entityType the POJO that is being operated against. Can be {@literal null}. + * @param document the converted Document from the POJO or Spring Update object. Can be {@literal null}. + * @param query the converted Document from the Spring Query object. Can be {@literal null}. */ - public MongoAction(WriteConcern defaultWriteConcern, MongoActionOperation mongoActionOperation, String collectionName, - Class entityType, Document document, Document query) { + public MongoAction(@Nullable WriteConcern defaultWriteConcern, MongoActionOperation mongoActionOperation, + String collectionName, @Nullable Class entityType, @Nullable Document document, @Nullable Document query) { Assert.hasText(collectionName, "Collection name must not be null or empty!"); + Assert.notNull(mongoActionOperation, "MongoActionOperation must not be null!"); this.defaultWriteConcern = defaultWriteConcern; this.mongoActionOperation = mongoActionOperation; @@ -69,22 +72,27 @@ public class MongoAction { return collectionName; } + @Nullable public WriteConcern getDefaultWriteConcern() { return defaultWriteConcern; } + @Nullable public Class getEntityType() { return entityType; } + @Nullable public MongoActionOperation getMongoActionOperation() { return mongoActionOperation; } + @Nullable public Document getQuery() { return query; } + @Nullable public Document getDocument() { return document; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAdmin.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAdmin.java index 745119d06..497398ca7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAdmin.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAdmin.java @@ -15,13 +15,14 @@ */ package org.springframework.data.mongodb.core; -import com.mongodb.MongoClient; -import com.mongodb.client.MongoDatabase; import org.bson.Document; import org.springframework.jmx.export.annotation.ManagedOperation; import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.util.Assert; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoDatabase; + /** * Mongo server administration exposed via JMX annotations * @@ -42,35 +43,35 @@ public class MongoAdmin implements MongoAdminOperations { } /* (non-Javadoc) - * @see org.springframework.data.mongodb.core.core.MongoAdminOperations#dropDatabase(java.lang.String) - */ + * @see org.springframework.data.mongodb.core.core.MongoAdminOperations#dropDatabase(java.lang.String) + */ @ManagedOperation public void dropDatabase(String databaseName) { getDB(databaseName).drop(); } /* (non-Javadoc) - * @see org.springframework.data.mongodb.core.core.MongoAdminOperations#createDatabase(java.lang.String) - */ + * @see org.springframework.data.mongodb.core.core.MongoAdminOperations#createDatabase(java.lang.String) + */ @ManagedOperation public void createDatabase(String databaseName) { getDB(databaseName); } /* (non-Javadoc) - * @see org.springframework.data.mongodb.core.core.MongoAdminOperations#getDatabaseStats(java.lang.String) - */ + * @see org.springframework.data.mongodb.core.core.MongoAdminOperations#getDatabaseStats(java.lang.String) + */ @ManagedOperation public String getDatabaseStats(String databaseName) { - return getDB(databaseName).runCommand(new Document("dbStats", 1).append("scale" , 1024)).toJson(); + return getDB(databaseName).runCommand(new Document("dbStats", 1).append("scale", 1024)).toJson(); } @ManagedOperation public String getServerStatus() { - return getDB("admin").runCommand(new Document("serverStatus", 1).append("rangeDeleter", 1).append("repl", 1)).toJson(); + return getDB("admin").runCommand(new Document("serverStatus", 1).append("rangeDeleter", 1).append("repl", 1)) + .toJson(); } - MongoDatabase getDB(String databaseName) { return mongoClient.getDatabase(databaseName); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientFactoryBean.java index cea3784ff..1d7c90aea 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientFactoryBean.java @@ -23,6 +23,7 @@ import java.util.List; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; +import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -41,11 +42,11 @@ public class MongoClientFactoryBean extends AbstractFactoryBean imp private static final PersistenceExceptionTranslator DEFAULT_EXCEPTION_TRANSLATOR = new MongoExceptionTranslator(); - private MongoClientOptions mongoClientOptions; - private String host; - private Integer port; - private List replicaSetSeeds; - private List credentials; + private @Nullable MongoClientOptions mongoClientOptions; + private @Nullable String host; + private @Nullable Integer port; + private List replicaSetSeeds = Collections.emptyList(); + private List credentials = Collections.emptyList(); private PersistenceExceptionTranslator exceptionTranslator = DEFAULT_EXCEPTION_TRANSLATOR; @@ -54,7 +55,7 @@ public class MongoClientFactoryBean extends AbstractFactoryBean imp * * @param mongoClientOptions */ - public void setMongoClientOptions(MongoClientOptions mongoClientOptions) { + public void setMongoClientOptions(@Nullable MongoClientOptions mongoClientOptions) { this.mongoClientOptions = mongoClientOptions; } @@ -63,7 +64,7 @@ public class MongoClientFactoryBean extends AbstractFactoryBean imp * * @param credentials can be {@literal null}. */ - public void setCredentials(MongoCredential[] credentials) { + public void setCredentials(@Nullable MongoCredential[] credentials) { this.credentials = filterNonNullElementsAsList(credentials); } @@ -72,7 +73,7 @@ public class MongoClientFactoryBean extends AbstractFactoryBean imp * * @param replicaSetSeeds can be {@literal null}. */ - public void setReplicaSetSeeds(ServerAddress[] replicaSetSeeds) { + public void setReplicaSetSeeds(@Nullable ServerAddress[] replicaSetSeeds) { this.replicaSetSeeds = filterNonNullElementsAsList(replicaSetSeeds); } @@ -81,7 +82,7 @@ public class MongoClientFactoryBean extends AbstractFactoryBean imp * * @param host */ - public void setHost(String host) { + public void setHost(@Nullable String host) { this.host = host; } @@ -99,7 +100,7 @@ public class MongoClientFactoryBean extends AbstractFactoryBean imp * * @param exceptionTranslator */ - public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) { + public void setExceptionTranslator(@Nullable PersistenceExceptionTranslator exceptionTranslator) { this.exceptionTranslator = exceptionTranslator == null ? DEFAULT_EXCEPTION_TRANSLATOR : exceptionTranslator; } @@ -115,6 +116,7 @@ public class MongoClientFactoryBean extends AbstractFactoryBean imp * (non-Javadoc) * @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException) */ + @Nullable public DataAccessException translateExceptionIfPossible(RuntimeException ex) { return exceptionTranslator.translateExceptionIfPossible(ex); } @@ -142,8 +144,11 @@ public class MongoClientFactoryBean extends AbstractFactoryBean imp * @see org.springframework.beans.factory.config.AbstractFactoryBean#destroyInstance(java.lang.Object) */ @Override - protected void destroyInstance(MongoClient instance) throws Exception { - instance.close(); + protected void destroyInstance(@Nullable MongoClient instance) throws Exception { + + if (instance != null) { + instance.close(); + } } private MongoClient createMongoClient() throws UnknownHostException { @@ -169,7 +174,7 @@ public class MongoClientFactoryBean extends AbstractFactoryBean imp * @param elements the elements to filter , can be {@literal null}. * @return a new unmodifiable {@link List#} from the given elements without {@literal null}s. */ - private static List filterNonNullElementsAsList(T[] elements) { + private static List filterNonNullElementsAsList(@Nullable T[] elements) { if (elements == null) { return Collections.emptyList(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientOptionsFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientOptionsFactoryBean.java index 0e5f39c72..b185e2cb1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientOptionsFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientOptionsFactoryBean.java @@ -27,6 +27,7 @@ import com.mongodb.MongoClient; import com.mongodb.MongoClientOptions; import com.mongodb.ReadPreference; import com.mongodb.WriteConcern; +import org.springframework.lang.Nullable; /** * A factory bean for construction of a {@link MongoClientOptions} instance. @@ -66,14 +67,14 @@ public class MongoClientOptionsFactoryBean extends AbstractFactoryBean * Allows for returning a result object, that is a domain object or a collection of domain objects. * + * @param action callback object that specifies the MongoDB actions to perform on the passed in DB instance. Must not + * be {@literal null}. * @param return type - * @param action callback object that specifies the MongoDB actions to perform on the passed in DB instance. - * @return a result object returned by the action or null + * @return a result object returned by the action or {@literal null}. */ + @Nullable T execute(DbCallback action); /** @@ -123,11 +127,12 @@ public interface MongoOperations extends FluentMongoOperations { *

* Allows for returning a result object, that is a domain object or a collection of domain objects. * - * @param entityClass class that determines the collection to use * @param return type - * @param action callback object that specifies the MongoDB action - * @return a result object returned by the action or null + * @param entityClass class that determines the collection to use. Must not be {@literal null}. + * @param action callback object that specifies the MongoDB action. Must not be {@literal null}. + * @return a result object returned by the action or {@literal null}. */ + @Nullable T execute(Class entityClass, CollectionCallback action); /** @@ -136,10 +141,12 @@ public interface MongoOperations extends FluentMongoOperations { * Allows for returning a result object, that is a domain object or a collection of domain objects. * * @param return type - * @param collectionName the name of the collection that specifies which DBCollection instance will be passed into - * @param action callback object that specifies the MongoDB action the callback action. - * @return a result object returned by the action or null + * @param collectionName the name of the collection that specifies which DBCollection instance will be passed into. + * Must not be {@literal null} or empty. + * @param action callback object that specifies the MongoDB action the callback action. Must not be {@literal null}. + * @return a result object returned by the action or {@literal null}. */ + @Nullable T execute(String collectionName, CollectionCallback action); /** @@ -182,11 +189,11 @@ public interface MongoOperations extends FluentMongoOperations { /** * Create a collection with a name based on the provided entity class using the options. * - * @param entityClass class that determines the collection to create + * @param entityClass class that determines the collection to create. Must not be {@literal null}. * @param collectionOptions options to use when creating the collection. * @return the created collection */ - MongoCollection createCollection(Class entityClass, CollectionOptions collectionOptions); + MongoCollection createCollection(Class entityClass, @Nullable CollectionOptions collectionOptions); /** * Create an uncapped collection with the provided name. @@ -199,11 +206,11 @@ public interface MongoOperations extends FluentMongoOperations { /** * Create a collection with the provided name and options. * - * @param collectionName name of the collection + * @param collectionName name of the collection. Must not be {@literal null} nor empty. * @param collectionOptions options to use when creating the collection. * @return the created collection */ - MongoCollection createCollection(String collectionName, CollectionOptions collectionOptions); + MongoCollection createCollection(String collectionName, @Nullable CollectionOptions collectionOptions); /** * A set of collection names. @@ -217,7 +224,7 @@ public interface MongoOperations extends FluentMongoOperations { *

* Translate any exceptions as necessary. * - * @param collectionName name of the collection + * @param collectionName name of the collection. Must not be {@literal null}. * @return an existing collection or a newly created one. */ MongoCollection getCollection(String collectionName); @@ -227,7 +234,7 @@ public interface MongoOperations extends FluentMongoOperations { *

* Translate any exceptions as necessary. * - * @param entityClass class that determines the name of the collection + * @param entityClass class that determines the name of the collection. Must not be {@literal null}. * @return true if a collection with the given name is found, false otherwise. */ boolean collectionExists(Class entityClass); @@ -237,7 +244,7 @@ public interface MongoOperations extends FluentMongoOperations { *

* Translate any exceptions as necessary. * - * @param collectionName name of the collection + * @param collectionName name of the collection. Must not be {@literal null}. * @return true if a collection with the given name is found, false otherwise. */ boolean collectionExists(String collectionName); @@ -247,7 +254,7 @@ public interface MongoOperations extends FluentMongoOperations { *

* Translate any exceptions as necessary. * - * @param entityClass class that determines the collection to drop/delete. + * @param entityClass class that determines the collection to drop/delete. Must not be {@literal null}. */ void dropCollection(Class entityClass); @@ -307,11 +314,11 @@ public interface MongoOperations extends FluentMongoOperations { * Returns a new {@link BulkOperations} for the given entity type and collection name. * * @param mode the {@link BulkMode} to use for bulk operations, must not be {@literal null}. - * @param entityClass the name of the entity class, must not be {@literal null}. + * @param entityClass the name of the entity class. Can be {@literal null}. * @param collectionName the name of the collection to work on, must not be {@literal null} or empty. * @return {@link BulkOperations} on the named collection associated with the given entity class. */ - BulkOperations bulkOps(BulkMode mode, Class entityType, String collectionName); + BulkOperations bulkOps(BulkMode mode, @Nullable Class entityType, String collectionName); /** * Query for a list of objects of type T from the collection used by the entity class. @@ -369,7 +376,7 @@ public interface MongoOperations extends FluentMongoOperations { * @param entityClass The parametrized type of the returned list * @return The results of the group operation */ - GroupByResults group(Criteria criteria, String inputCollectionName, GroupBy groupBy, Class entityClass); + GroupByResults group(@Nullable Criteria criteria, String inputCollectionName, GroupBy groupBy, Class entityClass); /** * Execute an aggregation operation. The raw results will be mapped to the given entity class. The name of the @@ -500,11 +507,10 @@ public interface MongoOperations extends FluentMongoOperations { /** * Execute a map-reduce operation. The map-reduce operation will be formed with an output type of INLINE * - * @param inputCollectionName the collection where the map-reduce will read from - * @param mapFunction The JavaScript map function + * @param inputCollectionName the collection where the map-reduce will read from. Must not be {@literal null}. + * @param mapFunction The JavaScript map function. * @param reduceFunction The JavaScript reduce function - * @param mapReduceOptions Options that specify detailed map-reduce behavior - * @param entityClass The parametrized type of the returned list + * @param entityClass The parametrized type of the returned list. Must not be {@literal null}. * @return The results of the map reduce operation */ MapReduceResults mapReduce(String inputCollectionName, String mapFunction, String reduceFunction, @@ -513,26 +519,25 @@ public interface MongoOperations extends FluentMongoOperations { /** * Execute a map-reduce operation that takes additional map-reduce options. * - * @param inputCollectionName the collection where the map-reduce will read from + * @param inputCollectionName the collection where the map-reduce will read from. Must not be {@literal null}. * @param mapFunction The JavaScript map function * @param reduceFunction The JavaScript reduce function - * @param mapReduceOptions Options that specify detailed map-reduce behavior - * @param entityClass The parametrized type of the returned list + * @param mapReduceOptions Options that specify detailed map-reduce behavior. + * @param entityClass The parametrized type of the returned list. Must not be {@literal null}. * @return The results of the map reduce operation */ MapReduceResults mapReduce(String inputCollectionName, String mapFunction, String reduceFunction, - MapReduceOptions mapReduceOptions, Class entityClass); + @Nullable MapReduceOptions mapReduceOptions, Class entityClass); /** * Execute a map-reduce operation that takes a query. The map-reduce operation will be formed with an output type of * INLINE * - * @param query The query to use to select the data for the map phase - * @param inputCollectionName the collection where the map-reduce will read from + * @param query The query to use to select the data for the map phase. Must not be {@literal null}. + * @param inputCollectionName the collection where the map-reduce will read from. Must not be {@literal null}. * @param mapFunction The JavaScript map function * @param reduceFunction The JavaScript reduce function - * @param mapReduceOptions Options that specify detailed map-reduce behavior - * @param entityClass The parametrized type of the returned list + * @param entityClass The parametrized type of the returned list. Must not be {@literal null}. * @return The results of the map reduce operation */ MapReduceResults mapReduce(Query query, String inputCollectionName, String mapFunction, String reduceFunction, @@ -541,16 +546,16 @@ public interface MongoOperations extends FluentMongoOperations { /** * Execute a map-reduce operation that takes a query and additional map-reduce options * - * @param query The query to use to select the data for the map phase - * @param inputCollectionName the collection where the map-reduce will read from + * @param query The query to use to select the data for the map phase. Must not be {@literal null}. + * @param inputCollectionName the collection where the map-reduce will read from. Must not be {@literal null}. * @param mapFunction The JavaScript map function * @param reduceFunction The JavaScript reduce function * @param mapReduceOptions Options that specify detailed map-reduce behavior - * @param entityClass The parametrized type of the returned list + * @param entityClass The parametrized type of the returned list. Must not be {@literal null}. * @return The results of the map reduce operation */ MapReduceResults mapReduce(Query query, String inputCollectionName, String mapFunction, String reduceFunction, - MapReduceOptions mapReduceOptions, Class entityClass); + @Nullable MapReduceOptions mapReduceOptions, Class entityClass); /** * Returns {@link GeoResults} for all entities matching the given {@link NearQuery}. Will consider entity mapping @@ -572,7 +577,7 @@ public interface MongoOperations extends FluentMongoOperations { * @param near must not be {@literal null}. * @param entityClass must not be {@literal null}. * @param collectionName the collection to trigger the query against. If no collection name is given the entity class - * will be inspected. + * will be inspected. Must not be {@literal null} nor empty. * @return */ GeoResults geoNear(NearQuery near, Class entityClass, String collectionName); @@ -592,6 +597,7 @@ public interface MongoOperations extends FluentMongoOperations { * @param entityClass the parametrized type of the returned list. * @return the converted object */ + @Nullable T findOne(Query query, Class entityClass); /** @@ -610,6 +616,7 @@ public interface MongoOperations extends FluentMongoOperations { * @param collectionName name of the collection to retrieve the objects from * @return the converted object */ + @Nullable T findOne(Query query, Class entityClass, String collectionName); /** @@ -636,11 +643,11 @@ public interface MongoOperations extends FluentMongoOperations { * Determine result of given {@link Query} contains at least one element. * * @param query the {@link Query} class that specifies the criteria used to find a record. - * @param entityClass the parametrized type. + * @param entityClass the parametrized type. Can be {@literal null}. * @param collectionName name of the collection to check for objects. * @return */ - boolean exists(Query query, Class entityClass, String collectionName); + boolean exists(Query query, @Nullable Class entityClass, String collectionName); /** * Map the results of an ad-hoc query on the collection for the entity class to a List of the specified type. @@ -652,8 +659,8 @@ public interface MongoOperations extends FluentMongoOperations { * feature rich {@link Query}. * * @param query the query class that specifies the criteria used to find a record and also an optional fields - * specification - * @param entityClass the parametrized type of the returned list. + * specification. Must not be {@literal null}. + * @param entityClass the parametrized type of the returned list. Must not be {@literal null}. * @return the List of converted objects */ List find(Query query, Class entityClass); @@ -668,9 +675,9 @@ public interface MongoOperations extends FluentMongoOperations { * feature rich {@link Query}. * * @param query the query class that specifies the criteria used to find a record and also an optional fields - * specification - * @param entityClass the parametrized type of the returned list. - * @param collectionName name of the collection to retrieve the objects from + * specification. Must not be {@literal null}. + * @param entityClass the parametrized type of the returned list. Must not be {@literal null}. + * @param collectionName name of the collection to retrieve the objects from. Must not be {@literal null}. * @return the List of converted objects */ List find(Query query, Class entityClass, String collectionName); @@ -680,10 +687,11 @@ public interface MongoOperations extends FluentMongoOperations { * derived from the given target class as well. * * @param - * @param id the id of the document to return. - * @param entityClass the type the document shall be converted into. + * @param id the id of the document to return. Must not be {@literal null}. + * @param entityClass the type the document shall be converted into. Must not be {@literal null}. * @return the document with the given id mapped onto the given target class. */ + @Nullable T findById(Object id, Class entityClass); /** @@ -693,8 +701,9 @@ public interface MongoOperations extends FluentMongoOperations { * @param entityClass the type to convert the document to * @param collectionName the collection to query for the document * @param - * @return + * @return {@literal null} if document does not exist. */ + @Nullable T findById(Object id, Class entityClass, String collectionName); /** @@ -702,11 +711,12 @@ public interface MongoOperations extends FluentMongoOperations { * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}. * * @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional - * fields specification. - * @param update the {@link Update} to apply on matching documents. - * @param entityClass the parametrized type. - * @return + * fields specification. Must not be {@literal null}. + * @param update the {@link Update} to apply on matching documents. Must not be {@literal null}. + * @param entityClass the parametrized type. Must not be {@literal null}. + * @return {@literal null} if not found. */ + @Nullable T findAndModify(Query query, Update update, Class entityClass); /** @@ -714,12 +724,13 @@ public interface MongoOperations extends FluentMongoOperations { * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}. * * @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional - * fields specification. - * @param update the {@link Update} to apply on matching documents. - * @param entityClass the parametrized type. - * @param collectionName the collection to query. - * @return + * fields specification. Must not be {@literal null}. + * @param update the {@link Update} to apply on matching documents. Must not be {@literal null}. + * @param entityClass the parametrized type. Must not be {@literal null}. + * @param collectionName the collection to query. Must not be {@literal null}. + * @return {@literal null} if not found. */ + @Nullable T findAndModify(Query query, Update update, Class entityClass, String collectionName); /** @@ -732,8 +743,9 @@ public interface MongoOperations extends FluentMongoOperations { * @param update the {@link Update} to apply on matching documents. * @param options the {@link FindAndModifyOptions} holding additional information. * @param entityClass the parametrized type. - * @return + * @return {@literal null} if not found. */ + @Nullable T findAndModify(Query query, Update update, FindAndModifyOptions options, Class entityClass); /** @@ -742,13 +754,14 @@ public interface MongoOperations extends FluentMongoOperations { * {@link FindAndModifyOptions} into account. * * @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional - * fields specification. - * @param update the {@link Update} to apply on matching documents. - * @param options the {@link FindAndModifyOptions} holding additional information. - * @param entityClass the parametrized type. - * @param collectionName the collection to query. - * @return + * fields specification. Must not be {@literal null}. + * @param update the {@link Update} to apply on matching documents. Must not be {@literal null}. + * @param options the {@link FindAndModifyOptions} holding additional information. Must not be {@literal null}. + * @param entityClass the parametrized type. Must not be {@literal null}. + * @param collectionName the collection to query. Must not be {@literal null}. + * @return {@literal null} if not found. */ + @Nullable T findAndModify(Query query, Update update, FindAndModifyOptions options, Class entityClass, String collectionName); @@ -767,6 +780,7 @@ public interface MongoOperations extends FluentMongoOperations { * @param entityClass the parametrized type of the returned list. * @return the converted object */ + @Nullable T findAndRemove(Query query, Class entityClass); /** @@ -785,12 +799,13 @@ public interface MongoOperations extends FluentMongoOperations { * @param collectionName name of the collection to retrieve the objects from * @return the converted object */ + @Nullable T findAndRemove(Query query, Class entityClass, String collectionName); /** * Returns the number of documents for the given {@link Query} by querying the collection of the given entity class. * - * @param query + * @param query must not be {@literal null}. * @param entityClass must not be {@literal null}. * @return */ @@ -801,7 +816,7 @@ public interface MongoOperations extends FluentMongoOperations { * must solely consist of document field references as we lack type information to map potential property references * onto document fields. Use {@link #count(Query, Class, String)} to get full type specific support. * - * @param query + * @param query must not be {@literal null}. * @param collectionName must not be {@literal null} or empty. * @return * @see #count(Query, Class, String) @@ -812,12 +827,12 @@ public interface MongoOperations extends FluentMongoOperations { * Returns the number of documents for the given {@link Query} by querying the given collection using the given entity * class to map the given {@link Query}. * - * @param query - * @param entityClass must not be {@literal null}. + * @param query must not be {@literal null}. + * @param entityClass can be be {@literal null}. * @param collectionName must not be {@literal null} or empty. * @return */ - long count(Query query, Class entityClass, String collectionName); + long count(Query query, @Nullable Class entityClass, String collectionName); /** * Insert the object into the collection for the entity type of the object to save. @@ -833,7 +848,7 @@ public interface MongoOperations extends FluentMongoOperations { *

* Insert is used to initially store the object into the database. To update an existing object use the save method. * - * @param objectToSave the object to store in the collection. + * @param objectToSave the object to store in the collection. Must not be {@literal null}. */ void insert(Object objectToSave); @@ -845,24 +860,24 @@ public interface MongoOperations extends FluentMongoOperations { *

* Insert is used to initially store the object into the database. To update an existing object use the save method. * - * @param objectToSave the object to store in the collection - * @param collectionName name of the collection to store the object in + * @param objectToSave the object to store in the collection. Must not be {@literal null}. + * @param collectionName name of the collection to store the object in. Must not be {@literal null}. */ void insert(Object objectToSave, String collectionName); /** * Insert a Collection of objects into a collection in a single batch write to the database. * - * @param batchToSave the list of objects to save. - * @param entityClass class that determines the collection to use + * @param batchToSave the list of objects to save. Must not be {@literal null}. + * @param entityClass class that determines the collection to use. Must not be {@literal null}. */ void insert(Collection batchToSave, Class entityClass); /** * Insert a list of objects into the specified collection in a single batch write to the database. * - * @param batchToSave the list of objects to save. - * @param collectionName name of the collection to store the object in + * @param batchToSave the list of objects to save. Must not be {@literal null}. + * @param collectionName name of the collection to store the object in. Must not be {@literal null}. */ void insert(Collection batchToSave, String collectionName); @@ -870,7 +885,7 @@ public interface MongoOperations extends FluentMongoOperations { * Insert a mixed Collection of objects into a database collection determining the collection name to use based on the * class. * - * @param collectionToSave the list of objects to save. + * @param collectionToSave the list of objects to save. Must not be {@literal null}. */ void insertAll(Collection objectsToSave); @@ -887,7 +902,7 @@ public interface MongoOperations extends FluentMongoOperations { * * Spring's Type Conversion" for more details. * - * @param objectToSave the object to store in the collection + * @param objectToSave the object to store in the collection. Must not be {@literal null}. */ void save(Object objectToSave); @@ -904,8 +919,8 @@ public interface MongoOperations extends FluentMongoOperations { * http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html#core-convert">Spring's * Type Conversion" for more details. * - * @param objectToSave the object to store in the collection - * @param collectionName name of the collection to store the object in + * @param objectToSave the object to store in the collection. Must not be {@literal null}. + * @param collectionName name of the collection to store the object in. Must not be {@literal null}. */ void save(Object objectToSave, String collectionName); @@ -913,9 +928,11 @@ public interface MongoOperations extends FluentMongoOperations { * Performs an upsert. If no document is found that matches the query, a new document is created and inserted by * combining the query document and the update document. * - * @param query the query document that specifies the criteria used to select a record to be upserted - * @param update the update document that contains the updated object or $ operators to manipulate the existing object - * @param entityClass class that determines the collection to use + * @param query the query document that specifies the criteria used to select a record to be upserted. Must not be + * {@literal null}. + * @param update the update document that contains the updated object or $ operators to manipulate the existing + * object. Must not be {@literal null}. + * @param entityClass class that determines the collection to use. Must not be {@literal null}. * @return the WriteResult which lets you access the results of the previous write. */ UpdateResult upsert(Query query, Update update, Class entityClass); @@ -938,10 +955,12 @@ public interface MongoOperations extends FluentMongoOperations { * Performs an upsert. If no document is found that matches the query, a new document is created and inserted by * combining the query document and the update document. * - * @param query the query document that specifies the criteria used to select a record to be upserted - * @param update the update document that contains the updated object or $ operators to manipulate the existing object - * @param entityClass class of the pojo to be operated on - * @param collectionName name of the collection to update the object in + * @param query the query document that specifies the criteria used to select a record to be upserted. Must not be + * {@literal null}. + * @param update the update document that contains the updated object or $ operators to manipulate the existing + * object. Must not be {@literal null}. + * @param entityClass class of the pojo to be operated on. Must not be {@literal null}. + * @param collectionName name of the collection to update the object in. Must not be {@literal null}. * @return the WriteResult which lets you access the results of the previous write. */ UpdateResult upsert(Query query, Update update, Class entityClass, String collectionName); @@ -964,10 +983,11 @@ public interface MongoOperations extends FluentMongoOperations { * NOTE: Any additional support for field mapping, versions, etc. is not available due to the lack of * domain type information. Use {@link #updateFirst(Query, Update, Class, String)} to get full type specific support. * - * @param query the query document that specifies the criteria used to select a record to be updated + * @param query the query document that specifies the criteria used to select a record to be updated. Must not be + * {@literal null}. * @param update the update document that contains the updated object or $ operators to manipulate the existing - * object. - * @param collectionName name of the collection to update the object in + * object. Must not be {@literal null}. + * @param collectionName name of the collection to update the object in. Must not be {@literal null}. * @return the WriteResult which lets you access the results of the previous write. */ UpdateResult updateFirst(Query query, Update update, String collectionName); @@ -976,11 +996,12 @@ public interface MongoOperations extends FluentMongoOperations { * Updates the first object that is found in the specified collection that matches the query document criteria with * the provided updated document. * - * @param query the query document that specifies the criteria used to select a record to be updated + * @param query the query document that specifies the criteria used to select a record to be updated. Must not be + * {@literal null}. * @param update the update document that contains the updated object or $ operators to manipulate the existing - * object. - * @param entityClass class of the pojo to be operated on - * @param collectionName name of the collection to update the object in + * object. Must not be {@literal null}. + * @param entityClass class of the pojo to be operated on. Must not be {@literal null}. + * @param collectionName name of the collection to update the object in. Must not be {@literal null}. * @return the WriteResult which lets you access the results of the previous write. */ UpdateResult updateFirst(Query query, Update update, Class entityClass, String collectionName); @@ -989,10 +1010,11 @@ public interface MongoOperations extends FluentMongoOperations { * Updates all objects that are found in the collection for the entity class that matches the query document criteria * with the provided updated document. * - * @param query the query document that specifies the criteria used to select a record to be updated + * @param query the query document that specifies the criteria used to select a record to be updated. Must not be + * {@literal null}. * @param update the update document that contains the updated object or $ operators to manipulate the existing - * object. - * @param entityClass class that determines the collection to use + * object. Must not be {@literal null}. + * @param entityClass class that determines the collection to use. Must not be {@literal null}. * @return the WriteResult which lets you access the results of the previous write. */ UpdateResult updateMulti(Query query, Update update, Class entityClass); @@ -1003,10 +1025,11 @@ public interface MongoOperations extends FluentMongoOperations { * NOTE: Any additional support for field mapping, versions, etc. is not available due to the lack of * domain type information. Use {@link #updateMulti(Query, Update, Class, String)} to get full type specific support. * - * @param query the query document that specifies the criteria used to select a record to be updated + * @param query the query document that specifies the criteria used to select a record to be updated. Must not be + * {@literal null}. * @param update the update document that contains the updated object or $ operators to manipulate the existing - * object. - * @param collectionName name of the collection to update the object in + * object. Must not be {@literal null}. + * @param collectionName name of the collection to update the object in. Must not be {@literal null}. * @return the WriteResult which lets you access the results of the previous write. */ UpdateResult updateMulti(Query query, Update update, String collectionName); @@ -1015,11 +1038,12 @@ public interface MongoOperations extends FluentMongoOperations { * Updates all objects that are found in the collection for the entity class that matches the query document criteria * with the provided updated document. * - * @param query the query document that specifies the criteria used to select a record to be updated + * @param query the query document that specifies the criteria used to select a record to be updated. Must not be + * {@literal null}. * @param update the update document that contains the updated object or $ operators to manipulate the existing - * object. - * @param entityClass class of the pojo to be operated on - * @param collectionName name of the collection to update the object in + * object. Must not be {@literal null}. + * @param entityClass class of the pojo to be operated on. Must not be {@literal null}. + * @param collectionName name of the collection to update the object in. Must not be {@literal null}. * @return the WriteResult which lets you access the results of the previous write. */ UpdateResult updateMulti(final Query query, final Update update, Class entityClass, String collectionName); @@ -1027,7 +1051,9 @@ public interface MongoOperations extends FluentMongoOperations { /** * Remove the given object from the collection by id. * - * @param object + * @param object must not be {@literal null}. + * @return never {@literal null}. + * @throws IllegalArgumentException when {@code object} to remove is {@literal null}. */ DeleteResult remove(Object object); @@ -1036,6 +1062,7 @@ public interface MongoOperations extends FluentMongoOperations { * * @param object * @param collection must not be {@literal null} or empty. + * @thorws IllegalArgumentException when {@code object} or {@code collection} is {@literal null}. */ DeleteResult remove(Object object, String collection); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoSynchronization.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoSynchronization.java deleted file mode 100644 index 02e48989f..000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoSynchronization.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.core; - -import org.springframework.transaction.support.ResourceHolder; -import org.springframework.transaction.support.ResourceHolderSynchronization; - -/** - * @author Oliver Gierke - */ -class MongoSynchronization extends ResourceHolderSynchronization { - - public MongoSynchronization(ResourceHolder resourceHolder, Object resourceKey) { - super(resourceHolder, resourceKey); - } -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index c1a0c7ebe..991666e65 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -108,6 +108,7 @@ import org.springframework.data.util.Optionals; import org.springframework.data.util.Pair; import org.springframework.data.util.StreamUtils; import org.springframework.jca.cci.core.ConnectionCallback; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -188,13 +189,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, private final UpdateMapper updateMapper; private final SpelAwareProxyProjectionFactory projectionFactory; - private WriteConcern writeConcern; + private @Nullable WriteConcern writeConcern; private WriteConcernResolver writeConcernResolver = DefaultWriteConcernResolver.INSTANCE; private WriteResultChecking writeResultChecking = WriteResultChecking.NONE; - private ReadPreference readPreference; - private ApplicationEventPublisher eventPublisher; - private ResourceLoader resourceLoader; - private MongoPersistentEntityIndexCreator indexCreator; + private @Nullable ReadPreference readPreference; + private @Nullable ApplicationEventPublisher eventPublisher; + private @Nullable ResourceLoader resourceLoader; + private @Nullable MongoPersistentEntityIndexCreator indexCreator; /** * Constructor used for a basic template configuration @@ -221,7 +222,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * @param mongoDbFactory must not be {@literal null}. * @param mongoConverter */ - public MongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter mongoConverter) { + public MongoTemplate(MongoDbFactory mongoDbFactory, @Nullable MongoConverter mongoConverter) { Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null!"); @@ -261,7 +262,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * * @param writeConcern */ - public void setWriteConcern(WriteConcern writeConcern) { + public void setWriteConcern(@Nullable WriteConcern writeConcern) { this.writeConcern = writeConcern; } @@ -270,7 +271,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * * @param writeConcernResolver */ - public void setWriteConcernResolver(WriteConcernResolver writeConcernResolver) { + public void setWriteConcernResolver(@Nullable WriteConcernResolver writeConcernResolver) { this.writeConcernResolver = writeConcernResolver; } @@ -280,7 +281,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * * @param readPreference */ - public void setReadPreference(ReadPreference readPreference) { + public void setReadPreference(@Nullable ReadPreference readPreference) { this.readPreference = readPreference; } @@ -384,12 +385,20 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, }); } + @Override public String getCollectionName(Class entityClass) { return this.determineCollectionName(entityClass); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#executeCommand(java.lang.String) + */ + @Override public Document executeCommand(final String jsonCommand) { + Assert.hasText(jsonCommand, "JsonCommand must not be null nor empty!"); + return execute(new DbCallback() { public Document doInDB(MongoDatabase db) throws MongoException, DataAccessException { return db.runCommand(Document.parse(jsonCommand), Document.class); @@ -397,8 +406,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, }); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#executeCommand(org.bson.Document) + */ + @Override public Document executeCommand(final Document command) { + Assert.notNull(command, "Command must not be null!"); + Document result = execute(new DbCallback() { public Document doInDB(MongoDatabase db) throws MongoException, DataAccessException { return db.runCommand(command, Document.class); @@ -410,9 +426,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, /* * (non-Javadoc) - * @see org.springframework.data.mongodb.core.MongoOperations#executeCommand(com.mongodb.Document, com.mongodb.ReadPreference) + * @see org.springframework.data.mongodb.core.MongoOperations#executeCommand(org.bson.Document, com.mongodb.ReadPreference) */ - public Document executeCommand(final Document command, final ReadPreference readPreference) { + @Override + public Document executeCommand(Document command, @Nullable ReadPreference readPreference) { Assert.notNull(command, "Command must not be null!"); @@ -426,6 +443,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, return result; } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#executeQuery(org.springframework.data.mongodb.core.query.Query, java.lang.String, org.springframework.data.mongodb.core.DocumentCallbackHandler) + */ + @Override public void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch) { executeQuery(query, collectionName, dch, new QueryCursorPreparer(query, null)); } @@ -437,14 +459,16 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * @param query the query class that specifies the criteria used to find a record and also an optional fields * specification, must not be {@literal null}. * @param collectionName name of the collection to retrieve the objects from - * @param dch the handler that will extract results, one document at a time + * @param documentCallbackHandler the handler that will extract results, one document at a time * @param preparer allows for customization of the {@link DBCursor} used when iterating over the result set, (apply * limits, skips and so on). */ - protected void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch, - CursorPreparer preparer) { + protected void executeQuery(Query query, String collectionName, DocumentCallbackHandler documentCallbackHandler, + @Nullable CursorPreparer preparer) { Assert.notNull(query, "Query must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); + Assert.notNull(documentCallbackHandler, "DocumentCallbackHandler must not be null!"); Document queryObject = queryMapper.getMappedObject(query.getQueryObject(), Optional.empty()); Document sortObject = query.getSortObject(); @@ -455,9 +479,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, sortObject, fieldsObject, collectionName); } - this.executeQueryInternal(new FindCallback(queryObject, fieldsObject), preparer, dch, collectionName); + this.executeQueryInternal(new FindCallback(queryObject, fieldsObject), preparer, documentCallbackHandler, + collectionName); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#execute(org.springframework.data.mongodb.core.DbCallback) + */ public T execute(DbCallback action) { Assert.notNull(action, "DbCallbackmust not be null!"); @@ -470,12 +499,23 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#execute(java.lang.Class, org.springframework.data.mongodb.core.DbCallback) + */ public T execute(Class entityClass, CollectionCallback callback) { + + Assert.notNull(entityClass, "EntityClass must not be null!"); return execute(determineCollectionName(entityClass), callback); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#execute(java.lang.String, org.springframework.data.mongodb.core.DbCallback) + */ public T execute(String collectionName, CollectionCallback callback) { + Assert.notNull(collectionName, "CollectionName must not be null!"); Assert.notNull(callback, "CollectionCallback must not be null!"); try { @@ -486,24 +526,53 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#createCollection(java.lang.Class) + */ public MongoCollection createCollection(Class entityClass) { return createCollection(determineCollectionName(entityClass)); } - public MongoCollection createCollection(Class entityClass, CollectionOptions collectionOptions) { + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#createCollection(java.lang.Class, org.springframework.data.mongodb.core.CollectionOptions) + */ + public MongoCollection createCollection(Class entityClass, + @Nullable CollectionOptions collectionOptions) { return createCollection(determineCollectionName(entityClass), collectionOptions); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#createCollection(java.lang.String) + */ public MongoCollection createCollection(final String collectionName) { + + Assert.notNull(collectionName, "CollectionName must not be null!"); + return doCreateCollection(collectionName, new Document()); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#createCollection(java.lang.String, org.springframework.data.mongodb.core.CollectionOptions) + */ public MongoCollection createCollection(final String collectionName, - final CollectionOptions collectionOptions) { + final @Nullable CollectionOptions collectionOptions) { + + Assert.notNull(collectionName, "CollectionName must not be null!"); return doCreateCollection(collectionName, convertToDocument(collectionOptions)); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#getCollection(java.lang.String) + */ public MongoCollection getCollection(final String collectionName) { + + Assert.notNull(collectionName, "CollectionName must not be null!"); + return execute(new DbCallback>() { public MongoCollection doInDB(MongoDatabase db) throws MongoException, DataAccessException { return db.getCollection(collectionName, Document.class); @@ -511,11 +580,22 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, }); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#getCollection(java.lang.Class) + */ public boolean collectionExists(Class entityClass) { return collectionExists(determineCollectionName(entityClass)); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#getCollection(java.lang.String) + */ public boolean collectionExists(final String collectionName) { + + Assert.notNull(collectionName, "CollectionName must not be null!"); + return execute(new DbCallback() { public Boolean doInDB(MongoDatabase db) throws MongoException, DataAccessException { for (String name : db.listCollectionNames()) { @@ -528,11 +608,22 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, }); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#dropCollection(java.lang.Class) + */ public void dropCollection(Class entityClass) { dropCollection(determineCollectionName(entityClass)); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#dropCollection(java.lang.String) + */ public void dropCollection(String collectionName) { + + Assert.notNull(collectionName, "CollectionName must not be null!"); + execute(collectionName, new CollectionCallback() { public Void doInCollection(MongoCollection collection) throws MongoException, DataAccessException { collection.drop(); @@ -544,24 +635,44 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, }); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#indexOps(java.lang.String) + */ public IndexOperations indexOps(String collectionName) { return new DefaultIndexOperations(getMongoDbFactory(), collectionName, queryMapper); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#indexOps(java.lang.Class) + */ public IndexOperations indexOps(Class entityClass) { return new DefaultIndexOperations(getMongoDbFactory(), determineCollectionName(entityClass), queryMapper, entityClass); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#bulkOps(org.springframework.data.mongodb.core.BulkMode, java.lang.String) + */ public BulkOperations bulkOps(BulkMode bulkMode, String collectionName) { return bulkOps(bulkMode, null, collectionName); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#bulkOps(org.springframework.data.mongodb.core.BulkMode, java.lang.Class) + */ public BulkOperations bulkOps(BulkMode bulkMode, Class entityClass) { return bulkOps(bulkMode, entityClass, determineCollectionName(entityClass)); } - public BulkOperations bulkOps(BulkMode mode, Class entityType, String collectionName) { + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#bulkOps(org.springframework.data.mongodb.core.BulkMode, java.lang.Class, java.lang.String) + */ + public BulkOperations bulkOps(BulkMode mode, @Nullable Class entityType, String collectionName) { Assert.notNull(mode, "BulkMode must not be null!"); Assert.hasText(collectionName, "Collection name must not be null or empty!"); @@ -586,12 +697,20 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, // Find methods that take a Query to express the query and that return a single object. + @Nullable + @Override public T findOne(Query query, Class entityClass) { return findOne(query, entityClass, determineCollectionName(entityClass)); } + @Nullable + @Override public T findOne(Query query, Class entityClass, String collectionName) { + Assert.notNull(query, "Query must not be null!"); + Assert.notNull(entityClass, "EntityClass must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); + if (ObjectUtils.isEmpty(query.getSortObject()) && !query.getCollation().isPresent()) { return doFindOne(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass); } else { @@ -601,19 +720,23 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } } + @Override public boolean exists(Query query, Class entityClass) { return exists(query, entityClass, determineCollectionName(entityClass)); } + @Override public boolean exists(Query query, String collectionName) { return exists(query, null, collectionName); } - public boolean exists(Query query, Class entityClass, String collectionName) { + @Override + public boolean exists(Query query, @Nullable Class entityClass, String collectionName) { if (query == null) { throw new InvalidDataAccessApiUsageException("Query passed in to exist can't be null"); } + Assert.notNull(collectionName, "CollectionName must not be null!"); Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), getPersistentEntity(entityClass)); @@ -623,13 +746,27 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, // Find methods that take a Query to express the query and that return a List of objects. + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#findOne(org.springframework.data.mongodb.core.query.Query, java.lang.Class) + */ + @Override public List find(Query query, Class entityClass) { return find(query, entityClass, determineCollectionName(entityClass)); } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.MongoOperations#findOne(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String) + */ + @Override public List find(final Query query, Class entityClass, String collectionName) { - if (query == null) { + Assert.notNull(query, "Query must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); + Assert.notNull(entityClass, "EntityClass must not be null!"); + + if (query.getQueryObject().isEmpty() && query.getSortObject().isEmpty()) { return findAll(entityClass, collectionName); } @@ -637,27 +774,38 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, new QueryCursorPreparer(query, entityClass)); } + @Nullable + @Override public T findById(Object id, Class entityClass) { return findById(id, entityClass, determineCollectionName(entityClass)); } + @Nullable + @Override public T findById(Object id, Class entityClass, String collectionName) { + Assert.notNull(id, "Id must not be null!"); + Assert.notNull(entityClass, "EntityClass must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); + MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(entityClass); String idKey = ID_FIELD; + if (persistentEntity != null) { if (persistentEntity.getIdProperty() != null) { idKey = persistentEntity.getIdProperty().getName(); } } - return doFindOne(collectionName, new Document(idKey, id), null, entityClass); + return doFindOne(collectionName, new Document(idKey, id), new Document(), entityClass); } + @Override public GeoResults geoNear(NearQuery near, Class entityClass) { return geoNear(near, entityClass, determineCollectionName(entityClass)); } + @Override @SuppressWarnings("unchecked") public GeoResults geoNear(NearQuery near, Class domainType, String collectionName) { return geoNear(near, domainType, collectionName, domainType); @@ -673,6 +821,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, throw new InvalidDataAccessApiUsageException("Entity class must not be null!"); } + Assert.notNull(collectionName, "CollectionName must not be null!"); + Assert.notNull(returnType, "ReturnType must not be null!"); + String collection = StringUtils.hasText(collectionName) ? collectionName : determineCollectionName(domainType); Document nearDocument = near.toDocument(); @@ -723,21 +874,35 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, return new GeoResults(result, new Distance(stats.getAverageDistance(), near.getMetric())); } + @Nullable + @Override public T findAndModify(Query query, Update update, Class entityClass) { return findAndModify(query, update, new FindAndModifyOptions(), entityClass, determineCollectionName(entityClass)); } + @Nullable + @Override public T findAndModify(Query query, Update update, Class entityClass, String collectionName) { return findAndModify(query, update, new FindAndModifyOptions(), entityClass, collectionName); } + @Nullable + @Override public T findAndModify(Query query, Update update, FindAndModifyOptions options, Class entityClass) { return findAndModify(query, update, options, entityClass, determineCollectionName(entityClass)); } + @Nullable + @Override public T findAndModify(Query query, Update update, FindAndModifyOptions options, Class entityClass, String collectionName) { + Assert.notNull(query, "Query must not be null!"); + Assert.notNull(update, "Update must not be null!"); + Assert.notNull(options, "Options must not be null!"); + Assert.notNull(entityClass, "EntityClass must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); + FindAndModifyOptions optionsToUse = FindAndModifyOptions.of(options); Optionals.ifAllPresent(query.getCollation(), optionsToUse.getCollation(), (l, r) -> { @@ -754,22 +919,32 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, // Find methods that take a Query to express the query and that return a single object that is also removed from the // collection in the database. + @Nullable + @Override public T findAndRemove(Query query, Class entityClass) { return findAndRemove(query, entityClass, determineCollectionName(entityClass)); } + @Nullable + @Override public T findAndRemove(Query query, Class entityClass, String collectionName) { + Assert.notNull(query, "Query must not be null!"); + Assert.notNull(entityClass, "EntityClass must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); + return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(), getMappedSortObject(query, entityClass), query.getCollation().orElse(null), entityClass); } + @Override public long count(Query query, Class entityClass) { Assert.notNull(entityClass, "Entity class must not be null!"); return count(query, entityClass, determineCollectionName(entityClass)); } + @Override public long count(final Query query, String collectionName) { return count(query, null, collectionName); } @@ -778,13 +953,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * (non-Javadoc) * @see org.springframework.data.mongodb.core.MongoOperations#count(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String) */ - public long count(Query query, Class entityClass, String collectionName) { + public long count(Query query, @Nullable Class entityClass, String collectionName) { + Assert.notNull(query, "Query must not be null!"); Assert.hasText(collectionName, "Collection name must not be null or empty!"); - Document document = query == null ? null - : queryMapper.getMappedObject(query.getQueryObject(), - Optional.ofNullable(entityClass).map(it -> mappingContext.getPersistentEntity(entityClass))); + Document document = queryMapper.getMappedObject(query.getQueryObject(), + Optional.ofNullable(entityClass).map(it -> mappingContext.getPersistentEntity(entityClass))); return execute(collectionName, collection -> collection.count(document)); } @@ -793,7 +968,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * (non-Javadoc) * @see org.springframework.data.mongodb.core.MongoOperations#insert(java.lang.Object) */ + @Override public void insert(Object objectToSave) { + + Assert.notNull(objectToSave, "ObjectToSave must not be null!"); + ensureNotIterable(objectToSave); insert(objectToSave, determineEntityCollectionName(objectToSave)); } @@ -802,7 +981,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * (non-Javadoc) * @see org.springframework.data.mongodb.core.MongoOperations#insert(java.lang.Object, java.lang.String) */ + @Override public void insert(Object objectToSave, String collectionName) { + + Assert.notNull(objectToSave, "ObjectToSave must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); + ensureNotIterable(objectToSave); doInsert(collectionName, objectToSave, this.mongoConverter); } @@ -838,13 +1022,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * @param writeConcern any WriteConcern already configured or null * @return The prepared WriteConcern or null */ + @Nullable protected WriteConcern prepareWriteConcern(MongoAction mongoAction) { WriteConcern wc = writeConcernResolver.resolve(mongoAction); return potentiallyForceAcknowledgedWrite(wc); } - private WriteConcern potentiallyForceAcknowledgedWrite(WriteConcern wc) { + @Nullable + private WriteConcern potentiallyForceAcknowledgedWrite(@Nullable WriteConcern wc) { if (ObjectUtils.nullSafeEquals(WriteResultChecking.EXCEPTION, writeResultChecking) && MongoClientVersion.isMongo3Driver()) { @@ -915,15 +1101,27 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } } + @Override public void insert(Collection batchToSave, Class entityClass) { + + Assert.notNull(batchToSave, "BatchToSave must not be null!"); + doInsertBatch(determineCollectionName(entityClass), batchToSave, this.mongoConverter); } + @Override public void insert(Collection batchToSave, String collectionName) { + + Assert.notNull(batchToSave, "BatchToSave must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); + doInsertBatch(collectionName, batchToSave, this.mongoConverter); } + @Override public void insertAll(Collection objectsToSave) { + + Assert.notNull(objectsToSave, "ObjectsToSave must not be null!"); doInsertAll(objectsToSave, this.mongoConverter); } @@ -983,12 +1181,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } } + @Override public void save(Object objectToSave) { Assert.notNull(objectToSave, "Object to save must not be null!"); save(objectToSave, determineEntityCollectionName(objectToSave)); } + @Override public void save(Object objectToSave, String collectionName) { Assert.notNull(objectToSave, "Object to save must not be null!"); @@ -1042,7 +1242,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, maybeEmitEvent(new AfterSaveEvent(objectToSave, document, collectionName)); return objectToSave; - } doInsert(collectionName, objectToSave, this.mongoConverter); @@ -1134,9 +1333,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } else { collection.withWriteConcern(writeConcernToUse).insertOne(dbDoc); } - } - - else if (writeConcernToUse == null) { + } else if (writeConcernToUse == null) { collection.replaceOne(Filters.eq(ID_FIELD, dbDoc.get(ID_FIELD)), dbDoc, new UpdateOptions().upsert(true)); } else { collection.withWriteConcern(writeConcernToUse).replaceOne(Filters.eq(ID_FIELD, dbDoc.get(ID_FIELD)), dbDoc, @@ -1147,44 +1344,66 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, }); } + @Override public UpdateResult upsert(Query query, Update update, Class entityClass) { return doUpdate(determineCollectionName(entityClass), query, update, entityClass, true, false); } + @Override public UpdateResult upsert(Query query, Update update, String collectionName) { return doUpdate(collectionName, query, update, null, true, false); } + @Override public UpdateResult upsert(Query query, Update update, Class entityClass, String collectionName) { + + Assert.notNull(entityClass, "EntityClass must not be null!"); + return doUpdate(collectionName, query, update, entityClass, true, false); } + @Override public UpdateResult updateFirst(Query query, Update update, Class entityClass) { return doUpdate(determineCollectionName(entityClass), query, update, entityClass, false, false); } + @Override public UpdateResult updateFirst(final Query query, final Update update, final String collectionName) { return doUpdate(collectionName, query, update, null, false, false); } + @Override public UpdateResult updateFirst(Query query, Update update, Class entityClass, String collectionName) { + + Assert.notNull(entityClass, "EntityClass must not be null!"); + return doUpdate(collectionName, query, update, entityClass, false, false); } + @Override public UpdateResult updateMulti(Query query, Update update, Class entityClass) { return doUpdate(determineCollectionName(entityClass), query, update, entityClass, false, true); } + @Override public UpdateResult updateMulti(final Query query, final Update update, String collectionName) { return doUpdate(collectionName, query, update, null, false, true); } + @Override public UpdateResult updateMulti(final Query query, final Update update, Class entityClass, String collectionName) { + + Assert.notNull(entityClass, "EntityClass must not be null!"); + return doUpdate(collectionName, query, update, entityClass, false, true); } protected UpdateResult doUpdate(final String collectionName, final Query query, final Update update, - final Class entityClass, final boolean upsert, final boolean multi) { + @Nullable final Class entityClass, final boolean upsert, final boolean multi) { + + Assert.notNull(collectionName, "CollectionName must not be null!"); + Assert.notNull(query, "Query must not be null!"); + Assert.notNull(update, "Update must not be null!"); return execute(collectionName, new CollectionCallback() { public UpdateResult doInCollection(MongoCollection collection) @@ -1258,23 +1477,20 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, return false; } + @Override public DeleteResult remove(Object object) { - if (object == null) { - return null; - } + Assert.notNull(object, "Object must not be null!"); return remove(getIdQueryFor(object), object.getClass()); } + @Override public DeleteResult remove(Object object, String collection) { + Assert.notNull(object, "Object must not be null!"); Assert.hasText(collection, "Collection name must not be null or empty!"); - if (object == null) { - return null; - } - return doRemove(collection, getIdQueryFor(object), object.getClass()); } @@ -1362,26 +1578,31 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } } + @Override public DeleteResult remove(Query query, String collectionName) { - return remove(query, null, collectionName); + return doRemove(collectionName, query, null); } + @Override public DeleteResult remove(Query query, Class entityClass) { return remove(query, entityClass, determineCollectionName(entityClass)); } + @Override public DeleteResult remove(Query query, Class entityClass, String collectionName) { + + Assert.notNull(entityClass, "EntityClass must not be null!"); return doRemove(collectionName, query, entityClass); } - protected DeleteResult doRemove(final String collectionName, final Query query, final Class entityClass) { + protected DeleteResult doRemove(final String collectionName, final Query query, + @Nullable final Class entityClass) { + Assert.hasText(collectionName, "Collection name must not be null or empty!"); if (query == null) { throw new InvalidDataAccessApiUsageException("Query passed in to remove can't be null!"); } - Assert.hasText(collectionName, "Collection name must not be null or empty!"); - final Document queryObject = query.getQueryObject(); final MongoPersistentEntity entity = getPersistentEntity(entityClass); @@ -1422,34 +1643,46 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, }); } + @Override public List findAll(Class entityClass) { return findAll(entityClass, determineCollectionName(entityClass)); } + @Override public List findAll(Class entityClass, String collectionName) { - return executeFindMultiInternal(new FindCallback(null, null), null, + return executeFindMultiInternal(new FindCallback(new Document(), new Document()), null, new ReadDocumentCallback(mongoConverter, entityClass, collectionName), collectionName); } + @Override public MapReduceResults mapReduce(String inputCollectionName, String mapFunction, String reduceFunction, Class entityClass) { - return mapReduce(null, inputCollectionName, mapFunction, reduceFunction, new MapReduceOptions().outputTypeInline(), - entityClass); + return mapReduce(new Query(), inputCollectionName, mapFunction, reduceFunction, + new MapReduceOptions().outputTypeInline(), entityClass); } + @Override public MapReduceResults mapReduce(String inputCollectionName, String mapFunction, String reduceFunction, - MapReduceOptions mapReduceOptions, Class entityClass) { - return mapReduce(null, inputCollectionName, mapFunction, reduceFunction, mapReduceOptions, entityClass); + @Nullable MapReduceOptions mapReduceOptions, Class entityClass) { + return mapReduce(new Query(), inputCollectionName, mapFunction, reduceFunction, mapReduceOptions, entityClass); } + @Override public MapReduceResults mapReduce(Query query, String inputCollectionName, String mapFunction, String reduceFunction, Class entityClass) { return mapReduce(query, inputCollectionName, mapFunction, reduceFunction, new MapReduceOptions().outputTypeInline(), entityClass); } + @Override public MapReduceResults mapReduce(Query query, String inputCollectionName, String mapFunction, - String reduceFunction, MapReduceOptions mapReduceOptions, Class entityClass) { + String reduceFunction, @Nullable MapReduceOptions mapReduceOptions, Class entityClass) { + + Assert.notNull(query, "Query must not be null!"); + Assert.notNull(inputCollectionName, "InputCollectionName must not be null!"); + Assert.notNull(entityClass, "EntityClass must not be null!"); + Assert.notNull(reduceFunction, "ReduceFunction must not be null!"); + Assert.notNull(mapFunction, "MapFunction must not be null!"); String mapFunc = replaceWithResourceIfNecessary(mapFunction); String reduceFunc = replaceWithResourceIfNecessary(reduceFunction); @@ -1465,12 +1698,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, if (query.getMeta() != null && query.getMeta().getMaxTimeMsec() != null) { result = result.maxTime(query.getMeta().getMaxTimeMsec(), TimeUnit.MILLISECONDS); } - result = result.sort(query.getSortObject()); + result = result.sort(getMappedSortObject(query, entityClass)); result = result.filter(queryMapper.getMappedObject(query.getQueryObject(), Optional.empty())); } - Optional collation = query != null ? query.getCollation() : Optional.empty(); + Optional collation = query.getCollation(); if (mapReduceOptions != null) { @@ -1516,7 +1749,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, return group(null, inputCollectionName, groupBy, entityClass); } - public GroupByResults group(Criteria criteria, String inputCollectionName, GroupBy groupBy, + public GroupByResults group(@Nullable Criteria criteria, String inputCollectionName, GroupBy groupBy, Class entityClass) { Document document = groupBy.getGroupByObject(); @@ -1698,7 +1931,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } protected AggregationResults aggregate(Aggregation aggregation, String collectionName, Class outputType, - AggregationOperationContext context) { + @Nullable AggregationOperationContext context) { Assert.hasText(collectionName, "Collection name must not be null or empty!"); Assert.notNull(aggregation, "Aggregation pipeline must not be null!"); @@ -1744,7 +1977,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } protected CloseableIterator aggregateStream(Aggregation aggregation, String collectionName, - Class outputType, AggregationOperationContext context) { + Class outputType, @Nullable AggregationOperationContext context) { Assert.hasText(collectionName, "Collection name must not be null or empty!"); Assert.notNull(aggregation, "Aggregation pipeline must not be null!"); @@ -1877,6 +2110,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, return func; } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#getCollectionNames() + */ public Set getCollectionNames() { return execute(new DbCallback>() { public Set doInDB(MongoDatabase db) throws MongoException, DataAccessException { @@ -2000,7 +2237,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } protected List doFind(String collectionName, Document query, Document fields, Class entityClass, - CursorPreparer preparer, DocumentCallback objectCallback) { + @Nullable CursorPreparer preparer, DocumentCallback objectCallback) { MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); @@ -2039,7 +2276,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, new ProjectingReadCallback<>(mongoConverter, sourceClass, targetClass, collectionName), collectionName); } - protected Document convertToDocument(CollectionOptions collectionOptions) { + protected Document convertToDocument(@Nullable CollectionOptions collectionOptions) { Document document = new Document(); if (collectionOptions != null) { @@ -2064,7 +2301,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * @return the List of converted objects. */ protected T doFindAndRemove(String collectionName, Document query, Document fields, Document sort, - Collation collation, Class entityClass) { + @Nullable Collation collation, Class entityClass) { EntityReader readerToUse = this.mongoConverter; @@ -2189,13 +2426,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * * @param * @param collectionCallback the callback to retrieve the {@link DBCursor} with - * @param preparer the {@link CursorPreparer} to potentially modify the {@link DBCursor} before ireating over it + * @param preparer the {@link CursorPreparer} to potentially modify the {@link DBCursor} before iterating over it * @param objectCallback the {@link DocumentCallback} to transform {@link Document}s into the actual domain type * @param collectionName the collection to be queried * @return */ private List executeFindMultiInternal(CollectionCallback> collectionCallback, - CursorPreparer preparer, DocumentCallback objectCallback, String collectionName) { + @Nullable CursorPreparer preparer, DocumentCallback objectCallback, String collectionName) { try { @@ -2220,7 +2457,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } return result; - } finally { if (cursor != null) { @@ -2252,13 +2488,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, while (cursor.hasNext()) { callbackHandler.processDocument(cursor.next()); } - } finally { if (cursor != null) { cursor.close(); } } - } catch (RuntimeException e) { throw potentiallyConvertRuntimeException(e, exceptionTranslator); } @@ -2268,7 +2502,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, return exceptionTranslator; } - private MongoPersistentEntity getPersistentEntity(Class type) { + private MongoPersistentEntity getPersistentEntity(@Nullable Class type) { return type != null ? mappingContext.getPersistentEntity(type) : null; } @@ -2413,24 +2647,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, private static class FindCallback implements CollectionCallback> { private final Document query; - private final Optional fields; + private final Document fields; public FindCallback(Document query) { - this(query, null); + this(query, new Document()); } public FindCallback(Document query, Document fields) { - this.query = query != null ? query : new Document(); - this.fields = Optional.ofNullable(fields).filter(it -> !ObjectUtils.isEmpty(fields)); + Assert.notNull(query, "Query must not be null!"); + Assert.notNull(fields, "Fields must not be null!"); + + this.query = query; + this.fields = fields; } public FindIterable doInCollection(MongoCollection collection) throws MongoException, DataAccessException { - FindIterable iterable = collection.find(query); - - return fields.filter(val -> !val.isEmpty()).map(iterable::projection).orElse(iterable); + return collection.find(query).projection(fields); } } @@ -2527,7 +2762,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, interface DocumentCallback { - T doWith(Document object); + @Nullable + T doWith(@Nullable Document object); } /** @@ -2553,7 +2789,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, this.collectionName = collectionName; } - public T doWith(Document object) { + @Nullable + public T doWith(@Nullable Document object) { if (null != object) { maybeEmitEvent(new AfterLoadEvent(object, type, collectionName)); } @@ -2586,7 +2823,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * @see org.springframework.data.mongodb.core.MongoTemplate.DocumentCallback#doWith(org.bson.Document) */ @SuppressWarnings("unchecked") - public T doWith(Document object) { + @Nullable + public T doWith(@Nullable Document object) { if (object == null) { return null; @@ -2612,7 +2850,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } @Override - public T doWith(Document object) { + public T doWith(@Nullable Document object) { + + if (object == null) { + return null; + } Object idField = object.get(Fields.UNDERSCORE_ID); @@ -2639,7 +2881,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, private final Query query; private final Class type; - public QueryCursorPreparer(Query query, Class type) { + public QueryCursorPreparer(@Nullable Query query, @Nullable Class type) { this.query = query; this.type = type; @@ -2705,7 +2947,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, } cursorToUse = cursorToUse.modifiers(meta); - } catch (RuntimeException e) { throw potentiallyConvertRuntimeException(e, exceptionTranslator); } @@ -2739,7 +2980,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, this.metric = metric; } - public GeoResult doWith(Document object) { + @Nullable + public GeoResult doWith(@Nullable Document object) { double distance = ((Double) object.get("dis")).doubleValue(); Document content = (Document) object.get("obj"); @@ -2753,8 +2995,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, /** * A {@link CloseableIterator} that is backed by a MongoDB {@link Cursor}. * - * @since 1.7 * @author Thomas Darimont + * @since 1.7 */ @AllArgsConstructor(access = AccessLevel.PACKAGE) static class CloseableIterableCursorAdapter implements CloseableIterator { @@ -2818,7 +3060,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, if (c != null) { c.close(); } - } catch (RuntimeException ex) { throw potentiallyConvertRuntimeException(ex, exceptionTranslator); } finally { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupport.java index 93d31f7ad..dda069778 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupport.java @@ -19,6 +19,7 @@ import lombok.AccessLevel; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.experimental.FieldDefaults; +import org.springframework.lang.Nullable; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -195,7 +196,7 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation { return template.exists(query, domainType, getCollectionName()); } - private Flux doFind(FindPublisherPreparer preparer) { + private Flux doFind(@Nullable FindPublisherPreparer preparer) { Document queryObject = query.getQueryObject(); Document fieldsObject = query.getFieldsObject(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoClientFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoClientFactoryBean.java index 1ae18fda9..bb0f1b655 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoClientFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoClientFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ package org.springframework.data.mongodb.core; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; +import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; import com.mongodb.async.client.MongoClientSettings; @@ -37,10 +38,10 @@ public class ReactiveMongoClientFactoryBean extends AbstractFactoryBean executeCommand(Document command, ReadPreference readPreference); + Mono executeCommand(Document command, @Nullable ReadPreference readPreference); /** * Executes a {@link ReactiveDatabaseCallback} translating any exceptions as necessary. @@ -312,11 +313,11 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations { * Determine result of given {@link Query} contains at least one element. * * @param query the {@link Query} class that specifies the criteria used to find a record. - * @param entityClass the parametrized type. + * @param entityClass the parametrized type. Can be {@literal null}. * @param collectionName name of the collection to check for objects. * @return */ - Mono exists(Query query, Class entityClass, String collectionName); + Mono exists(Query query, @Nullable Class entityClass, String collectionName); /** * Map the results of an ad-hoc query on the collection for the entity class to a {@link Flux} of the specified type. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java index 14ac474e6..117943bf0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java @@ -20,8 +20,6 @@ import static org.springframework.data.mongodb.core.query.SerializationUtils.*; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import org.springframework.data.projection.ProjectionInformation; -import org.springframework.util.ClassUtils; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -40,6 +38,8 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; +import javax.annotation.Nonnull; + import org.bson.Document; import org.bson.conversions.Bson; import org.bson.types.ObjectId; @@ -105,10 +105,13 @@ import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.util.MongoClientVersion; +import org.springframework.data.projection.ProjectionInformation; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.util.Optionals; import org.springframework.data.util.Pair; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -179,12 +182,12 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati private final UpdateMapper updateMapper; private final SpelAwareProxyProjectionFactory projectionFactory; - private WriteConcern writeConcern; + private @Nullable WriteConcern writeConcern; private WriteConcernResolver writeConcernResolver = DefaultWriteConcernResolver.INSTANCE; private WriteResultChecking writeResultChecking = WriteResultChecking.NONE; - private ReadPreference readPreference; - private ApplicationEventPublisher eventPublisher; - private MongoPersistentEntityIndexCreator indexCreator; + private @Nullable ReadPreference readPreference; + private @Nullable ApplicationEventPublisher eventPublisher; + private @Nullable MongoPersistentEntityIndexCreator indexCreator; /** * Constructor used for a basic template configuration. @@ -209,9 +212,10 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * Constructor used for a basic template configuration. * * @param mongoDatabaseFactory must not be {@literal null}. - * @param mongoConverter + * @param mongoConverter can be {@literal null}. */ - public ReactiveMongoTemplate(ReactiveMongoDatabaseFactory mongoDatabaseFactory, MongoConverter mongoConverter) { + public ReactiveMongoTemplate(ReactiveMongoDatabaseFactory mongoDatabaseFactory, + @Nullable MongoConverter mongoConverter) { Assert.notNull(mongoDatabaseFactory, "ReactiveMongoDatabaseFactory must not be null!"); @@ -242,7 +246,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * * @param resultChecking */ - public void setWriteResultChecking(WriteResultChecking resultChecking) { + public void setWriteResultChecking(@Nullable WriteResultChecking resultChecking) { this.writeResultChecking = resultChecking == null ? DEFAULT_WRITE_RESULT_CHECKING : resultChecking; } @@ -251,18 +255,18 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * configured on the {@link MongoDbFactory} will apply. If you configured a {@link Mongo} instance no * {@link WriteConcern} will be used. * - * @param writeConcern + * @param writeConcern can be {@literal null}. */ - public void setWriteConcern(WriteConcern writeConcern) { + public void setWriteConcern(@Nullable WriteConcern writeConcern) { this.writeConcern = writeConcern; } /** * Configures the {@link WriteConcernResolver} to be used with the template. * - * @param writeConcernResolver + * @param writeConcernResolver can be {@literal null}. */ - public void setWriteConcernResolver(WriteConcernResolver writeConcernResolver) { + public void setWriteConcernResolver(@Nullable WriteConcernResolver writeConcernResolver) { this.writeConcernResolver = writeConcernResolver; } @@ -370,7 +374,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * (non-Javadoc) * @see org.springframework.data.mongodb.core.ReactiveMongoOperations#executeCommand(org.bson.Document, com.mongodb.ReadPreference) */ - public Mono executeCommand(final Document command, final ReadPreference readPreference) { + public Mono executeCommand(final Document command, @Nullable ReadPreference readPreference) { Assert.notNull(command, "Command must not be null!"); @@ -609,7 +613,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * (non-Javadoc) * @see org.springframework.data.mongodb.core.ReactiveMongoOperations#exists(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String) */ - public Mono exists(final Query query, final Class entityClass, String collectionName) { + public Mono exists(final Query query, @Nullable Class entityClass, String collectionName) { if (query == null) { throw new InvalidDataAccessApiUsageException("Query passed in to exist can't be null"); @@ -722,7 +726,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * @return never {@literal null}. */ protected Flux aggregate(Aggregation aggregation, String collectionName, Class outputType, - AggregationOperationContext context) { + @Nullable AggregationOperationContext context) { Assert.notNull(aggregation, "Aggregation pipeline must not be null!"); Assert.hasText(collectionName, "Collection name must not be null or empty!"); @@ -904,7 +908,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * (non-Javadoc) * @see org.springframework.data.mongodb.core.ReactiveMongoOperations#count(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String) */ - public Mono count(final Query query, final Class entityClass, String collectionName) { + public Mono count(final Query query, @Nullable Class entityClass, String collectionName) { Assert.hasText(collectionName, "Collection name must not be null or empty!"); @@ -1051,7 +1055,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati Mono>> prepareDocuments = Flux.fromIterable(batchToSave) .flatMap(new Function>>() { @Override - public Flux> apply(T o) { + public Flux> apply(@Nullable T o) { initializeVersionProperty(o); maybeEmitEvent(new BeforeConvertEvent(o, collectionName)); @@ -1356,7 +1360,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati } protected Mono doUpdate(final String collectionName, final Query query, final Update update, - final Class entityClass, final boolean upsert, final boolean multi) { + @Nullable Class entityClass, final boolean upsert, final boolean multi) { MongoPersistentEntity entity = entityClass == null ? null : getPersistentEntity(entityClass); @@ -1578,7 +1582,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * (non-Javadoc) * @see org.springframework.data.mongodb.core.ReactiveMongoOperations#remove(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String) */ - public Mono remove(Query query, Class entityClass, String collectionName) { + public Mono remove(Query query, @Nullable Class entityClass, String collectionName) { return doRemove(collectionName, query, entityClass); } @@ -1663,7 +1667,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findAllAndRemove(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String) */ @Override - public Flux findAllAndRemove(Query query, Class entityClass, String collectionName) { + public Flux findAllAndRemove(Query query, @Nullable Class entityClass, String collectionName) { return doFindAndDelete(collectionName, query, entityClass); } @@ -1789,10 +1793,11 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * @param query the query document that specifies the criteria used to find a record. * @param fields the document that specifies the fields to be returned. * @param entityClass the parameterized type of the returned list. + * @param collation can be {@literal null}. * @return the {@link List} of converted objects. */ - protected Mono doFindOne(String collectionName, Document query, Document fields, Class entityClass, - Collation collation) { + protected Mono doFindOne(String collectionName, Document query, @Nullable Document fields, + Class entityClass, @Nullable Collation collation) { MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); Document mappedQuery = queryMapper.getMappedObject(query, entity); @@ -1842,7 +1847,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati } protected Flux doFind(String collectionName, Document query, Document fields, Class entityClass, - FindPublisherPreparer preparer, DocumentCallback objectCallback) { + @Nullable FindPublisherPreparer preparer, DocumentCallback objectCallback) { MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); @@ -2128,7 +2133,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * @return */ private Flux executeFindMultiInternal(ReactiveCollectionQueryCallback collectionCallback, - FindPublisherPreparer preparer, DocumentCallback objectCallback, String collectionName) { + @Nullable FindPublisherPreparer preparer, DocumentCallback objectCallback, String collectionName) { return createFlux(collectionName, collection -> { @@ -2330,7 +2335,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati private final Document query; private final Document fields; - FindCallback(Document query) { + FindCallback(@Nullable Document query) { this(query, null); } @@ -2687,8 +2692,9 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati static class NoOpDbRefResolver implements DbRefResolver { @Override - public Object resolveDbRef(MongoPersistentProperty property, DBRef dbref, DbRefResolverCallback callback, - DbRefProxyHandler proxyHandler) { + @Nullable + public Object resolveDbRef(@Nonnull MongoPersistentProperty property, @Nonnull DBRef dbref, + @Nonnull DbRefResolverCallback callback, @Nonnull DbRefProxyHandler proxyHandler) { return null; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScriptOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScriptOperations.java index 673717ddb..824ae221c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScriptOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScriptOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import java.util.Set; import org.springframework.data.mongodb.core.script.ExecutableMongoScript; import org.springframework.data.mongodb.core.script.NamedMongoScript; +import org.springframework.lang.Nullable; import com.mongodb.DB; @@ -56,6 +57,7 @@ public interface ScriptOperations { * @return the script evaluation result. * @throws org.springframework.dao.DataAccessException */ + @Nullable Object execute(ExecutableMongoScript script, Object... args); /** @@ -65,6 +67,7 @@ public interface ScriptOperations { * @param args * @return */ + @Nullable Object call(String scriptName, Object... args); /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java index c1b89fcea..cbef75e4a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java @@ -21,6 +21,7 @@ import org.springframework.beans.factory.DisposableBean; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.mongodb.MongoDbFactory; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.DB; @@ -44,7 +45,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory { private final boolean mongoInstanceCreated; private final PersistenceExceptionTranslator exceptionTranslator; - private WriteConcern writeConcern; + private @Nullable WriteConcern writeConcern; /** * Creates a new {@link SimpleMongoDbFactory} instance from the given {@link MongoClientURI}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleReactiveMongoDatabaseFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleReactiveMongoDatabaseFactory.java index 325983fc7..f197283bc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleReactiveMongoDatabaseFactory.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleReactiveMongoDatabaseFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.springframework.beans.factory.DisposableBean; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.ConnectionString; @@ -41,9 +42,10 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React private final MongoClient mongo; private final String databaseName; private final boolean mongoInstanceCreated; + private final PersistenceExceptionTranslator exceptionTranslator; - private WriteConcern writeConcern; + private @Nullable WriteConcern writeConcern; /** * Creates a new {@link SimpleReactiveMongoDatabaseFactory} instance from the given {@link ConnectionString}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernResolver.java index fa3858237..5b17d0f81 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2012 the original author or authors. + * Copyright 2011-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ */ package org.springframework.data.mongodb.core; +import org.springframework.lang.Nullable; + import com.mongodb.WriteConcern; /** @@ -33,5 +35,6 @@ public interface WriteConcernResolver { * should not be resolved. * @return a {@link WriteConcern} based on the passed in {@link MongoAction} value, maybe {@literal null}. */ + @Nullable WriteConcern resolve(MongoAction action); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOptions.java index 694aeb108..7fefc4682 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOptions.java @@ -19,6 +19,7 @@ import java.util.Optional; import org.bson.Document; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.DBObject; @@ -242,8 +243,8 @@ public class AggregationOptions { private boolean allowDiskUse; private boolean explain; - private Document cursor; - private Collation collation; + private @Nullable Document cursor; + private @Nullable Collation collation; /** * Defines whether to off-load intensive sort-operations to disk. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java index fc61f4372..2c3ace86c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java @@ -1,5 +1,5 @@ /* - * Copyright 2016. the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import org.springframework.data.domain.Range; import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Filter.AsBuilder; import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.PropertyExpression; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -414,9 +415,9 @@ public class ArrayOperators { */ public static class Filter implements AggregationExpression { - private Object input; - private ExposedField as; - private Object condition; + private @Nullable Object input; + private @Nullable ExposedField as; + private @Nullable Object condition; private Filter() { // used by builder diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConditionalOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConditionalOperators.java index a0ac604aa..f8fb36a6c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConditionalOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConditionalOperators.java @@ -1,5 +1,5 @@ /* - * Copyright 2016. the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Co import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond.ThenBuilder; import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Switch.CaseOperator; import org.springframework.data.mongodb.core.query.CriteriaDefinition; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -33,6 +34,7 @@ import org.springframework.util.ClassUtils; * Gateway to {@literal conditional expressions} that evaluate their argument expressions as booleans to a value. * * @author Mark Paluch + * @author Christoph Strobl * @since 1.10 */ public class ConditionalOperators { @@ -121,9 +123,11 @@ public class ConditionalOperators { public static class ConditionalOperatorFactory { - private final String fieldReference; - private final AggregationExpression expression; - private final CriteriaDefinition criteriaDefinition; + private final @Nullable String fieldReference; + + private final @Nullable AggregationExpression expression; + + private final @Nullable CriteriaDefinition criteriaDefinition; /** * Creates new {@link ConditionalOperatorFactory} for given {@literal fieldReference}. @@ -358,7 +362,7 @@ public class ConditionalOperators { */ static final class IfNullOperatorBuilder implements IfNullBuilder, ThenBuilder { - private Object condition; + private @Nullable Object condition; private IfNullOperatorBuilder() {} @@ -850,8 +854,8 @@ public class ConditionalOperators { */ static class ConditionalExpressionBuilder implements WhenBuilder, ThenBuilder, OtherwiseBuilder { - private Object condition; - private Object thenValue; + private @Nullable Object condition; + private @Nullable Object thenValue; private ConditionalExpressionBuilder() {} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GraphLookupOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GraphLookupOperation.java index 0e1c19345..335b84f41 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GraphLookupOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GraphLookupOperation.java @@ -25,6 +25,7 @@ import org.bson.Document; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation; import org.springframework.data.mongodb.core.query.CriteriaDefinition; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -51,12 +52,12 @@ public class GraphLookupOperation implements InheritsFieldsAggregationOperation private final Field connectFrom; private final Field connectTo; private final Field as; - private final Long maxDepth; - private final Field depthField; - private final CriteriaDefinition restrictSearchWithMatch; + private final @Nullable Long maxDepth; + private final @Nullable Field depthField; + private final @Nullable CriteriaDefinition restrictSearchWithMatch; private GraphLookupOperation(String from, List startWith, Field connectFrom, Field connectTo, Field as, - Long maxDepth, Field depthField, CriteriaDefinition restrictSearchWithMatch) { + @Nullable Long maxDepth, @Nullable Field depthField, @Nullable CriteriaDefinition restrictSearchWithMatch) { this.from = from; this.startWith = startWith; @@ -214,9 +215,9 @@ public class GraphLookupOperation implements InheritsFieldsAggregationOperation static final class GraphLookupOperationFromBuilder implements FromBuilder, StartWithBuilder, ConnectFromBuilder, ConnectToBuilder { - private String from; - private List startWith; - private String connectFrom; + private @Nullable String from; + private @Nullable List startWith; + private @Nullable String connectFrom; /* (non-Javadoc) * @see org.springframework.data.mongodb.core.aggregation.GraphLookupOperation.FromBuilder#from(java.lang.String) @@ -336,9 +337,9 @@ public class GraphLookupOperation implements InheritsFieldsAggregationOperation private final List startWith; private final Field connectFrom; private final Field connectTo; - private Long maxDepth; - private Field depthField; - private CriteriaDefinition restrictSearchWithMatch; + private @Nullable Long maxDepth; + private @Nullable Field depthField; + private @Nullable CriteriaDefinition restrictSearchWithMatch; protected GraphLookupOperationBuilder(String from, List startWith, String connectFrom, String connectTo) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/LookupOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/LookupOperation.java index ffacea315..6f7c5df47 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/LookupOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/LookupOperation.java @@ -18,6 +18,7 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -28,14 +29,15 @@ import org.springframework.util.Assert; * @author Christoph Strobl * @author Mark Paluch * @since 1.9 - * @see MongoDB Aggregation Framework: $lookup + * @see MongoDB Aggregation Framework: + * $lookup */ public class LookupOperation implements FieldsExposingAggregationOperation, InheritsFieldsAggregationOperation { - private Field from; - private Field localField; - private Field foreignField; - private ExposedField as; + private final Field from; + private final Field localField; + private final Field foreignField; + private final ExposedField as; /** * Creates a new {@link LookupOperation} for the given {@link Field}s. @@ -58,10 +60,6 @@ public class LookupOperation implements FieldsExposingAggregationOperation, Inhe this.as = new ExposedField(as, true); } - private LookupOperation() { - // used by builder - } - /* * (non-Javadoc) * @see org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation#getFields() @@ -143,11 +141,10 @@ public class LookupOperation implements FieldsExposingAggregationOperation, Inhe public static final class LookupOperationBuilder implements FromBuilder, LocalFieldBuilder, ForeignFieldBuilder, AsBuilder { - private final LookupOperation lookupOperation; - - private LookupOperationBuilder() { - this.lookupOperation = new LookupOperation(); - } + private @Nullable Field from; + private @Nullable Field localField; + private @Nullable Field foreignField; + private @Nullable ExposedField as; /** * Creates new builder for {@link LookupOperation}. @@ -162,7 +159,7 @@ public class LookupOperation implements FieldsExposingAggregationOperation, Inhe public LocalFieldBuilder from(String name) { Assert.hasText(name, "'From' must not be null or empty!"); - lookupOperation.from = Fields.field(name); + from = Fields.field(name); return this; } @@ -170,16 +167,16 @@ public class LookupOperation implements FieldsExposingAggregationOperation, Inhe public LookupOperation as(String name) { Assert.hasText(name, "'As' must not be null or empty!"); - lookupOperation.as = new ExposedField(Fields.field(name), true); - return new LookupOperation(lookupOperation.from, lookupOperation.localField, lookupOperation.foreignField, - lookupOperation.as); + as = new ExposedField(Fields.field(name), true); + return new LookupOperation(from, localField, foreignField, + as); } @Override public AsBuilder foreignField(String name) { Assert.hasText(name, "'ForeignField' must not be null or empty!"); - lookupOperation.foreignField = Fields.field(name); + foreignField = Fields.field(name); return this; } @@ -187,7 +184,7 @@ public class LookupOperation implements FieldsExposingAggregationOperation, Inhe public ForeignFieldBuilder localField(String name) { Assert.hasText(name, "'LocalField' must not be null or empty!"); - lookupOperation.localField = Fields.field(name); + localField = Fields.field(name); return this; } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnwindOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnwindOperation.java index b65327875..08f4984bc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnwindOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnwindOperation.java @@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -36,7 +37,7 @@ public class UnwindOperation implements AggregationOperation, FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation { private final ExposedField field; - private final ExposedField arrayIndex; + private final @Nullable ExposedField arrayIndex; private final boolean preserveNullAndEmptyArrays; /** @@ -185,8 +186,8 @@ public class UnwindOperation */ public static final class UnwindOperationBuilder implements PathBuilder, IndexBuilder, EmptyArraysBuilder { - private Field field; - private Field arrayIndex; + private @Nullable Field field; + private @Nullable Field arrayIndex; private UnwindOperationBuilder() {} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/package-info.java index a098ec022..0e30b8b85 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/package-info.java @@ -1,5 +1,8 @@ /** * Support for the MongoDB aggregation framework. + * * @since 1.3 */ -package org.springframework.data.mongodb.core.aggregation; \ No newline at end of file +@org.springframework.lang.NonNullApi +package org.springframework.data.mongodb.core.aggregation; + diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java index f9f35b520..64a005059 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java @@ -28,6 +28,8 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerT import org.springframework.data.mongodb.core.convert.MongoConverters.ObjectIdToBigIntegerConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.ObjectIdToStringConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.StringToObjectIdConverter; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * Base class for {@link MongoConverter} implementations. Sets up a {@link GenericConversionService} and populates basic @@ -36,6 +38,7 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.StringToObj * @author Jon Brisbin * @author Oliver Gierke * @author Mark Paluch + * @author Christoph Strobl */ public abstract class AbstractMongoConverter implements MongoConverter, InitializingBean { @@ -46,18 +49,20 @@ public abstract class AbstractMongoConverter implements MongoConverter, Initiali /** * Creates a new {@link AbstractMongoConverter} using the given {@link GenericConversionService}. * - * @param conversionService + * @param conversionService can be {@literal null} and defaults to {@link DefaultConversionService}. */ - public AbstractMongoConverter(GenericConversionService conversionService) { + public AbstractMongoConverter(@Nullable GenericConversionService conversionService) { this.conversionService = conversionService == null ? new DefaultConversionService() : conversionService; } /** * Registers the given custom conversions with the converter. * - * @param conversions + * @param conversions must not be {@literal null}. */ public void setCustomConversions(CustomConversions conversions) { + + Assert.notNull(conversions, "Conversions must not be null!"); this.conversions = conversions; } @@ -66,7 +71,7 @@ public abstract class AbstractMongoConverter implements MongoConverter, Initiali * * @param instantiators */ - public void setInstantiators(EntityInstantiators instantiators) { + public void setInstantiators(@Nullable EntityInstantiators instantiators) { this.instantiators = instantiators == null ? new EntityInstantiators() : instantiators; } @@ -91,20 +96,13 @@ public abstract class AbstractMongoConverter implements MongoConverter, Initiali conversions.registerConvertersIn(conversionService); } - /* - * (non-Javadoc) - * @see org.springframework.data.mongodb.core.convert.MongoWriter#convertToMongoType(java.lang.Object) - */ - public Object convertToMongoType(Object obj) { - return convertToMongoType(obj, null); - } - /* * (non-Javadoc) * @see org.springframework.data.mongodb.core.core.convert.MongoConverter#getConversionService() */ + @Override public ConversionService getConversionService() { - return conversionService; + return conversionService != null ? conversionService : new DefaultConversionService(); } /* (non-Javadoc) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolver.java index 5ba5592ff..b81b1ad0e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolver.java @@ -21,6 +21,7 @@ import org.bson.Document; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; +import org.springframework.lang.Nullable; import com.mongodb.DBRef; @@ -45,6 +46,7 @@ public interface DbRefResolver { * @param callback will never be {@literal null}. * @return */ + @Nullable Object resolveDbRef(MongoPersistentProperty property, DBRef dbref, DbRefResolverCallback callback, DbRefProxyHandler proxyHandler); @@ -67,6 +69,7 @@ public interface DbRefResolver { * @return * @since 1.7 */ + @Nullable Document fetch(DBRef dbRef); /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java index 4be8f1c56..b5a3393a7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java @@ -32,6 +32,7 @@ import java.util.stream.Stream; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.bson.Document; +import org.jetbrains.annotations.NotNull; import org.springframework.aop.framework.ProxyFactory; import org.springframework.cglib.proxy.Callback; import org.springframework.cglib.proxy.Enhancer; @@ -44,6 +45,7 @@ import org.springframework.data.mongodb.LazyLoadingException; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; +import org.springframework.lang.Nullable; import org.springframework.objenesis.ObjenesisStd; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; @@ -89,10 +91,11 @@ public class DefaultDbRefResolver implements DbRefResolver { */ @Override public Object resolveDbRef(MongoPersistentProperty property, DBRef dbref, DbRefResolverCallback callback, - DbRefProxyHandler handler) { + DbRefProxyHandler handler) { Assert.notNull(property, "Property must not be null!"); Assert.notNull(callback, "Callback must not be null!"); + Assert.notNull(handler, "Handler must not be null!"); if (isLazyDbRef(property)) { return createLazyLoadingProxy(property, dbref, callback, handler); @@ -262,7 +265,7 @@ public class DefaultDbRefResolver implements DbRefResolver { private final PersistenceExceptionTranslator exceptionTranslator; private volatile boolean resolved; - private Object result; + private @Nullable Object result; private DBRef dbref; static { @@ -301,7 +304,7 @@ public class DefaultDbRefResolver implements DbRefResolver { * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation) */ @Override - public Object invoke(MethodInvocation invocation) throws Throwable { + public Object invoke(@Nullable MethodInvocation invocation) throws Throwable { return intercept(invocation.getThis(), invocation.getMethod(), invocation.getArguments(), null); } @@ -310,7 +313,7 @@ public class DefaultDbRefResolver implements DbRefResolver { * @see org.springframework.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], org.springframework.cglib.proxy.MethodProxy) */ @Override - public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { + public Object intercept(@Nullable Object obj, @Nullable Method method, @Nullable Object[] args, @Nullable MethodProxy proxy) throws Throwable { if (INITIALIZE_METHOD.equals(method)) { return ensureResolved(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPropertyAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPropertyAccessor.java index 8a875e17a..f8e9038a0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPropertyAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPropertyAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -22,6 +22,7 @@ import org.springframework.context.expression.MapAccessor; import org.springframework.expression.EvaluationContext; import org.springframework.expression.PropertyAccessor; import org.springframework.expression.TypedValue; +import org.springframework.lang.Nullable; /** * {@link PropertyAccessor} to allow entity based field access to {@link Document}s. @@ -47,7 +48,7 @@ class DocumentPropertyAccessor extends MapAccessor { * @see org.springframework.context.expression.MapAccessor#canRead(org.springframework.expression.EvaluationContext, java.lang.Object, java.lang.String) */ @Override - public boolean canRead(EvaluationContext context, Object target, String name) { + public boolean canRead(EvaluationContext context, @Nullable Object target, String name) { return true; } @@ -57,7 +58,11 @@ class DocumentPropertyAccessor extends MapAccessor { */ @Override @SuppressWarnings("unchecked") - public TypedValue read(EvaluationContext context, Object target, String name) { + public TypedValue read(EvaluationContext context, @Nullable Object target, String name) { + + if (target == null) { + return TypedValue.NULL; + } Map source = (Map) target; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index 8e0cc9d7f..2422d38cc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -60,6 +60,7 @@ import org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent; import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -94,9 +95,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App protected final DbRefResolver dbRefResolver; protected final DefaultDbRefProxyHandler dbRefProxyHandler; - protected ApplicationContext applicationContext; + protected @Nullable ApplicationContext applicationContext; protected MongoTypeMapper typeMapper; - protected String mapKeyDotReplacement = null; + protected @Nullable String mapKeyDotReplacement = null; private SpELContext spELContext; @@ -142,12 +143,11 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * {@link DefaultMongoTypeMapper} by default. Setting this to {@literal null} will reset the {@link TypeMapper} to the * default one. * - * @param typeMapper the typeMapper to set + * @param typeMapper the typeMapper to set. Can be {@literal null}. */ - public void setTypeMapper(MongoTypeMapper typeMapper) { + public void setTypeMapper(@Nullable MongoTypeMapper typeMapper) { this.typeMapper = typeMapper == null - ? new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, mappingContext) - : typeMapper; + ? new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, mappingContext) : typeMapper; } /* @@ -165,9 +165,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * object to fail. If further customization of the translation is needed, have a look at * {@link #potentiallyEscapeMapKey(String)} as well as {@link #potentiallyUnescapeMapKey(String)}. * - * @param mapKeyDotReplacement the mapKeyDotReplacement to set + * @param mapKeyDotReplacement the mapKeyDotReplacement to set. Can be {@literal null}. */ - public void setMapKeyDotReplacement(String mapKeyDotReplacement) { + public void setMapKeyDotReplacement(@Nullable String mapKeyDotReplacement) { this.mapKeyDotReplacement = mapKeyDotReplacement; } @@ -352,7 +352,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * (non-Javadoc) * @see org.springframework.data.mongodb.core.convert.MongoWriter#toDBRef(java.lang.Object, org.springframework.data.mongodb.core.mapping.MongoPersistentProperty) */ - public DBRef toDBRef(Object object, MongoPersistentProperty referringProperty) { + public DBRef toDBRef(Object object, @Nullable MongoPersistentProperty referringProperty) { org.springframework.data.mongodb.core.mapping.DBRef annotation = null; @@ -404,7 +404,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * @param bson */ @SuppressWarnings("unchecked") - protected void writeInternal(final Object obj, final Bson bson, final TypeInformation typeHint) { + protected void writeInternal(@Nullable Object obj, final Bson bson, final TypeInformation typeHint) { if (null == obj) { return; @@ -434,7 +434,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App addCustomTypeKeyIfNecessary(typeHint, obj, bson); } - protected void writeInternal(Object obj, final Bson bson, MongoPersistentEntity entity) { + protected void writeInternal(@Nullable Object obj, final Bson bson, MongoPersistentEntity entity) { if (obj == null) { return; @@ -554,8 +554,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } MongoPersistentEntity entity = isSubtype(prop.getType(), obj.getClass()) - ? mappingContext.getRequiredPersistentEntity(obj.getClass()) - : mappingContext.getRequiredPersistentEntity(type); + ? mappingContext.getRequiredPersistentEntity(obj.getClass()) : mappingContext.getRequiredPersistentEntity(type); Object existingValue = accessor.get(prop); Document document = existingValue instanceof Document ? (Document) existingValue : new Document(); @@ -774,8 +773,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } return conversions.hasCustomWriteTarget(key.getClass(), String.class) - ? (String) getPotentiallyConvertedSimpleWrite(key) - : key.toString(); + ? (String) getPotentiallyConvertedSimpleWrite(key) : key.toString(); } /** @@ -1117,6 +1115,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * @see org.springframework.data.mongodb.core.convert.MongoWriter#convertToMongoType(java.lang.Object, org.springframework.data.util.TypeInformation) */ @SuppressWarnings("unchecked") + @Override public Object convertToMongoType(Object obj, TypeInformation typeInformation) { if (obj == null) { @@ -1421,8 +1420,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } List referencedRawDocuments = dbrefs.size() == 1 - ? Collections.singletonList(readRef(dbrefs.iterator().next())) - : bulkReadRefs(dbrefs); + ? Collections.singletonList(readRef(dbrefs.iterator().next())) : bulkReadRefs(dbrefs); String collectionName = dbrefs.iterator().next().getCollectionName(); List targeList = new ArrayList<>(dbrefs.size()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java index 915183e16..cdc6b49f3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java @@ -28,6 +28,7 @@ import org.springframework.core.convert.converter.GenericConverter; import org.springframework.data.convert.JodaTimeConverters; import org.springframework.data.convert.WritingConverter; import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes; +import org.springframework.lang.Nullable; /** * Value object to capture custom conversion. {@link MongoCustomConversions} also act as factory for @@ -94,8 +95,8 @@ public class MongoCustomConversions extends org.springframework.data.convert.Cus * (non-Javadoc) * @see org.springframework.core.convert.converter.GenericConverter#convert(java.lang.Object, org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor) */ - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - return source.toString(); + public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + return source != null ? source.toString() : null; } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoWriter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoWriter.java index 19f03b67c..39a31dec0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoWriter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoWriter.java @@ -19,6 +19,7 @@ import org.bson.conversions.Bson; import org.springframework.data.convert.EntityWriter; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Nullable; import com.mongodb.DBRef; @@ -40,7 +41,10 @@ public interface MongoWriter extends EntityWriter { * @param obj can be {@literal null}. * @return */ - Object convertToMongoType(Object obj); + @Nullable + default Object convertToMongoType(@Nullable Object obj) { + return convertToMongoType(obj, null); + } /** * Converts the given object into one Mongo will be able to store natively but retains the type information in case @@ -50,7 +54,8 @@ public interface MongoWriter extends EntityWriter { * @param typeInformation can be {@literal null}. * @return */ - Object convertToMongoType(Object obj, TypeInformation typeInformation); + @Nullable + Object convertToMongoType(@Nullable Object obj, @Nullable TypeInformation typeInformation); /** * Creates a {@link DBRef} to refer to the given object. @@ -60,5 +65,5 @@ public interface MongoWriter extends EntityWriter { * the {@link DBRef} object to create. Can be {@literal null}. * @return will never be {@literal null}. */ - DBRef toDBRef(Object object, MongoPersistentProperty referingProperty); + DBRef toDBRef(Object object, @Nullable MongoPersistentProperty referingProperty); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java index db1ca5e4f..c45ab1d94 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java @@ -33,13 +33,13 @@ import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.converter.Converter; import org.springframework.data.domain.Example; import org.springframework.data.mapping.Association; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.data.mapping.context.InvalidPersistentPropertyPath; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.PersistentPropertyPath; -import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.core.convert.MappingMongoConverter.NestedDocument; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; @@ -48,6 +48,7 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.util.BsonUtils; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.BasicDBList; @@ -108,7 +109,7 @@ public class QueryMapper { * @return */ @SuppressWarnings("deprecation") - public Document getMappedObject(Bson query, MongoPersistentEntity entity) { + public Document getMappedObject(Bson query, @Nullable MongoPersistentEntity entity) { if (isNestedKeyword(query)) { return getMappedKeyword(new Keyword(query), entity); @@ -161,10 +162,12 @@ public class QueryMapper { * @return * @since 1.6 */ - public Document getMappedSort(Document sortObject, MongoPersistentEntity entity) { + public Document getMappedSort(Document sortObject, @Nullable MongoPersistentEntity entity) { - if (sortObject == null) { - return null; + Assert.notNull(sortObject, "SortObject must not be null!"); + + if (sortObject.isEmpty()) { + return new Document(); } Document mappedSort = getMappedObject(sortObject, entity); @@ -172,33 +175,27 @@ public class QueryMapper { return mappedSort; } - public Document getMappedSort(Document sortObject, Optional> entity) { - return getMappedSort(sortObject, entity.orElse(null)); - } - /** * Maps fields to retrieve to the {@link MongoPersistentEntity}s properties.
- * Also onverts and potentially adds missing property {@code $meta} representation. + * Also converts and potentially adds missing property {@code $meta} representation. * - * @param fieldsObject - * @param entity + * @param fieldsObject must not be {@literal null}. + * @param entity can be {@litearl null}. * @return * @since 1.6 */ - public Document getMappedFields(Document fieldsObject, MongoPersistentEntity entity) { + public Document getMappedFields(Document fieldsObject, @Nullable MongoPersistentEntity entity) { - Document mappedFields = fieldsObject != null ? getMappedObject(fieldsObject, entity) : new Document(); + Assert.notNull(fieldsObject, "FieldsObject must not be null!"); + + Document mappedFields = fieldsObject.isEmpty() ? new Document() : getMappedObject(fieldsObject, entity); mapMetaAttributes(mappedFields, entity, MetaMapping.FORCE); - return mappedFields.keySet().isEmpty() ? null : mappedFields; + return mappedFields; } - public Document getMappedFields(Document fieldsObject, Optional> entity) { - return getMappedFields(fieldsObject, entity.orElse(null)); - } + private void mapMetaAttributes(Document source, @Nullable MongoPersistentEntity entity, MetaMapping metaMapping) { - private void mapMetaAttributes(Document source, MongoPersistentEntity entity, MetaMapping metaMapping) { - - if (entity == null || source == null) { + if (entity == null) { return; } @@ -373,7 +370,7 @@ public class QueryMapper { * @param value * @return */ - protected boolean isAssociationConversionNecessary(Field documentField, Object value) { + protected boolean isAssociationConversionNecessary(Field documentField, @Nullable Object value) { Assert.notNull(documentField, "Document field must not be null!"); @@ -393,8 +390,8 @@ public class QueryMapper { } MongoPersistentEntity entity = documentField.getPropertyEntity(); - return entity.hasIdProperty() && (type.equals(DBRef.class) - || entity.getRequiredIdProperty().getActualType().isAssignableFrom(type)); + return entity.hasIdProperty() + && (type.equals(DBRef.class) || entity.getRequiredIdProperty().getActualType().isAssignableFrom(type)); } /** @@ -437,7 +434,7 @@ public class QueryMapper { * @param entity * @return the converted mongo type or null if source is null */ - protected Object delegateConvertToMongoType(Object source, MongoPersistentEntity entity) { + protected Object delegateConvertToMongoType(Object source, @Nullable MongoPersistentEntity entity) { return converter.convertToMongoType(source, entity == null ? null : entity.getTypeInformation()); } @@ -490,7 +487,7 @@ public class QueryMapper { * @param value can be {@literal null}. * @return */ - protected final boolean isDocument(Object value) { + protected final boolean isDocument(@Nullable Object value) { return value instanceof Document; } @@ -500,7 +497,7 @@ public class QueryMapper { * @param value can be {@literal null}. * @return */ - protected final boolean isDBObject(Object value) { + protected final boolean isDBObject(@Nullable Object value) { return value instanceof DBObject; } @@ -511,7 +508,7 @@ public class QueryMapper { * @param value can be {@literal null}. * @return */ - protected final Entry createMapEntry(Field field, Object value) { + protected final Entry createMapEntry(Field field, @Nullable Object value) { return createMapEntry(field.getMappedKey(), value); } @@ -522,7 +519,7 @@ public class QueryMapper { * @param value can be {@literal null} * @return */ - private Entry createMapEntry(String key, Object value) { + private Entry createMapEntry(String key, @Nullable Object value) { Assert.hasText(key, "Key must not be null or empty!"); return Collections.singletonMap(key, value).entrySet().iterator().next(); @@ -543,7 +540,8 @@ public class QueryMapper { * @param id * @return */ - public Object convertId(Object id) { + @Nullable + public Object convertId(@Nullable Object id) { if (id == null) { return null; @@ -712,8 +710,9 @@ public class QueryMapper { * property that represents the value to handle. This means it'll be the leaf property for plain paths or the * association property in case we refer to an association somewhere in the path. * - * @return + * @return can be {@literal null}. */ + @Nullable public MongoPersistentProperty getProperty() { return null; } @@ -721,8 +720,9 @@ public class QueryMapper { /** * Returns the {@link MongoPersistentEntity} that field is conatined in. * - * @return + * @return can be {@literal null}. */ + @Nullable public MongoPersistentEntity getPropertyEntity() { return null; } @@ -754,6 +754,7 @@ public class QueryMapper { return false; } + @Nullable public Association getAssociation() { return null; } @@ -803,7 +804,7 @@ public class QueryMapper { */ public MetadataBackedField(String name, MongoPersistentEntity entity, MappingContext, MongoPersistentProperty> context, - MongoPersistentProperty property) { + @Nullable MongoPersistentProperty property) { super(name); @@ -884,6 +885,7 @@ public class QueryMapper { * * @return */ + @Nullable private Association findAssociation() { if (this.path != null) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/UpdateMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/UpdateMapper.java index e2f304dac..d6de3d3c5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/UpdateMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/UpdateMapper.java @@ -31,6 +31,7 @@ import org.springframework.data.mongodb.core.query.Update.Modifier; import org.springframework.data.mongodb.core.query.Update.Modifiers; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Nullable; /** * A subclass of {@link QueryMapper} that retains type information on the mongo types. @@ -60,7 +61,7 @@ public class UpdateMapper extends QueryMapper { * @see org.springframework.data.mongodb.core.convert.QueryMapper#getMappedObject(Bson, MongoPersistentEntity) */ @Override - public Document getMappedObject(Bson query, MongoPersistentEntity entity) { + public Document getMappedObject(Bson query, @Nullable MongoPersistentEntity entity) { Document document = super.getMappedObject(query, entity); @@ -102,10 +103,10 @@ public class UpdateMapper extends QueryMapper { /** * Returns {@literal true} if the given {@link Document} is an update object that uses update operators. * - * @param updateObj + * @param updateObj can be {@literal null}. * @return {@literal true} if the given {@link Document} is an update object. */ - public static boolean isUpdateObject(Document updateObj) { + public static boolean isUpdateObject(@Nullable Document updateObj) { if (updateObj == null) { return false; @@ -128,7 +129,7 @@ public class UpdateMapper extends QueryMapper { * org.springframework.data.mongodb.core.mapping.MongoPersistentEntity) */ @Override - protected Object delegateConvertToMongoType(Object source, MongoPersistentEntity entity) { + protected Object delegateConvertToMongoType(Object source, @Nullable MongoPersistentEntity entity) { return converter.convertToMongoType(source, entity == null ? ClassTypeInformation.OBJECT : getTypeHintForEntity(source, entity)); } @@ -184,23 +185,23 @@ public class UpdateMapper extends QueryMapper { * @see org.springframework.data.mongodb.core.convert.QueryMapper#isAssociationConversionNecessary(org.springframework.data.mongodb.core.convert.QueryMapper.Field, java.lang.Object) */ @Override - protected boolean isAssociationConversionNecessary(Field documentField, Object value) { + protected boolean isAssociationConversionNecessary(Field documentField, @Nullable Object value) { return super.isAssociationConversionNecessary(documentField, value) || documentField.containsAssociation(); } - private boolean isUpdateModifier(Object value) { + private boolean isUpdateModifier(@Nullable Object value) { return value instanceof Modifier || value instanceof Modifiers; } - private boolean isQuery(Object value) { + private boolean isQuery(@Nullable Object value) { return value instanceof Query; } - private Document getMappedValue(Field field, Modifier modifier) { + private Document getMappedValue(@Nullable Field field, Modifier modifier) { return new Document(modifier.getKey(), getMappedModifier(field, modifier)); } - private Object getMappedModifier(Field field, Modifier modifier) { + private Object getMappedModifier(@Nullable Field field, Modifier modifier) { Object value = modifier.getValue(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/package-info.java index 89a163a21..cfa07fa8f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/package-info.java @@ -1,5 +1,6 @@ /** * Spring Data MongoDB specific converter infrastructure. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.core.convert; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonModule.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonModule.java index 6b8be6f0c..23955510f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonModule.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.List; import org.springframework.data.geo.Point; +import org.springframework.lang.Nullable; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; @@ -64,7 +65,8 @@ public class GeoJsonModule extends SimpleModule { * @see com.fasterxml.jackson.databind.JsonDeserializer#deserialize(com.fasterxml.jackson.core.JsonParser, com.fasterxml.jackson.databind.DeserializationContext) */ @Override - public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + public T deserialize(@Nullable JsonParser jp, @Nullable DeserializationContext ctxt) + throws IOException, JsonProcessingException { JsonNode node = jp.readValueAsTree(); JsonNode coordinates = node.get("coordinates"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/package-info.java index 52505fe2e..1585cec14 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/package-info.java @@ -16,5 +16,6 @@ /** * Support for MongoDB geo-spatial queries. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.core.geo; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/GeospatialIndex.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/GeospatialIndex.java index b4bfea841..db4ef3e71 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/GeospatialIndex.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/GeospatialIndex.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 the original author or authors. + * Copyright 2010-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import java.util.Optional; import org.bson.Document; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -33,13 +34,13 @@ import org.springframework.util.StringUtils; public class GeospatialIndex implements IndexDefinition { private final String field; - private String name; - private Integer min; - private Integer max; - private Integer bits; + private @Nullable String name; + private @Nullable Integer min; + private @Nullable Integer max; + private @Nullable Integer bits; private GeoSpatialIndexType type = GeoSpatialIndexType.GEO_2D; private Double bucketSize = 1.0; - private String additionalField; + private @Nullable String additionalField; private Optional filter = Optional.empty(); private Optional collation = Optional.empty(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Index.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Index.java index 7ec294372..67ee6262d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Index.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Index.java @@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit; import org.bson.Document; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -40,7 +41,7 @@ public class Index implements IndexDefinition { } private final Map fieldSpec = new LinkedHashMap(); - private String name; + private @Nullable String name; private boolean unique = false; private boolean dropDuplicates = false; private boolean sparse = false; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexInfo.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexInfo.java index 6766a14b4..6469a8078 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexInfo.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexInfo.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Optional; import org.bson.Document; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -46,8 +47,8 @@ public class IndexInfo { private final boolean unique; private final boolean sparse; private final String language; - private String partialFilterExpression; - private Document collation; + private @Nullable String partialFilterExpression; + private @Nullable Document collation; public IndexInfo(List indexFields, String name, boolean unique, boolean sparse, String language) { @@ -167,6 +168,7 @@ public class IndexInfo { * @return * @since 1.0 */ + @Nullable public String getPartialFilterExpression() { return partialFilterExpression; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexPredicate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexPredicate.java index ea17d03c4..15bdf1cc6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexPredicate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 by the original author(s). + * Copyright 2011-2017 by the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,18 @@ package org.springframework.data.mongodb.core.index; +import org.springframework.lang.Nullable; + /** * @author Jon Brisbin */ public abstract class IndexPredicate { - private String name; + private @Nullable String name; private IndexDirection direction = IndexDirection.ASCENDING; private boolean unique = false; + @Nullable public String getName() { return name; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/TextIndexDefinition.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/TextIndexDefinition.java index 1a90fc91f..b707e3b52 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/TextIndexDefinition.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/TextIndexDefinition.java @@ -21,6 +21,7 @@ import java.util.Set; import org.bson.Document; import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -33,11 +34,11 @@ import org.springframework.util.StringUtils; */ public class TextIndexDefinition implements IndexDefinition { - private String name; + private @Nullable String name; private Set fieldSpecs; - private String defaultLanguage; - private String languageOverride; - private IndexFilter filter; + private @Nullable String defaultLanguage; + private @Nullable String languageOverride; + private @Nullable IndexFilter filter; TextIndexDefinition() { fieldSpecs = new LinkedHashSet(); @@ -142,7 +143,7 @@ public class TextIndexDefinition implements IndexDefinition { public static class TextIndexedFieldSpec { private final String fieldname; - private final Float weight; + private final @Nullable Float weight; /** * Create new {@link TextIndexedFieldSpec} for given fieldname without any weight. @@ -159,7 +160,7 @@ public class TextIndexDefinition implements IndexDefinition { * @param fieldname * @param weight */ - public TextIndexedFieldSpec(String fieldname, Float weight) { + public TextIndexedFieldSpec(String fieldname, @Nullable Float weight) { Assert.hasText(fieldname, "Text index field cannot be blank."); this.fieldname = fieldname; @@ -180,6 +181,7 @@ public class TextIndexDefinition implements IndexDefinition { * * @return */ + @Nullable public Float getWeight() { return weight; } @@ -304,7 +306,8 @@ public class TextIndexDefinition implements IndexDefinition { * * @param language * @return - * @see https://docs.mongodb.org/manual/tutorial/specify-language-for-text-index/#specify-default-language-text-index + * @see https://docs.mongodb.org/manual/tutorial/specify-language-for-text-index/#specify-default-language-text-index */ public TextIndexDefinitionBuilder withDefaultLanguage(String language) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/package-info.java index 4f82c9782..c49f501d8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/package-info.java @@ -1,5 +1,6 @@ /** * Support for MongoDB document indexing. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.core.index; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java index 1f397fa75..9d584f8d1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java @@ -29,9 +29,9 @@ import org.springframework.context.expression.BeanFactoryResolver; import org.springframework.data.annotation.Id; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.AssociationHandler; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.model.BasicPersistentEntity; -import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.MongoCollectionUtils; import org.springframework.data.util.TypeInformation; import org.springframework.expression.Expression; @@ -39,6 +39,7 @@ import org.springframework.expression.ParserContext; import org.springframework.expression.common.LiteralExpression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -176,13 +177,17 @@ public class BasicMongoPersistentEntity extends BasicPersistentEntity implements ApplicationListen * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) */ @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override public void onApplicationEvent(MongoMappingEvent event) { if (event instanceof AfterLoadEvent) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListener.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListener.java index a3a215722..3cc13d785 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListener.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AuditingEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2017 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. @@ -51,6 +51,7 @@ public class AuditingEventListener implements ApplicationListener event) { Optional.ofNullable(event.getSource())// diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/package-info.java index 96c601da3..0cc9d071a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/package-info.java @@ -1,5 +1,6 @@ /** * Mapping event callback infrastructure for the MongoDB document-to-object mapping subsystem. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.core.mapping.event; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/package-info.java index 5e451b043..0a513f1a1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/package-info.java @@ -1,5 +1,6 @@ /** * Infrastructure for the MongoDB document-to-object mapping subsystem. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.core.mapping; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/GroupBy.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/GroupBy.java index 3348bdf9e..22bff10be 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/GroupBy.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/GroupBy.java @@ -19,6 +19,7 @@ import java.util.Optional; import org.bson.Document; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Nullable; /** * Collects the parameters required to perform a group operation on a collection. The query condition and the input @@ -30,8 +31,8 @@ import org.springframework.data.mongodb.core.query.Collation; */ public class GroupBy { - private Document initialDocument; - private String reduce; + private @Nullable Document initialDocument; + private @Nullable String reduce; private Optional keys = Optional.empty(); private Optional keyFunction = Optional.empty(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/GroupByResults.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/GroupByResults.java index 3fb89c703..d17db6619 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/GroupByResults.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/GroupByResults.java @@ -19,6 +19,7 @@ import java.util.Iterator; import java.util.List; import org.bson.Document; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -36,7 +37,7 @@ public class GroupByResults implements Iterable { private double count; private int keys; - private String serverUsed; + private @Nullable String serverUsed; public GroupByResults(List mappedResults, Document rawResults) { @@ -59,6 +60,7 @@ public class GroupByResults implements Iterable { return keys; } + @Nullable public String getServerUsed() { return serverUsed; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceOptions.java index e8909a6ad..7a6bfd633 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceOptions.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 the original author or authors. + * Copyright 2010-2017 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. @@ -23,6 +23,7 @@ import org.bson.Document; import org.springframework.data.mongodb.core.query.Collation; import com.mongodb.MapReduceCommand; +import org.springframework.lang.Nullable; /** * @author Mark Pollack @@ -31,15 +32,15 @@ import com.mongodb.MapReduceCommand; */ public class MapReduceOptions { - private String outputCollection; + private @Nullable String outputCollection; private Optional outputDatabase = Optional.empty(); private MapReduceCommand.OutputType outputType = MapReduceCommand.OutputType.REPLACE; private Map scopeVariables = new HashMap(); private Map extraOptions = new HashMap(); - private Boolean jsMode; + private @Nullable Boolean jsMode; private Boolean verbose = Boolean.TRUE; - private Integer limit; + private @Nullable Integer limit; private Optional outputSharded = Optional.empty(); private Optional finalizeFunction = Optional.empty(); @@ -251,6 +252,7 @@ public class MapReduceOptions { return this.jsMode; } + @Nullable public String getOutputCollection() { return this.outputCollection; } @@ -276,6 +278,7 @@ public class MapReduceOptions { * * @return {@literal null} if not set. */ + @Nullable public Integer getLimit() { return limit; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/package-info.java index ca447893d..54781e78c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/package-info.java @@ -1,5 +1,6 @@ /** * Support for MongoDB map-reduce operations. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.core.mapreduce; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/package-info.java index a4c52a66d..e2f9169d0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/package-info.java @@ -1,5 +1,6 @@ /** * MongoDB core support. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.core; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java index dfc452648..4840dcbf3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java @@ -63,8 +63,8 @@ public class BasicQuery extends Query { */ public BasicQuery(String query, String fields) { - this.queryObject = query != null ? Document.parse(query) : new Document(); - this.fieldsObject = fields != null ? Document.parse(fields) : new Document(); + this(query != null ? Document.parse(query) : new Document(), + fields != null ? Document.parse(fields) : new Document()); } /** @@ -81,6 +81,7 @@ public class BasicQuery extends Query { this.queryObject = queryObject; this.fieldsObject = fieldsObject; + this.sortObject = new Document(); } /* @@ -111,19 +112,10 @@ public class BasicQuery extends Query { @Override public Document getFieldsObject() { - if (fieldsObject == null) { - return super.getFieldsObject(); - } - - if (super.getFieldsObject() != null) { - - Document combinedFieldsObject = new Document(); - combinedFieldsObject.putAll(fieldsObject); - combinedFieldsObject.putAll(super.getFieldsObject()); - return combinedFieldsObject; - } - - return fieldsObject; + Document combinedFieldsObject = new Document(); + combinedFieldsObject.putAll(fieldsObject); + combinedFieldsObject.putAll(super.getFieldsObject()); + return combinedFieldsObject; } /* @@ -134,10 +126,7 @@ public class BasicQuery extends Query { public Document getSortObject() { Document result = new Document(); - - if (sortObject != null) { - result.putAll(sortObject); - } + result.putAll(sortObject); Document overrides = super.getSortObject(); result.putAll(overrides); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java index 1406de996..b1a731bbf 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java @@ -35,6 +35,7 @@ import org.springframework.data.geo.Shape; import org.springframework.data.mongodb.InvalidMongoDbApiUsageException; import org.springframework.data.mongodb.core.geo.GeoJson; import org.springframework.data.mongodb.core.geo.Sphere; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -59,7 +60,7 @@ public class Criteria implements CriteriaDefinition { */ private static final Object NOT_SET = new Object(); - private String key; + private @Nullable String key; private List criteriaChain; private LinkedHashMap criteria = new LinkedHashMap(); private Object isValue = NOT_SET; @@ -615,6 +616,11 @@ public class Criteria implements CriteriaDefinition { return this; } + /* + * @see org.springframework.data.mongodb.core.query.CriteriaDefinition#getKey() + */ + @Override + @Nullable public String getKey() { return this.key; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/CriteriaDefinition.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/CriteriaDefinition.java index 744785e37..583516b82 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/CriteriaDefinition.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/CriteriaDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 the original author or authors. + * Copyright 2010-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core.query; import org.bson.Document; +import org.springframework.lang.Nullable; /** * @author Oliver Gierke @@ -25,17 +26,18 @@ public interface CriteriaDefinition { /** * Get {@link Document} representation. - * - * @return + * + * @return never {@literal null}. */ Document getCriteriaObject(); /** * Get the identifying {@literal key}. - * - * @return + * + * @return can be {@literal null}. * @since 1.6 */ + @Nullable String getKey(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Field.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Field.java index 9db0d0ff4..9e7431d09 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Field.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Field.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 the original author or authors. + * Copyright 2010-2017 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. @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Map.Entry; import org.bson.Document; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -37,7 +38,7 @@ public class Field { private final Map criteria = new HashMap(); private final Map slices = new HashMap(); private final Map elemMatchs = new HashMap(); - private String postionKey; + private @Nullable String postionKey; private int positionValue; public Field include(String key) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/NearQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/NearQuery.java index 31184ea3d..f6d6e51f8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/NearQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/NearQuery.java @@ -24,7 +24,9 @@ import org.springframework.data.geo.Distance; import org.springframework.data.geo.Metric; import org.springframework.data.geo.Metrics; import org.springframework.data.geo.Point; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; /** * Builder class to build near-queries. @@ -36,40 +38,39 @@ import org.springframework.util.Assert; public final class NearQuery { private final Point point; - private Query query; - private Distance maxDistance; - private Distance minDistance; + private @Nullable Query query; + private @Nullable Distance maxDistance; + private @Nullable Distance minDistance; private Metric metric; private boolean spherical; - private Long num; - private Long skip; + private @Nullable Long num; + private @Nullable Long skip; /** * Creates a new {@link NearQuery}. * * @param point must not be {@literal null}. + * @param metric must not be {@literal null}. */ private NearQuery(Point point, Metric metric) { Assert.notNull(point, "Point must not be null!"); + Assert.notNull(metric, "Metric must not be null!"); this.point = point; this.spherical = false; - - if (metric != null) { - in(metric); - } + this.metric = metric; } /** * Creates a new {@link NearQuery} starting near the given coordinates. * - * @param i - * @param j + * @param x + * @param y * @return */ public static NearQuery near(double x, double y) { - return near(x, y, null); + return near(x, y, Metrics.NEUTRAL); } /** @@ -79,7 +80,7 @@ public final class NearQuery { * * @param x * @param y - * @param metric + * @param metric must not be {@literal null}. * @return */ public static NearQuery near(double x, double y, Metric metric) { @@ -93,7 +94,7 @@ public final class NearQuery { * @return */ public static NearQuery near(Point point) { - return near(point, null); + return near(point, Metrics.NEUTRAL); } /** @@ -102,7 +103,7 @@ public final class NearQuery { * initially set {@link Metric}. * * @param point must not be {@literal null}. - * @param metric + * @param metric must not be {@literal null}. * @return */ public static NearQuery near(Point point, Metric metric) { @@ -116,7 +117,7 @@ public final class NearQuery { * @return will never be {@literal null}. */ public Metric getMetric() { - return metric == null ? Metrics.NEUTRAL : metric; + return metric; } /** @@ -191,7 +192,7 @@ public final class NearQuery { /** * Sets the maximum distance to the given {@link Distance}. Will set the returned {@link Metric} to be the one of the - * given {@link Distance} if no {@link Metric} was set before. + * given {@link Distance} if {@link Metric} was {@link Metrics#NEUTRAL} before. * * @param distance must not be {@literal null}. * @return @@ -204,7 +205,7 @@ public final class NearQuery { this.spherical(true); } - if (this.metric == null) { + if (ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, this.metric)) { in(distance.getMetric()); } @@ -275,6 +276,7 @@ public final class NearQuery { * * @return */ + @Nullable public Distance getMaxDistance() { return this.maxDistance; } @@ -285,6 +287,7 @@ public final class NearQuery { * @return * @since 1.7 */ + @Nullable public Distance getMinDistance() { return this.minDistance; } @@ -378,6 +381,7 @@ public final class NearQuery { public NearQuery query(Query query) { Assert.notNull(query, "Cannot apply 'null' query on NearQuery."); + this.query = query; this.skip = query.getSkip(); @@ -390,6 +394,7 @@ public final class NearQuery { /** * @return the number of elements to skip. */ + @Nullable public Long getSkip() { return skip; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java index c52e0c0bd..dba1c45c8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java @@ -34,6 +34,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; import org.springframework.data.mongodb.InvalidMongoDbApiUsageException; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -55,7 +56,7 @@ public class Query { private Sort sort = Sort.unsorted(); private long skip; private int limit; - private String hint; + private @Nullable String hint; private Meta meta = new Meta(); @@ -282,6 +283,7 @@ public class Query { /** * @return */ + @Nullable public String getHint() { return hint; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextCriteria.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextCriteria.java index 7294e1918..e14e27966 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextCriteria.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextCriteria.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.List; import org.bson.Document; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -33,8 +34,8 @@ public class TextCriteria implements CriteriaDefinition { private final List terms; private String language; - private Boolean caseSensitive; - private Boolean diacriticSensitive; + private @Nullable Boolean caseSensitive; + private @Nullable Boolean diacriticSensitive; /** * Creates a new {@link TextCriteria}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/package-info.java index 911f2fea6..d3f67790a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/package-info.java @@ -1,5 +1,6 @@ /** * MongoDB specific query and update support. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.core.query; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/script/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/script/package-info.java new file mode 100644 index 000000000..34eb8ea89 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/script/package-info.java @@ -0,0 +1,8 @@ +/** + * Abstraction classes javascript function execution within MongoDB Server. + * + * @since 1.7 + */ +@org.springframework.lang.NonNullApi +package org.springframework.data.mongodb.core.script; + diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/package-info.java index f703ec9e4..fbfa2ae78 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/package-info.java @@ -1,5 +1,8 @@ /** * Support classes to transform SpEL expressions into MongoDB expressions. + * * @since 1.4 */ -package org.springframework.data.mongodb.core.spel; \ No newline at end of file +@org.springframework.lang.NonNullApi +package org.springframework.data.mongodb.core.spel; + diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsCriteria.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsCriteria.java index c90f1c7ce..1a8925a82 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsCriteria.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsCriteria.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2016 the original author or authors. + * Copyright 2011-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.gridfs; import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.lang.Nullable; /** * GridFs-specific helper class to define {@link Criteria}s. @@ -49,7 +50,8 @@ public class GridFsCriteria extends Criteria { * @param metadataKey * @return */ - public static GridFsCriteria whereMetaData(String metadataKey) { + public static GridFsCriteria whereMetaData(@Nullable String metadataKey) { + String extension = metadataKey == null ? "" : "." + metadataKey; return new GridFsCriteria(String.format("metadata%s", extension)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperations.java index 6c1c8c11e..b768ed101 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperations.java @@ -22,6 +22,7 @@ import org.bson.types.ObjectId; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.lang.Nullable; import com.mongodb.client.gridfs.GridFSFindIterable; import com.mongodb.gridfs.GridFSFile; @@ -53,7 +54,7 @@ public interface GridFsOperations extends ResourcePatternResolver { * @param metadata can be {@literal null}. * @return the {@link GridFSFile} just created */ - ObjectId store(InputStream content, Object metadata); + ObjectId store(InputStream content, @Nullable Object metadata); /** * Stores the given content into a file with the given name. @@ -62,7 +63,7 @@ public interface GridFsOperations extends ResourcePatternResolver { * @param metadata can be {@literal null}. * @return the {@link GridFSFile} just created */ - ObjectId store(InputStream content, Document metadata); + ObjectId store(InputStream content, @Nullable Document metadata); /** * Stores the given content into a file with the given name and content type. @@ -72,18 +73,18 @@ public interface GridFsOperations extends ResourcePatternResolver { * @param contentType can be {@literal null}. * @return the {@link GridFSFile} just created */ - ObjectId store(InputStream content, String filename, String contentType); + ObjectId store(InputStream content, @Nullable String filename, @Nullable String contentType); /** * Stores the given content into a file with the given name using the given metadata. The metadata object will be * marshalled before writing. * * @param content must not be {@literal null}. - * @param filename must not be {@literal null} or empty. + * @param filename can be {@literal null} or empty. * @param metadata can be {@literal null}. * @return the {@link GridFSFile} just created */ - ObjectId store(InputStream content, String filename, Object metadata); + ObjectId store(InputStream content, @Nullable String filename, @Nullable Object metadata); /** * Stores the given content into a file with the given name and content type using the given metadata. The metadata @@ -95,7 +96,7 @@ public interface GridFsOperations extends ResourcePatternResolver { * @param metadata can be {@literal null} * @return the {@link GridFSFile} just created */ - ObjectId store(InputStream content, String filename, String contentType, Object metadata); + ObjectId store(InputStream content, @Nullable String filename, @Nullable String contentType, @Nullable Object metadata); /** * Stores the given content into a file with the given name using the given metadata. @@ -105,7 +106,7 @@ public interface GridFsOperations extends ResourcePatternResolver { * @param metadata can be {@literal null}. * @return the {@link GridFSFile} just created */ - ObjectId store(InputStream content, String filename, Document metadata); + ObjectId store(InputStream content, @Nullable String filename, @Nullable Document metadata); /** * Stores the given content into a file with the given name and content type using the given metadata. @@ -116,14 +117,14 @@ public interface GridFsOperations extends ResourcePatternResolver { * @param metadata can be {@literal null}. * @return the {@link GridFSFile} just created */ - ObjectId store(InputStream content, String filename, String contentType, Document metadata); + ObjectId store(InputStream content, @Nullable String filename, @Nullable String contentType, @Nullable Document metadata); /** * Returns all files matching the given query. Note, that currently {@link Sort} criterias defined at the * {@link Query} will not be regarded as MongoDB does not support ordering for GridFS file access. * * @see MongoDB Jira: JAVA-431 - * @param query + * @param query must not be {@literal null}. * @return */ GridFSFindIterable find(Query query); @@ -131,22 +132,23 @@ public interface GridFsOperations extends ResourcePatternResolver { /** * Returns a single file matching the given query or {@literal null} in case no file matches. * - * @param query + * @param query must not be {@literal null}. * @return */ + @Nullable com.mongodb.client.gridfs.model.GridFSFile findOne(Query query); /** * Deletes all files matching the given {@link Query}. * - * @param query + * @param query must not be {@literal null}. */ void delete(Query query); /** * Returns all {@link GridFsResource} with the given file name. * - * @param filename + * @param filename must not be {@literal null}. * @return the resource if it exists or {@literal null}. * @see ResourcePatternResolver#getResource(String) */ @@ -155,7 +157,7 @@ public interface GridFsOperations extends ResourcePatternResolver { /** * Returns all {@link GridFsResource}s matching the given file name pattern. * - * @param filenamePattern + * @param filenamePattern must not be {@literal null}. * @return * @see ResourcePatternResolver#getResources(String) */ diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java index 319386de5..e39880f42 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java @@ -31,6 +31,7 @@ import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -54,6 +55,7 @@ import com.mongodb.client.gridfs.model.GridFSUploadOptions; public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver { private final MongoDbFactory dbFactory; + private final String bucket; private final MongoConverter converter; private final QueryMapper queryMapper; @@ -99,9 +101,8 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver * (non-Javadoc) * @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.Object) */ - @Override - public ObjectId store(InputStream content, Object metadata) { + public ObjectId store(InputStream content, @Nullable Object metadata) { return store(content, null, metadata); } @@ -110,7 +111,7 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver * @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, com.mongodb.Document) */ @Override - public ObjectId store(InputStream content, Document metadata) { + public ObjectId store(InputStream content, @Nullable Document metadata) { return store(content, null, metadata); } @@ -118,7 +119,7 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver * (non-Javadoc) * @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, java.lang.String) */ - public ObjectId store(InputStream content, String filename, String contentType) { + public ObjectId store(InputStream content, @Nullable String filename, @Nullable String contentType) { return store(content, filename, contentType, (Object) null); } @@ -126,7 +127,7 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver * (non-Javadoc) * @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, java.lang.Object) */ - public ObjectId store(InputStream content, String filename, Object metadata) { + public ObjectId store(InputStream content, @Nullable String filename, @Nullable Object metadata) { return store(content, filename, null, metadata); } @@ -134,7 +135,7 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver * (non-Javadoc) * @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, java.lang.String, java.lang.Object) */ - public ObjectId store(InputStream content, String filename, String contentType, Object metadata) { + public ObjectId store(InputStream content, @Nullable String filename, @Nullable String contentType, @Nullable Object metadata) { Document document = null; @@ -150,7 +151,7 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver * (non-Javadoc) * @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, com.mongodb.Document) */ - public ObjectId store(InputStream content, String filename, Document metadata) { + public ObjectId store(InputStream content, @Nullable String filename, @Nullable Document metadata) { return this.store(content, filename, null, metadata); } @@ -158,7 +159,7 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver * (non-Javadoc) * @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, com.mongodb.Document) */ - public ObjectId store(InputStream content, String filename, String contentType, Document metadata) { + public ObjectId store(InputStream content, @Nullable String filename, @Nullable String contentType, @Nullable Document metadata) { Assert.notNull(content, "InputStream must not be null!"); @@ -185,9 +186,7 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver */ public GridFSFindIterable find(Query query) { - if (query == null) { - return getGridFs().find(new Document()); - } + Assert.notNull(query, "Query must not be null!"); Document queryObject = getMappedQuery(query.getQueryObject()); Document sortObject = getMappedQuery(query.getSortObject()); @@ -260,7 +259,7 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver } private Document getMappedQuery(Document query) { - return query == null ? null : queryMapper.getMappedObject(query, Optional.empty()); + return queryMapper.getMappedObject(query, Optional.empty()); } private GridFSBucket getGridFs() { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/package-info.java index b76640542..2f3b5af15 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/package-info.java @@ -1,5 +1,6 @@ /** * Support for MongoDB GridFS feature. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.gridfs; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/package-info.java index db25cc487..0d495584a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/package-info.java @@ -1,5 +1,6 @@ /** * MongoDB specific JMX monitoring support. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.monitor; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/package-info.java index 1a6fe3950..900342bbc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/package-info.java @@ -1,5 +1,5 @@ /** * Spring Data's MongoDB abstraction. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb; - diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/cdi/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/cdi/package-info.java index ca8bb77ac..a2cbf659d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/cdi/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/cdi/package-info.java @@ -1,5 +1,6 @@ /** * CDI support for MongoDB specific repository implementation. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.repository.cdi; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/package-info.java index 30e2aeb82..d0d9b0708 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/package-info.java @@ -1,5 +1,6 @@ /** * Support infrastructure for the configuration of MongoDB specific repositories. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.repository.config; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/package-info.java index 50507d7b4..8deddfe93 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/package-info.java @@ -1,5 +1,6 @@ /** * MongoDB specific repository implementation. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.repository; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java index cc96ac4ae..abf91f03d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java @@ -77,6 +77,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery { * (non-Javadoc) * @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[]) */ + @Override public Object execute(Object[] parameters) { ConvertingParameterAccessor accessor = new ConvertingParameterAccessor(operations.getConverter(), diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameters.java index 60005a0b8..323ef0fdb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameters.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameters.java @@ -29,7 +29,10 @@ import org.springframework.data.mongodb.repository.query.MongoParameters.MongoPa import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.Parameters; import org.springframework.data.util.ClassTypeInformation; +import org.springframework.data.util.ReflectionUtils; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Nullable; +import org.springframework.util.ClassUtils; /** * Custom extension of {@link Parameters} discovering additional @@ -42,8 +45,7 @@ public class MongoParameters extends Parameters private final int rangeIndex; private final int maxDistanceIndex; private final Integer fullTextIndex; - - private Integer nearIndex; + private final Integer nearIndex; /** * Creates a new {@link MongoParameters} instance from the given {@link Method} and {@link MongoQueryMethod}. @@ -64,11 +66,12 @@ public class MongoParameters extends Parameters this.rangeIndex = getTypeIndex(parameterTypeInfo, Range.class, Distance.class); this.maxDistanceIndex = this.rangeIndex == -1 ? getTypeIndex(parameterTypeInfo, Distance.class, null) : -1; - if (this.nearIndex == null && isGeoNearMethod) { - this.nearIndex = getNearIndex(parameterTypes); - } else if (this.nearIndex == null) { - this.nearIndex = -1; + int index = findNearIndexInParameters(method); + if (index == -1 && isGeoNearMethod) { + index = getNearIndex(parameterTypes); } + + this.nearIndex = index; } private MongoParameters(List parameters, int maxDistanceIndex, Integer nearIndex, @@ -102,26 +105,36 @@ public class MongoParameters extends Parameters return -1; } + private int findNearIndexInParameters(Method method) { + + int index = -1; + for (java.lang.reflect.Parameter p : method.getParameters()) { + + MongoParameter param = createParameter(MethodParameter.forParameter(p)); + if (param.isManuallyAnnotatedNearParameter()) { + if(index == -1) { + index = param.getIndex(); + } else { + throw new IllegalStateException(String.format("Found multiple @Near annotations ond method %s! Only one allowed!", + method.toString())); + } + + } + } + return index; + } + /* * (non-Javadoc) * @see org.springframework.data.repository.query.Parameters#createParameter(org.springframework.core.MethodParameter) */ @Override protected MongoParameter createParameter(MethodParameter parameter) { - - MongoParameter mongoParameter = new MongoParameter(parameter); - - // Detect manually annotated @Near Point and reject multiple annotated ones - if (this.nearIndex == null && mongoParameter.isManuallyAnnotatedNearParameter()) { - this.nearIndex = mongoParameter.getIndex(); - } else if (mongoParameter.isManuallyAnnotatedNearParameter()) { - throw new IllegalStateException(String.format("Found multiple @Near annotations ond method %s! Only one allowed!", - parameter.getMethod().toString())); - } - - return mongoParameter; + return new MongoParameter(parameter); } + + public int getDistanceRangeIndex() { return -1; } @@ -180,7 +193,7 @@ public class MongoParameters extends Parameters return new MongoParameters(parameters, this.maxDistanceIndex, this.nearIndex, this.fullTextIndex, this.rangeIndex); } - private int getTypeIndex(List> parameterTypes, Class type, Class componentType) { + private int getTypeIndex(List> parameterTypes, Class type, @Nullable Class componentType) { for (int i = 0; i < parameterTypes.size(); i++) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java index eb9c75635..76ed6ea81 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java @@ -37,6 +37,7 @@ import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.QueryMethod; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -57,7 +58,7 @@ public class MongoQueryMethod extends QueryMethod { private final Method method; private final MappingContext, MongoPersistentProperty> mappingContext; - private MongoEntityMetadata metadata; + private @Nullable MongoEntityMetadata metadata; /** * Creates a new {@link MongoQueryMethod} from the given {@link Method}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/package-info.java index f31ea0222..20c77e22a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/package-info.java @@ -1,5 +1,6 @@ /** * Query derivation mechanism for MongoDB specific repositories. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.repository.query; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoAnnotationProcessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoAnnotationProcessor.java index aa036659b..7e0c1dfe1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoAnnotationProcessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoAnnotationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 the original author or authors. + * Copyright 2011-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import com.querydsl.core.annotations.QueryEmbedded; import com.querydsl.core.annotations.QueryEntities; import com.querydsl.core.annotations.QuerySupertype; import com.querydsl.core.annotations.QueryTransient; +import org.springframework.lang.Nullable; /** * Annotation processor to create Querydsl query types for QueryDsl annotated classes. @@ -48,7 +49,7 @@ public class MongoAnnotationProcessor extends AbstractQuerydslProcessor { * @see com.mysema.query.apt.AbstractQuerydslProcessor#createConfiguration(javax.annotation.processing.RoundEnvironment) */ @Override - protected Configuration createConfiguration(RoundEnvironment roundEnv) { + protected Configuration createConfiguration(@Nullable RoundEnvironment roundEnv) { processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Running " + getClass().getSimpleName()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactory.java index e60eab7c2..a6fa10fcd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactory.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactory.java @@ -44,6 +44,7 @@ import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -129,7 +130,7 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport { * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider) */ @Override - protected Optional getQueryLookupStrategy(Key key, + protected Optional getQueryLookupStrategy(@Nullable Key key, EvaluationContextProvider evaluationContextProvider) { return Optional.of(new MongoQueryLookupStrategy(operations, evaluationContextProvider, mappingContext)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java index ad4e63dd2..58e5d1030 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 the original author or authors. + * Copyright 2010-2017 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. @@ -23,6 +23,7 @@ import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.repository.core.support.RepositoryFactorySupport; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -33,7 +34,7 @@ import org.springframework.util.Assert; public class MongoRepositoryFactoryBean, S, ID extends Serializable> extends RepositoryFactoryBeanSupport { - private MongoOperations operations; + private @Nullable MongoOperations operations; private boolean createIndexesForQueryMethods = false; private boolean mappingContextConfigured = false; @@ -88,7 +89,8 @@ public class MongoRepositoryFactoryBean, S, ID exten RepositoryFactorySupport factory = getFactoryInstance(operations); if (createIndexesForQueryMethods) { - factory.addQueryCreationListener(new IndexEnsuringQueryCreationListener(collectionName -> operations.indexOps(collectionName))); + factory.addQueryCreationListener( + new IndexEnsuringQueryCreationListener(collectionName -> operations.indexOps(collectionName))); } return factory; @@ -115,7 +117,7 @@ public class MongoRepositoryFactoryBean, S, ID exten public void afterPropertiesSet() { super.afterPropertiesSet(); - Assert.notNull(operations, "MongoTemplate must not be null!"); + Assert.state(operations != null, "MongoTemplate must not be null!"); if (!mappingContextConfigured) { setMappingContext(operations.getConverter().getMappingContext()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactory.java index bcd4c2bbe..be9c9dc83 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactory.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactory.java @@ -41,6 +41,7 @@ import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -97,7 +98,7 @@ public class ReactiveMongoRepositoryFactory extends ReactiveRepositoryFactorySup * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider) */ @Override - protected Optional getQueryLookupStrategy(Key key, + protected Optional getQueryLookupStrategy(@Nullable Key key, EvaluationContextProvider evaluationContextProvider) { return Optional.of(new MongoQueryLookupStrategy(operations, evaluationContextProvider, mappingContext)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java index 325147859..77a78870b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java @@ -23,6 +23,7 @@ import org.springframework.data.mongodb.core.index.IndexOperationsAdapter; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.repository.core.support.RepositoryFactorySupport; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -38,7 +39,7 @@ import org.springframework.util.Assert; public class ReactiveMongoRepositoryFactoryBean, S, ID extends Serializable> extends RepositoryFactoryBeanSupport { - private ReactiveMongoOperations operations; + private @Nullable ReactiveMongoOperations operations; private boolean createIndexesForQueryMethods = false; private boolean mappingContextConfigured = false; @@ -56,7 +57,7 @@ public class ReactiveMongoRepositoryFactoryBean, S, * * @param operations the operations to set */ - public void setReactiveMongoOperations(ReactiveMongoOperations operations) { + public void setReactiveMongoOperations(@Nullable ReactiveMongoOperations operations) { this.operations = operations; } @@ -121,7 +122,7 @@ public class ReactiveMongoRepositoryFactoryBean, S, public void afterPropertiesSet() { super.afterPropertiesSet(); - Assert.notNull(operations, "ReactiveMongoOperations must not be null!"); + Assert.state(operations != null, "ReactiveMongoOperations must not be null!"); if (!mappingContextConfigured) { setMappingContext(operations.getConverter().getMappingContext()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbQuery.java index 8a8386eeb..93fd4080f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.data.mongodb.repository.support; import org.bson.Document; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.lang.Nullable; import com.google.common.base.Function; import com.mongodb.BasicDBObject; @@ -58,9 +59,7 @@ public class SpringDataMongodbQuery extends AbstractMongodbQuery() { @Override - public T apply(DBObject input) { - - ; + public T apply(@Nullable DBObject input) { return operations.getConverter().read(type, new Document((BasicDBObject) input)); } }, new SpringDataMongodbSerializer(operations.getConverter())); @@ -73,7 +72,7 @@ public class SpringDataMongodbQuery extends AbstractMongodbQuery type) { + protected DBCollection getCollection(@Nullable Class type) { return ((MongoTemplate) operations).getMongoDbFactory().getLegacyDb() .getCollection(operations.getCollectionName(type)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java index bdd935176..692fe2993 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java @@ -27,6 +27,7 @@ import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -118,7 +119,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer { * @see com.querydsl.mongodb.MongodbSerializer#asDocument(java.lang.String, java.lang.Object) */ @Override - protected DBObject asDBObject(String key, Object value) { + protected DBObject asDBObject(@Nullable String key, @Nullable Object value) { value = value instanceof Optional ? ((Optional) value).orElse(null) : value; @@ -135,7 +136,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer { * @see com.querydsl.mongodb.MongodbSerializer#isReference(com.querydsl.core.types.Path) */ @Override - protected boolean isReference(Path path) { + protected boolean isReference(@Nullable Path path) { MongoPersistentProperty property = getPropertyForPotentialDbRef(path); return property == null ? false : property.isAssociation(); @@ -146,7 +147,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer { * @see com.querydsl.mongodb.MongodbSerializer#asReference(java.lang.Object) */ @Override - protected DBRef asReference(Object constant) { + protected DBRef asReference(@Nullable Object constant) { return asReference(constant, null); } @@ -159,7 +160,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer { * @see com.querydsl.mongodb.MongodbSerializer#asDBKey(com.querydsl.core.types.Operation, int) */ @Override - protected String asDBKey(Operation expr, int index) { + protected String asDBKey(@Nullable Operation expr, int index) { Expression arg = expr.getArg(index); String key = super.asDBKey(expr, index); @@ -183,7 +184,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer { * (non-Javadoc) * @see com.querydsl.mongodb.MongodbSerializer#convert(com.querydsl.core.types.Path, com.querydsl.core.types.Constant) */ - protected Object convert(Path path, Constant constant) { + protected Object convert(@Nullable Path path, @Nullable Constant constant) { if (!isReference(path)) { return super.convert(path, constant); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/package-info.java index 9520a0833..1d0b8beeb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/package-info.java @@ -1,5 +1,6 @@ /** * Support infrastructure for query derivation of MongoDB specific repositories. */ +@org.springframework.lang.NonNullApi package org.springframework.data.mongodb.repository.support; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/package-info.java index bfee8e660..34b262fd2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/package-info.java @@ -14,7 +14,8 @@ * limitations under the License. */ /** - * * @author Thomas Darimont */ -package org.springframework.data.mongodb.util; \ No newline at end of file +@org.springframework.lang.NonNullApi +package org.springframework.data.mongodb.util; + diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java index 9705d299f..d677f404c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java @@ -201,7 +201,7 @@ public abstract class MongoOperationsUnitTests { public void doWith(MongoOperations operations) { operations.executeCommand(""); } - }.assertDataAccessException(); + }.assertException(IllegalArgumentException.class); } @Test diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index 4cdb3fbef..ee7549034 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -692,7 +692,7 @@ public class MongoTemplateTests { p = template.findAndModify(query, update, new FindAndModifyOptions().returnNew(true), Person.class); assertThat(p.getAge(), is(26)); - p = template.findAndModify(query, update, null, Person.class, "person"); + p = template.findAndModify(query, update, new FindAndModifyOptions(), Person.class, "person"); assertThat(p.getAge(), is(26)); p = template.findOne(query, Person.class); assertThat(p.getAge(), is(27)); @@ -1157,7 +1157,7 @@ public class MongoTemplateTests { }); } - @Test // DATADOC-166 + @Test(expected = IllegalArgumentException.class) // DATADOC-166, DATAMONGO-1762 public void removingNullIsANoOp() { template.remove((Object) null); } @@ -1227,7 +1227,7 @@ public class MongoTemplateTests { DBRef first = new DBRef("foo", new ObjectId()); DBRef second = new DBRef("bar", new ObjectId()); - template.updateFirst(null, update("dbRefs", Arrays.asList(first, second)), ClassWithDBRefs.class); + template.updateFirst(new Query(), update("dbRefs", Arrays.asList(first, second)), ClassWithDBRefs.class); } class ClassWithDBRefs { @@ -1288,7 +1288,7 @@ public class MongoTemplateTests { template.save(dave); template.save(carter); - assertThat(template.count(null, Person.class), is(2L)); + assertThat(template.count(new Query(), Person.class), is(2L)); assertThat(template.count(query(where("firstName").is("Carter")), Person.class), is(1L)); } @@ -1569,11 +1569,9 @@ public class MongoTemplateTests { assertThat(person.version, is(0)); } - @Test // DATAMONGO-568 + @Test(expected = IllegalArgumentException.class) // DATAMONGO-568, DATAMONGO-1762 public void queryCantBeNull() { - - List result = template.findAll(PersonWithIdPropertyOfTypeObjectId.class); - assertThat(template.find(null, PersonWithIdPropertyOfTypeObjectId.class), is(result)); + template.find(null, PersonWithIdPropertyOfTypeObjectId.class); } @Test // DATAMONGO-620 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java index dedbbb056..50b2f3224 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java @@ -136,7 +136,9 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { when(findIterable.collation(Mockito.any())).thenReturn(findIterable); when(findIterable.limit(anyInt())).thenReturn(findIterable); when(mapReduceIterable.collation(Mockito.any())).thenReturn(mapReduceIterable); + when(mapReduceIterable.sort(Mockito.any())).thenReturn(mapReduceIterable); when(mapReduceIterable.iterator()).thenReturn(cursor); + when(mapReduceIterable.filter(any())).thenReturn(mapReduceIterable); this.mappingContext = new MongoMappingContext(); this.converter = new MappingMongoConverter(new DefaultDbRefResolver(factory), mappingContext); @@ -435,7 +437,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { MongoCursor cursor = mock(MongoCursor.class); MapReduceIterable output = mock(MapReduceIterable.class); when(output.limit(anyInt())).thenReturn(output); - when(output.sort(Mockito.any(Document.class))).thenReturn(output); + when(output.sort(any())).thenReturn(output); when(output.filter(Mockito.any(Document.class))).thenReturn(output); when(output.iterator()).thenReturn(cursor); when(cursor.hasNext()).thenReturn(false); @@ -456,7 +458,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { MongoCursor cursor = mock(MongoCursor.class); MapReduceIterable output = mock(MapReduceIterable.class); when(output.limit(anyInt())).thenReturn(output); - when(output.sort(Mockito.any(Document.class))).thenReturn(output); + when(output.sort(any())).thenReturn(output); when(output.filter(Mockito.any(Document.class))).thenReturn(output); when(output.iterator()).thenReturn(cursor); when(cursor.hasNext()).thenReturn(false); @@ -477,9 +479,12 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { MongoCursor cursor = mock(MongoCursor.class); MapReduceIterable output = mock(MapReduceIterable.class); when(output.limit(anyInt())).thenReturn(output); + when(output.sort(any())).thenReturn(output); + when(output.filter(any())).thenReturn(output); when(output.iterator()).thenReturn(cursor); when(cursor.hasNext()).thenReturn(false); + when(collection.mapReduce(anyString(), anyString())).thenReturn(output); template.mapReduce("collection", "function(){}", "function(key,values){}", new MapReduceOptions().limit(1000), @@ -494,7 +499,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { MongoCursor cursor = mock(MongoCursor.class); MapReduceIterable output = mock(MapReduceIterable.class); when(output.limit(anyInt())).thenReturn(output); - when(output.sort(Mockito.any(Document.class))).thenReturn(output); + when(output.sort(any())).thenReturn(output); when(output.filter(Mockito.any(Document.class))).thenReturn(output); when(output.iterator()).thenReturn(cursor); when(cursor.hasNext()).thenReturn(false); @@ -655,7 +660,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { @Test // DATAMONGO-1518 public void findShouldUseCollationWhenPresent() { - template.find(new BasicQuery("{}").collation(Collation.of("fr")), AutogenerateableId.class); + template.find(new BasicQuery("{'foo' : 'bar'}").collation(Collation.of("fr")), AutogenerateableId.class); verify(findIterable).collation(eq(com.mongodb.client.model.Collation.builder().locale("fr").build())); } @@ -663,7 +668,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { @Test // DATAMONGO-1518 public void findOneShouldUseCollationWhenPresent() { - template.findOne(new BasicQuery("{}").collation(Collation.of("fr")), AutogenerateableId.class); + template.findOne(new BasicQuery("{'foo' : 'bar'}").collation(Collation.of("fr")), AutogenerateableId.class); verify(findIterable).collation(eq(com.mongodb.client.model.Collation.builder().locale("fr").build())); } @@ -817,7 +822,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { template.doFind("star-wars", new Document(), new Document(), Person.class, PersonSpELProjection.class, null); - verify(findIterable, never()).projection(any()); + verify(findIterable).projection(eq(new Document())); } @Test // DATAMONGO-1733 @@ -825,7 +830,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { template.doFind("star-wars", new Document(), new Document(), Person.class, Jedi.class, null); - verify(findIterable, never()).projection(any()); + verify(findIterable).projection(eq(new Document())); } @Test // DATAMONGO-1733 @@ -841,7 +846,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { template.doFind("star-wars", new Document(), new Document(), Person.class, Person.class, null); - verify(findIterable, never()).projection(any()); + verify(findIterable).projection(eq(new Document())); } @Test // DATAMONGO-1733 @@ -849,7 +854,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { template.doFind("star-wars", new Document(), new Document(), Person.class, PersonExtended.class, null); - verify(findIterable, never()).projection(any()); + verify(findIterable).projection(eq(new Document())); } class AutogenerateableId { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java index 1961f1cb7..184f67f74 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java @@ -62,7 +62,7 @@ public class GridFsTemplateIntegrationTests { @Before public void setUp() { - operations.delete(null); + operations.delete(new Query()); } @Test // DATAMONGO-6 @@ -164,19 +164,24 @@ public class GridFsTemplateIntegrationTests { assertEquals(((BsonObjectId) files.get(2).getId()).getValue(), third); } - @Test // DATAMONGO-534 - public void queryingWithNullQueryReturnsAllFiles() throws IOException { + @Test // DATAMONGO-534, DATAMONGO-1762 + public void queryingWithEmptyQueryReturnsAllFiles() throws IOException { ObjectId reference = operations.store(resource.getInputStream(), "foo.xml"); List files = new ArrayList(); - GridFSFindIterable result = operations.find(null); + GridFSFindIterable result = operations.find(new Query()); result.into(files); assertThat(files, hasSize(1)); assertEquals(((BsonObjectId) files.get(0).getId()).getValue(), reference); } + @Test(expected = IllegalArgumentException.class) // DATAMONGO-1762 + public void queryingWithNullQueryThrowsException() { + operations.find(null); + } + @Test // DATAMONGO-813 public void getResourceShouldReturnNullForNonExistingResource() { assertThat(operations.getResource("doesnotexist"), is(nullValue()));