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()));