From 2b97b37b7f9bdccf8a84583e9c0246da1c769bf7 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 19 Nov 2024 10:10:07 +0100 Subject: [PATCH 01/17] Prepare next development iteration. See #4836 --- pom.xml | 2 +- spring-data-mongodb-distribution/pom.xml | 2 +- spring-data-mongodb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index ded4d85d02..eea14dc54b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.0-SNAPSHOT + 5.0.0-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index 58c63dfc97..fc88571622 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -15,7 +15,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.0-SNAPSHOT + 5.0.0-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index 37e68c6f78..77e77d83de 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -13,7 +13,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.0-SNAPSHOT + 5.0.0-SNAPSHOT ../pom.xml From 7fd5dd5ff670ca5ce21d1ec5d602481636fad529 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 19 Nov 2024 10:10:10 +0100 Subject: [PATCH 02/17] After release cleanups. See #4836 --- Jenkinsfile | 2 +- pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0e83b47e2f..59898e5d9b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -9,7 +9,7 @@ pipeline { triggers { pollSCM 'H/10 * * * *' - upstream(upstreamProjects: "spring-data-commons/main", threshold: hudson.model.Result.SUCCESS) + upstream(upstreamProjects: "spring-data-commons/4.0.x", threshold: hudson.model.Result.SUCCESS) } options { diff --git a/pom.xml b/pom.xml index eea14dc54b..a6f11626cc 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.data.build spring-data-parent - 3.5.0-SNAPSHOT + 4.0.0-SNAPSHOT @@ -26,7 +26,7 @@ multi spring-data-mongodb - 3.5.0-SNAPSHOT + 4.0.0-SNAPSHOT 5.3.1 ${mongo} ${mongo} From e0f183e96e74cbc338bd86dca868919c791d2073 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 19 Nov 2024 15:30:17 +0100 Subject: [PATCH 03/17] Adopt to deprecation removals in Commons. Closes #4837 --- .../core/convert/MappingMongoConverter.java | 3 +- .../UnwrappedMongoPersistentEntity.java | 6 -- .../repository/query/AbstractMongoQuery.java | 61 ++-------------- .../query/AbstractReactiveMongoQuery.java | 66 ------------------ .../query/DefaultSpELExpressionEvaluator.java | 69 ------------------- .../repository/query/PartTreeMongoQuery.java | 25 ------- .../query/ReactiveMongoQueryMethod.java | 7 +- .../query/ReactivePartTreeMongoQuery.java | 23 ------- .../query/ReactiveStringBasedAggregation.java | 20 ------ .../query/ReactiveStringBasedMongoQuery.java | 67 +----------------- .../query/StringBasedAggregation.java | 27 -------- .../query/StringBasedMongoQuery.java | 44 ------------ .../support/MongoRepositoryFactory.java | 2 - .../ReactiveMongoRepositoryFactory.java | 10 ++- .../ReactiveMongoRepositoryFactoryBean.java | 10 --- .../util/json/ParameterBindingContext.java | 25 ------- .../json/ParameterBindingDocumentCodec.java | 2 +- .../data/mongodb/core/MongoTemplateTests.java | 6 +- .../data/mongodb/core/Venue.java | 4 +- .../DbRefMappingMongoConverterUnitTests.java | 6 +- .../MappingMongoConverterUnitTests.java | 19 +++-- .../core/convert/ObjectPathUnitTests.java | 8 +-- .../core/convert/UpdateMapperUnitTests.java | 2 +- .../data/mongodb/core/geo/GeoJsonTests.java | 4 +- ...ersistentEntityIndexResolverUnitTests.java | 6 +- ...BasicMongoPersistentPropertyUnitTests.java | 12 ++-- .../data/mongodb/core/mapping/Person.java | 4 +- .../core/mapping/PersonCustomIdName.java | 4 +- .../mongodb/performance/PerformanceTests.java | 6 +- .../performance/ReactivePerformanceTests.java | 6 +- .../mongodb/repository/PersonAggregate.java | 4 +- .../ReactiveMongoRepositoryTests.java | 2 - .../SimpleReactiveMongoRepositoryTests.java | 2 - ...sitoryConfigurationExtensionUnitTests.java | 6 +- ...sitoryConfigurationExtensionUnitTests.java | 6 +- .../query/MongoQueryExecutionUnitTests.java | 15 ++-- .../query/PartTreeMongoQueryUnitTests.java | 6 +- .../ReactiveMongoQueryExecutionUnitTests.java | 6 +- ...activeStringBasedAggregationUnitTests.java | 20 +++--- ...eactiveStringBasedMongoQueryUnitTests.java | 14 ++-- .../StringBasedAggregationUnitTests.java | 20 +++--- .../ROOT/pages/mongodb/mapping/mapping.adoc | 8 +-- .../mongodb/template-query-operations.adoc | 2 +- 43 files changed, 104 insertions(+), 561 deletions(-) delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/DefaultSpELExpressionEvaluator.java 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 864cc1c3e3..1d40573b81 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 @@ -71,7 +71,6 @@ import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider; import org.springframework.data.mapping.model.PropertyValueProvider; import org.springframework.data.mapping.model.SpELContext; -import org.springframework.data.mapping.model.SpELExpressionParameterValueProvider; import org.springframework.data.mapping.model.ValueExpressionEvaluator; import org.springframework.data.mapping.model.ValueExpressionParameterValueProvider; import org.springframework.data.mongodb.CodecRegistryProvider; @@ -2059,7 +2058,7 @@ public T getPropertyValue(MongoPersistentProperty property) { } /** - * Extension of {@link SpELExpressionParameterValueProvider} to recursively trigger value conversion on the raw + * Extension of {@link ValueExpressionParameterValueProvider} to recursively trigger value conversion on the raw * resolved SpEL value. * * @author Oliver Gierke diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentEntity.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentEntity.java index fed08815b8..6b032a1558 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentEntity.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentEntity.java @@ -98,13 +98,7 @@ public String getName() { return delegate.getName(); } - @Override @Nullable - @Deprecated - public PreferredConstructor getPersistenceConstructor() { - return delegate.getPersistenceConstructor(); - } - @Override public InstanceCreatorMetadata getInstanceCreatorMetadata() { return delegate.getInstanceCreatorMetadata(); 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 4d0d604a27..910665253d 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 @@ -21,11 +21,8 @@ import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; -import org.springframework.core.env.StandardEnvironment; import org.springframework.data.expression.ValueEvaluationContextProvider; import org.springframework.data.expression.ValueExpression; -import org.springframework.data.expression.ValueExpressionParser; -import org.springframework.data.mapping.model.SpELExpressionEvaluator; import org.springframework.data.mapping.model.ValueExpressionEvaluator; import org.springframework.data.mongodb.core.ExecutableFindOperation.ExecutableFind; import org.springframework.data.mongodb.core.ExecutableFindOperation.FindWithQuery; @@ -47,16 +44,10 @@ import org.springframework.data.mongodb.util.json.ParameterBindingContext; import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec; import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ValueExpressionDelegate; -import org.springframework.data.spel.ExpressionDependencies; import org.springframework.data.util.Lazy; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -84,36 +75,6 @@ public abstract class AbstractMongoQuery implements RepositoryQuery { private final ValueExpressionDelegate valueExpressionDelegate; private final ValueEvaluationContextProvider valueEvaluationContextProvider; - /** - * Creates a new {@link AbstractMongoQuery} from the given {@link MongoQueryMethod} and {@link MongoOperations}. - * - * @param method must not be {@literal null}. - * @param operations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. - * @deprecated use the constructor version with {@link ValueExpressionDelegate} - */ - @Deprecated(since = "4.4.0") - public AbstractMongoQuery(MongoQueryMethod method, MongoOperations operations, ExpressionParser expressionParser, - QueryMethodEvaluationContextProvider evaluationContextProvider) { - - Assert.notNull(operations, "MongoOperations must not be null"); - Assert.notNull(method, "MongoQueryMethod must not be null"); - Assert.notNull(expressionParser, "SpelExpressionParser must not be null"); - Assert.notNull(evaluationContextProvider, "QueryMethodEvaluationContextProvider must not be null"); - - this.method = method; - this.operations = operations; - - MongoEntityMetadata metadata = method.getEntityInformation(); - Class type = metadata.getCollectionEntity().getType(); - - this.executableFind = operations.query(type); - this.executableUpdate = operations.update(type); - this.valueExpressionDelegate = new ValueExpressionDelegate(new QueryMethodValueEvaluationContextAccessor(new StandardEnvironment(), evaluationContextProvider.getEvaluationContextProvider()), ValueExpressionParser.create(() -> expressionParser)); - this.valueEvaluationContextProvider = valueExpressionDelegate.createValueContextProvider(method.getParameters()); - } - /** * Creates a new {@link AbstractMongoQuery} from the given {@link MongoQueryMethod} and {@link MongoOperations}. * @@ -185,7 +146,8 @@ protected Object doExecute(MongoQueryMethod method, ResultProcessor processor, C } /** - * If present apply the {@link com.mongodb.ReadPreference} from the {@link org.springframework.data.mongodb.repository.ReadPreference} annotation. + * If present apply the {@link com.mongodb.ReadPreference} from the + * {@link org.springframework.data.mongodb.repository.ReadPreference} annotation. * * @param query must not be {@literal null}. * @return never {@literal null}. @@ -396,20 +358,6 @@ protected ParameterBindingDocumentCodec getParameterBindingCodec() { return codec.get(); } - /** - * Obtain a the {@link EvaluationContext} suitable to evaluate expressions backed by the given dependencies. - * - * @param dependencies must not be {@literal null}. - * @param accessor must not be {@literal null}. - * @return the {@link SpELExpressionEvaluator}. - * @since 2.4 - */ - protected SpELExpressionEvaluator getSpELExpressionEvaluatorFor(ExpressionDependencies dependencies, - ConvertingParameterAccessor accessor) { - - return new DefaultSpELExpressionEvaluator(new SpelExpressionParser(), valueEvaluationContextProvider.getEvaluationContext(accessor.getValues(), dependencies).getEvaluationContext()); - } - /** * Obtain a {@link ValueExpressionEvaluator} suitable to evaluate expressions. * @@ -418,8 +366,9 @@ protected SpELExpressionEvaluator getSpELExpressionEvaluatorFor(ExpressionDepend * @since 4.4.0 */ protected ValueExpressionEvaluator getExpressionEvaluatorFor(MongoParameterAccessor accessor) { - return new ValueExpressionDelegateValueExpressionEvaluator(valueExpressionDelegate, (ValueExpression expression) -> - valueEvaluationContextProvider.getEvaluationContext(accessor.getValues(), expression.getExpressionDependencies())); + return new ValueExpressionDelegateValueExpressionEvaluator(valueExpressionDelegate, + (ValueExpression expression) -> valueEvaluationContextProvider.getEvaluationContext(accessor.getValues(), + expression.getExpressionDependencies())); } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java index a5754a4e46..76b4b2e088 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java @@ -27,14 +27,11 @@ import org.reactivestreams.Publisher; import org.springframework.core.convert.converter.Converter; -import org.springframework.core.env.StandardEnvironment; import org.springframework.data.expression.ReactiveValueEvaluationContextProvider; import org.springframework.data.expression.ValueEvaluationContext; import org.springframework.data.expression.ValueEvaluationContextProvider; import org.springframework.data.expression.ValueExpression; -import org.springframework.data.expression.ValueExpressionParser; import org.springframework.data.mapping.model.EntityInstantiators; -import org.springframework.data.mapping.model.SpELExpressionEvaluator; import org.springframework.data.mapping.model.ValueExpressionEvaluator; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.ReactiveFindOperation.FindWithProjection; @@ -56,14 +53,10 @@ import org.springframework.data.mongodb.util.json.ParameterBindingContext; import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec; import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor; -import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.spel.ExpressionDependencies; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -89,45 +82,6 @@ public abstract class AbstractReactiveMongoQuery implements RepositoryQuery { private final ValueExpressionDelegate valueExpressionDelegate; private final ReactiveValueEvaluationContextProvider valueEvaluationContextProvider; - /** - * Creates a new {@link AbstractReactiveMongoQuery} from the given {@link MongoQueryMethod} and - * {@link MongoOperations}. - * - * @param method must not be {@literal null}. - * @param operations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. - * @deprecated use the constructor version with {@link ValueExpressionDelegate} - */ - @Deprecated(since = "4.4.0") - public AbstractReactiveMongoQuery(ReactiveMongoQueryMethod method, ReactiveMongoOperations operations, - ExpressionParser expressionParser, ReactiveQueryMethodEvaluationContextProvider evaluationContextProvider) { - - Assert.notNull(method, "MongoQueryMethod must not be null"); - Assert.notNull(operations, "ReactiveMongoOperations must not be null"); - Assert.notNull(expressionParser, "SpelExpressionParser must not be null"); - Assert.notNull(evaluationContextProvider, "ReactiveEvaluationContextExtension must not be null"); - - this.method = method; - this.operations = operations; - this.instantiators = new EntityInstantiators(); - this.valueExpressionDelegate = new ValueExpressionDelegate( - new QueryMethodValueEvaluationContextAccessor(new StandardEnvironment(), - evaluationContextProvider.getEvaluationContextProvider()), - ValueExpressionParser.create(() -> expressionParser)); - - MongoEntityMetadata metadata = method.getEntityInformation(); - Class type = metadata.getCollectionEntity().getType(); - - this.findOperationWithProjection = operations.query(type); - this.updateOps = operations.update(type); - ValueEvaluationContextProvider valueContextProvider = valueExpressionDelegate - .createValueContextProvider(method.getParameters()); - Assert.isInstanceOf(ReactiveValueEvaluationContextProvider.class, valueContextProvider, - "ValueEvaluationContextProvider must be reactive"); - this.valueEvaluationContextProvider = (ReactiveValueEvaluationContextProvider) valueContextProvider; - } - /** * Creates a new {@link AbstractReactiveMongoQuery} from the given {@link MongoQueryMethod} and * {@link MongoOperations}. @@ -460,26 +414,6 @@ protected Mono getParameterBindingCodec() { return getCodecRegistry().map(ParameterBindingDocumentCodec::new); } - /** - * Obtain a {@link Mono publisher} emitting the {@link SpELExpressionEvaluator} suitable to evaluate expressions - * backed by the given dependencies. - * - * @param dependencies must not be {@literal null}. - * @param accessor must not be {@literal null}. - * @return a {@link Mono} emitting the {@link SpELExpressionEvaluator} when ready. - * @since 3.4 - * @deprecated since 4.4.0, use - * {@link #getValueExpressionEvaluatorLater(ExpressionDependencies, MongoParameterAccessor)} instead - */ - @Deprecated(since = "4.4.0") - protected Mono getSpelEvaluatorFor(ExpressionDependencies dependencies, - MongoParameterAccessor accessor) { - return valueEvaluationContextProvider.getEvaluationContextLater(accessor.getValues(), dependencies) - .map(evaluationContext -> (SpELExpressionEvaluator) new DefaultSpELExpressionEvaluator( - new SpelExpressionParser(), evaluationContext.getEvaluationContext())) - .defaultIfEmpty(DefaultSpELExpressionEvaluator.unsupported()); - } - /** * Obtain a {@link ValueExpressionEvaluator} suitable to evaluate expressions. * diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/DefaultSpELExpressionEvaluator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/DefaultSpELExpressionEvaluator.java deleted file mode 100644 index 16a1e55226..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/DefaultSpELExpressionEvaluator.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2020-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.repository.query; - -import org.springframework.data.mapping.model.SpELExpressionEvaluator; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.ExpressionParser; - -/** - * Simple {@link SpELExpressionEvaluator} implementation using {@link ExpressionParser} and {@link EvaluationContext}. - * - * @author Mark Paluch - * @since 3.1 - */ -class DefaultSpELExpressionEvaluator implements SpELExpressionEvaluator { - - private final ExpressionParser parser; - private final EvaluationContext context; - - DefaultSpELExpressionEvaluator(ExpressionParser parser, EvaluationContext context) { - this.parser = parser; - this.context = context; - } - - /** - * Return a {@link SpELExpressionEvaluator} that does not support expression evaluation. - * - * @return a {@link SpELExpressionEvaluator} that does not support expression evaluation. - * @since 3.1 - */ - public static SpELExpressionEvaluator unsupported() { - return NoOpExpressionEvaluator.INSTANCE; - } - - @Override - @SuppressWarnings("unchecked") - public T evaluate(String expression) { - return (T) parser.parseExpression(expression).getValue(context, Object.class); - } - - /** - * {@link SpELExpressionEvaluator} that does not support SpEL evaluation. - * - * @author Mark Paluch - * @since 3.1 - */ - enum NoOpExpressionEvaluator implements SpELExpressionEvaluator { - - INSTANCE; - - @Override - public T evaluate(String expression) { - throw new UnsupportedOperationException("Expression evaluation not supported"); - } - } -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQuery.java index afabf9c37e..fdf08ba9d8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQuery.java @@ -18,8 +18,6 @@ import org.bson.Document; import org.bson.json.JsonParseException; -import org.springframework.core.env.StandardEnvironment; -import org.springframework.data.expression.ValueExpressionParser; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.MongoTemplate; @@ -29,14 +27,11 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.TextCriteria; import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ReturnedType; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.expression.ExpressionParser; import org.springframework.util.StringUtils; /** @@ -54,26 +49,6 @@ public class PartTreeMongoQuery extends AbstractMongoQuery { private final MappingContext context; private final ResultProcessor processor; - /** - * Creates a new {@link PartTreeMongoQuery} from the given {@link QueryMethod} and {@link MongoTemplate}. - * - * @param method must not be {@literal null}. - * @param mongoOperations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. - * @deprecated since 4.4, use the constructors accepting {@link QueryMethodValueEvaluationContextAccessor} instead. - */ - @Deprecated(since = "4.4.0") - public PartTreeMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations, ExpressionParser expressionParser, - QueryMethodEvaluationContextProvider evaluationContextProvider) { - super(method, mongoOperations, expressionParser, evaluationContextProvider); - - this.processor = method.getResultProcessor(); - this.tree = new PartTree(method.getName(), processor.getReturnedType().getDomainType()); - this.isGeoNearQuery = method.isGeoNearQuery(); - this.context = mongoOperations.getConverter().getMappingContext(); - } - /** * Creates a new {@link PartTreeMongoQuery} from the given {@link QueryMethod} and {@link MongoTemplate}. * diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java index 8df1ba487e..966bbc0a26 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java @@ -15,8 +15,6 @@ */ package org.springframework.data.mongodb.repository.query; -import static org.springframework.data.repository.util.ClassUtils.*; - import java.lang.reflect.Method; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -35,6 +33,7 @@ import org.springframework.data.repository.util.ReactiveWrapperConverters; import org.springframework.data.util.Lazy; import org.springframework.data.util.ReactiveWrappers; +import org.springframework.data.util.ReflectionUtils; import org.springframework.data.util.TypeInformation; import org.springframework.util.ClassUtils; @@ -130,7 +129,7 @@ public boolean hasReactiveWrapperParameter() { @Override public void verify() { - if (hasParameterOfType(method, Pageable.class)) { + if (ReflectionUtils.hasParameterOfType(method, Pageable.class)) { TypeInformation returnType = TypeInformation.fromReturnTypeOf(method); @@ -139,7 +138,7 @@ public void verify() { && (PAGE_TYPE.isAssignableFrom(returnType.getRequiredComponentType()) || SLICE_TYPE.isAssignableFrom(returnType.getRequiredComponentType())); - if (hasParameterOfType(method, Sort.class)) { + if (ReflectionUtils.hasParameterOfType(method, Sort.class)) { throw new IllegalStateException(String.format("Method must not have Pageable *and* Sort parameter;" + " Use sorting capabilities on Pageable instead; Offending method: %s", method)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactivePartTreeMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactivePartTreeMongoQuery.java index 5787cca5a5..b27adfab93 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactivePartTreeMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactivePartTreeMongoQuery.java @@ -28,14 +28,11 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.TextCriteria; import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor; -import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ReturnedType; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.expression.ExpressionParser; import org.springframework.util.StringUtils; /** @@ -52,26 +49,6 @@ public class ReactivePartTreeMongoQuery extends AbstractReactiveMongoQuery { private final MappingContext context; private final ResultProcessor processor; - /** - * Creates a new {@link ReactivePartTreeMongoQuery} from the given {@link QueryMethod} and {@link MongoTemplate}. - * - * @param method must not be {@literal null}. - * @param mongoOperations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. - * @deprecated since 4.4.0, use the constructors accepting {@link QueryMethodValueEvaluationContextAccessor} instead. - */ - @Deprecated(since = "4.4.0") - public ReactivePartTreeMongoQuery(ReactiveMongoQueryMethod method, ReactiveMongoOperations mongoOperations, - ExpressionParser expressionParser, ReactiveQueryMethodEvaluationContextProvider evaluationContextProvider) { - super(method, mongoOperations, expressionParser, evaluationContextProvider); - - this.processor = method.getResultProcessor(); - this.tree = new PartTree(method.getName(), processor.getReturnedType().getDomainType()); - this.isGeoNearQuery = method.isGeoNearQuery(); - this.context = mongoOperations.getConverter().getMappingContext(); - } - /** * Creates a new {@link ReactivePartTreeMongoQuery} from the given {@link QueryMethod} and {@link MongoTemplate}. * diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregation.java index ff01d8f8a3..cf6e7231f8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregation.java @@ -29,11 +29,9 @@ import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.util.ReflectionUtils; -import org.springframework.expression.ExpressionParser; import org.springframework.lang.Nullable; /** @@ -49,24 +47,6 @@ public class ReactiveStringBasedAggregation extends AbstractReactiveMongoQuery { private final ReactiveMongoOperations reactiveMongoOperations; private final MongoConverter mongoConverter; - /** - * @param method must not be {@literal null}. - * @param reactiveMongoOperations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. - * @deprecated since 4.4.0, use the constructors accepting {@link ValueExpressionDelegate} instead. - */ - @Deprecated(since = "4.4.0") - public ReactiveStringBasedAggregation(ReactiveMongoQueryMethod method, - ReactiveMongoOperations reactiveMongoOperations, ExpressionParser expressionParser, - ReactiveQueryMethodEvaluationContextProvider evaluationContextProvider) { - - super(method, reactiveMongoOperations, expressionParser, evaluationContextProvider); - - this.reactiveMongoOperations = reactiveMongoOperations; - this.mongoConverter = reactiveMongoOperations.getConverter(); - } - /** * @param method must not be {@literal null}. * @param reactiveMongoOperations must not be {@literal null}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java index 0e980fcfaf..562ee026fc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java @@ -28,12 +28,8 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.util.json.ParameterBindingContext; import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec; -import org.springframework.data.repository.query.ReactiveExtensionAwareQueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.spel.ExpressionDependencies; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.lang.NonNull; import org.springframework.util.Assert; @@ -59,67 +55,8 @@ public class ReactiveStringBasedMongoQuery extends AbstractReactiveMongoQuery { private final boolean isDeleteQuery; /** - * Creates a new {@link ReactiveStringBasedMongoQuery} for the given {@link MongoQueryMethod} and - * {@link MongoOperations}. - * - * @param method must not be {@literal null}. - * @param mongoOperations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. - * @deprecated since 4.4.0, use the constructors accepting {@link ValueExpressionDelegate} instead. - */ - @Deprecated(since = "4.4.0") - public ReactiveStringBasedMongoQuery(ReactiveMongoQueryMethod method, ReactiveMongoOperations mongoOperations, - ExpressionParser expressionParser, ReactiveQueryMethodEvaluationContextProvider evaluationContextProvider) { - this(method.getAnnotatedQuery(), method, mongoOperations, expressionParser, evaluationContextProvider); - } - - /** - * Creates a new {@link ReactiveStringBasedMongoQuery} for the given {@link String}, {@link MongoQueryMethod}, - * {@link MongoOperations}, {@link SpelExpressionParser} and - * {@link ReactiveExtensionAwareQueryMethodEvaluationContextProvider}. - * - * @param query must not be {@literal null}. - * @param method must not be {@literal null}. - * @param mongoOperations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @deprecated since 4.4.0, use the constructors accepting {@link ValueExpressionDelegate} instead. - */ - @Deprecated(since = "4.4.0") - public ReactiveStringBasedMongoQuery(String query, ReactiveMongoQueryMethod method, - ReactiveMongoOperations mongoOperations, ExpressionParser expressionParser, - ReactiveQueryMethodEvaluationContextProvider evaluationContextProvider) { - super(method, mongoOperations, expressionParser, evaluationContextProvider); - - Assert.notNull(query, "Query must not be null"); - - this.query = query; - this.expressionParser = ValueExpressionParser.create(() -> expressionParser); - this.fieldSpec = method.getFieldSpecification(); - - if (method.hasAnnotatedQuery()) { - - org.springframework.data.mongodb.repository.Query queryAnnotation = method.getQueryAnnotation(); - - this.isCountQuery = queryAnnotation.count(); - this.isExistsQuery = queryAnnotation.exists(); - this.isDeleteQuery = queryAnnotation.delete(); - - if (hasAmbiguousProjectionFlags(this.isCountQuery, this.isExistsQuery, this.isDeleteQuery)) { - throw new IllegalArgumentException(String.format(COUNT_EXISTS_AND_DELETE, method)); - } - - } else { - - this.isCountQuery = false; - this.isExistsQuery = false; - this.isDeleteQuery = false; - } - } - - /** - * Creates a new {@link ReactiveStringBasedMongoQuery} for the given {@link MongoQueryMethod}, - * {@link MongoOperations} and {@link ValueExpressionDelegate}. + * Creates a new {@link ReactiveStringBasedMongoQuery} for the given {@link MongoQueryMethod}, {@link MongoOperations} + * and {@link ValueExpressionDelegate}. * * @param method must not be {@literal null}. * @param mongoOperations must not be {@literal null}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedAggregation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedAggregation.java index 7ad5d78fa6..5596435eb0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedAggregation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedAggregation.java @@ -29,12 +29,9 @@ import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.util.ReflectionUtils; -import org.springframework.expression.ExpressionParser; import org.springframework.lang.Nullable; /** @@ -51,30 +48,6 @@ public class StringBasedAggregation extends AbstractMongoQuery { private final MongoOperations mongoOperations; private final MongoConverter mongoConverter; - /** - * Creates a new {@link StringBasedAggregation} from the given {@link MongoQueryMethod} and {@link MongoOperations}. - * - * @param method must not be {@literal null}. - * @param mongoOperations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. - * @deprecated since 4.4.0, use the constructors accepting {@link QueryMethodValueEvaluationContextAccessor} instead. - */ - @Deprecated(since = "4.4.0") - public StringBasedAggregation(MongoQueryMethod method, MongoOperations mongoOperations, - ExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) { - super(method, mongoOperations, expressionParser, evaluationContextProvider); - - if (method.isPageQuery()) { - throw new InvalidMongoDbApiUsageException(String.format( - "Repository aggregation method '%s' does not support '%s' return type; Please use 'Slice' or 'List' instead", - method.getName(), method.getReturnType().getType().getSimpleName())); - } - - this.mongoOperations = mongoOperations; - this.mongoConverter = mongoOperations.getConverter(); - } - /** * Creates a new {@link StringBasedAggregation} from the given {@link MongoQueryMethod} and {@link MongoOperations}. * diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java index abc158f88a..5e2fba381b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java @@ -22,11 +22,8 @@ import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor; import org.springframework.data.repository.query.ValueExpressionDelegate; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.util.Assert; /** @@ -49,47 +46,6 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { private final boolean isExistsQuery; private final boolean isDeleteQuery; - /** - * Creates a new {@link StringBasedMongoQuery} for the given {@link MongoQueryMethod}, {@link MongoOperations}, - * {@link SpelExpressionParser} and {@link QueryMethodEvaluationContextProvider}. - * - * @param method must not be {@literal null}. - * @param mongoOperations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. - * @deprecated since 4.4.0, use the constructors accepting {@link ValueExpressionDelegate} instead. - */ - @Deprecated(since = "4.4.0") - public StringBasedMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations, - ExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) { - super(method, mongoOperations, expressionParser, evaluationContextProvider); - - String query = method.getAnnotatedQuery(); - Assert.notNull(query, "Query must not be null"); - - this.query = query; - this.fieldSpec = method.getFieldSpecification(); - - if (method.hasAnnotatedQuery()) { - - org.springframework.data.mongodb.repository.Query queryAnnotation = method.getQueryAnnotation(); - - this.isCountQuery = queryAnnotation.count(); - this.isExistsQuery = queryAnnotation.exists(); - this.isDeleteQuery = queryAnnotation.delete(); - - if (hasAmbiguousProjectionFlags(this.isCountQuery, this.isExistsQuery, this.isDeleteQuery)) { - throw new IllegalArgumentException(String.format(COUNT_EXISTS_AND_DELETE, method)); - } - - } else { - - this.isCountQuery = false; - this.isExistsQuery = false; - this.isDeleteQuery = false; - } - } - /** * Creates a new {@link StringBasedMongoQuery} for the given {@link MongoQueryMethod}, {@link MongoOperations}, * {@link ValueExpressionDelegate}. 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 baf069c3a4..91a3e39cbe 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 @@ -42,7 +42,6 @@ import org.springframework.data.repository.core.support.RepositoryFactorySupport; import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.QueryLookupStrategy.Key; -import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.lang.Nullable; @@ -61,7 +60,6 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport { private final CrudMethodMetadataPostProcessor crudMethodMetadataPostProcessor = new CrudMethodMetadataPostProcessor(); private final MongoOperations operations; private final MappingContext, MongoPersistentProperty> mappingContext; - @Nullable private QueryMethodValueEvaluationContextAccessor accessor; /** * Creates a new {@link MongoRepositoryFactory} with the given {@link MongoOperations}. 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 3edfcdd2db..fe18fda758 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 @@ -21,7 +21,6 @@ import java.lang.reflect.Method; import java.util.Optional; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.ReactiveMongoOperations; @@ -44,7 +43,6 @@ import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor; -import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.lang.Nullable; @@ -77,7 +75,6 @@ public ReactiveMongoRepositoryFactory(ReactiveMongoOperations mongoOperations) { this.operations = mongoOperations; this.mappingContext = mongoOperations.getConverter().getMappingContext(); - setEvaluationContextProvider(ReactiveQueryMethodEvaluationContextProvider.DEFAULT); addRepositoryProxyPostProcessor(crudMethodMetadataPostProcessor); } @@ -132,7 +129,8 @@ protected Object getTargetRepository(RepositoryInformation information) { return targetRepository; } - @Override protected Optional getQueryLookupStrategy(Key key, + @Override + protected Optional getQueryLookupStrategy(Key key, ValueExpressionDelegate valueExpressionDelegate) { return Optional.of(new MongoQueryLookupStrategy(operations, mappingContext, valueExpressionDelegate)); } @@ -159,8 +157,8 @@ private MongoEntityInformation getEntityInformation(Class doma * @author Christoph Strobl */ private record MongoQueryLookupStrategy(ReactiveMongoOperations operations, - MappingContext, MongoPersistentProperty> mappingContext, - ValueExpressionDelegate delegate) implements QueryLookupStrategy { + MappingContext, MongoPersistentProperty> mappingContext, + ValueExpressionDelegate delegate) implements QueryLookupStrategy { @Override public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, ProjectionFactory factory, 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 4f9c0d945c..dfb7c00fe6 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 @@ -16,17 +16,13 @@ package org.springframework.data.mongodb.repository.support; import java.io.Serializable; -import java.util.Optional; -import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.ReactiveMongoOperations; 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.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.ReactiveExtensionAwareQueryMethodEvaluationContextProvider; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -94,12 +90,6 @@ protected RepositoryFactorySupport createRepositoryFactory() { return factory; } - @Override - protected Optional createDefaultQueryMethodEvaluationContextProvider( - ListableBeanFactory beanFactory) { - return Optional.of(new ReactiveExtensionAwareQueryMethodEvaluationContextProvider(beanFactory)); - } - /** * Creates and initializes a {@link RepositoryFactorySupport} instance. * diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingContext.java index b4fd13b3af..5678d959ce 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingContext.java @@ -19,7 +19,6 @@ import java.util.function.Function; import java.util.function.Supplier; -import org.springframework.data.mapping.model.SpELExpressionEvaluator; import org.springframework.data.mapping.model.ValueExpressionEvaluator; import org.springframework.data.spel.ExpressionDependencies; import org.springframework.data.util.Lazy; @@ -28,7 +27,6 @@ import org.springframework.expression.ExpressionParser; import org.springframework.expression.ParseException; import org.springframework.expression.ParserContext; -import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.lang.Nullable; /** @@ -44,29 +42,6 @@ public class ParameterBindingContext { private final ValueProvider valueProvider; private final ValueExpressionEvaluator expressionEvaluator; - /** - * @param valueProvider - * @param expressionParser - * @param evaluationContext - * @deprecated since 4.4.0, use {@link #ParameterBindingContext(ValueProvider, ExpressionParser, Supplier)} instead. - */ - @Deprecated(since = "4.4.0") - public ParameterBindingContext(ValueProvider valueProvider, SpelExpressionParser expressionParser, - EvaluationContext evaluationContext) { - this(valueProvider, expressionParser, () -> evaluationContext); - } - - /** - * @param valueProvider - * @param expressionEvaluator - * @since 3.1 - * @deprecated since 4.4.0, use {@link #ParameterBindingContext(ValueProvider, ValueExpressionEvaluator)} instead. - */ - @Deprecated(since = "4.4.0") - public ParameterBindingContext(ValueProvider valueProvider, SpELExpressionEvaluator expressionEvaluator) { - this(valueProvider, (ValueExpressionEvaluator) expressionEvaluator); - } - /** * @param valueProvider * @param expressionParser diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingDocumentCodec.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingDocumentCodec.java index ffa226ab69..adce99c904 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingDocumentCodec.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingDocumentCodec.java @@ -170,7 +170,7 @@ public void encode(final BsonWriter writer, final Document document, final Encod public Document decode(@Nullable String json, Object[] values) { return decode(json, new ParameterBindingContext((index) -> values[index], new SpelExpressionParser(), - EvaluationContextProvider.DEFAULT.getEvaluationContext(values))); + () -> EvaluationContextProvider.DEFAULT.getEvaluationContext(values))); } public Document decode(@Nullable String json, ParameterBindingContext bindingContext) { 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 83d4e30cc5..5d701de5f6 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 @@ -48,7 +48,7 @@ import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.Version; import org.springframework.data.auditing.IsNewAwareAuditingHandler; import org.springframework.data.domain.PageRequest; @@ -4469,7 +4469,7 @@ static class TestClass { LocalDateTime myDate; - @PersistenceConstructor + @PersistenceCreator TestClass(LocalDateTime myDate) { this.myDate = myDate; } @@ -4726,7 +4726,7 @@ static class DocumentWithLazyDBrefUsedInPresistenceConstructor { @org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) Document refToDocUsedInCtor; @org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) Document refToDocNotUsedInCtor; - @PersistenceConstructor + @PersistenceCreator public DocumentWithLazyDBrefUsedInPresistenceConstructor(Document refToDocUsedInCtor) { this.refToDocUsedInCtor = refToDocUsedInCtor; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/Venue.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/Venue.java index 09a0605ed7..13aba70afa 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/Venue.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/Venue.java @@ -19,7 +19,7 @@ import java.util.Date; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.mongodb.core.mapping.Document; @Document("newyork") @@ -30,7 +30,7 @@ public class Venue { private double[] location; private Date openingDate; - @PersistenceConstructor + @PersistenceCreator Venue(String name, double[] location) { super(); this.name = name; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java index b53531f301..787e8d6746 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java @@ -46,7 +46,7 @@ import org.springframework.data.annotation.AccessType; import org.springframework.data.annotation.AccessType.Type; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mongodb.MongoDatabaseFactory; @@ -774,7 +774,7 @@ static class LazyDbRefTargetWithPeristenceConstructor extends LazyDbRefTarget { public LazyDbRefTargetWithPeristenceConstructor() {} - @PersistenceConstructor + @PersistenceCreator LazyDbRefTargetWithPeristenceConstructor(String id, String value) { super(id, value); this.persistenceConstructorCalled = true; @@ -790,7 +790,7 @@ static class LazyDbRefTargetWithPeristenceConstructorWithoutDefaultConstructor e boolean persistenceConstructorCalled; - @PersistenceConstructor + @PersistenceCreator LazyDbRefTargetWithPeristenceConstructorWithoutDefaultConstructor(String id, String value) { super(id, value); this.persistenceConstructorCalled = true; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index cf6d69c6c3..a343d15c7e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -63,7 +63,7 @@ import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.converter.Converter; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.convert.ConverterBuilder; @@ -103,7 +103,6 @@ import org.springframework.data.mongodb.core.mapping.event.AfterConvertCallback; import org.springframework.data.projection.EntityProjection; import org.springframework.data.projection.EntityProjectionIntrospector; -import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; @@ -1061,7 +1060,7 @@ void convertsSetToBasicDBList() { address.city = "London"; address.street = "Foo"; - Object result = converter.convertToMongoType(Collections.singleton(address), ClassTypeInformation.OBJECT); + Object result = converter.convertToMongoType(Collections.singleton(address), TypeInformation.OBJECT); assertThat(result).isInstanceOf(List.class); Set readResult = converter.read(Set.class, (org.bson.Document) result); @@ -1393,7 +1392,7 @@ void convertsListToBasicDBListAndRetainsTypeInformationForComplexObjects() { address.street = "Foo"; Object result = converter.convertToMongoType(Collections.singletonList(address), - ClassTypeInformation.from(InterfaceType.class)); + TypeInformation.of(InterfaceType.class)); assertThat(result).isInstanceOf(List.class); @@ -1421,7 +1420,7 @@ void convertsArrayToBasicDBListAndRetainsTypeInformationForComplexObjects() { address.city = "London"; address.street = "Foo"; - Object result = converter.convertToMongoType(new Address[] { address }, ClassTypeInformation.OBJECT); + Object result = converter.convertToMongoType(new Address[] { address }, TypeInformation.OBJECT); assertThat(result).isInstanceOf(List.class); @@ -1712,7 +1711,7 @@ void shouldIncludeTextScorePropertyWhenReading() { } @Test // DATAMONGO-1001, DATAMONGO-1509 - void shouldWriteCglibProxiedClassTypeInformationCorrectly() { + void shouldWriteCglibProxiedTypeInformationCorrectly() { ProxyFactory factory = new ProxyFactory(); factory.setTargetClass(GenericType.class); @@ -2318,7 +2317,7 @@ void readAndConvertDBRefNestedByMapCorrectly() { Mockito.doReturn(cluster).when(spyConverter).readRef(dbRef); Map result = spyConverter.readMap(spyConverter.getConversionContext(ObjectPath.ROOT), data, - ClassTypeInformation.MAP); + TypeInformation.MAP); assertThat(((Map) result.get("cluster")).get("_id")).isEqualTo(100L); } @@ -3522,7 +3521,7 @@ static class Person implements Contact { } - @PersistenceConstructor + @PersistenceCreator public Person(Set
addresses) { this.addresses = addresses; } @@ -3802,7 +3801,7 @@ static class PrimitiveContainer { @Field("property") private int m_property; - @PersistenceConstructor + @PersistenceCreator public PrimitiveContainer(@Value("#root.property") int a_property) { m_property = a_property; } @@ -3817,7 +3816,7 @@ static class ObjectContainer { @Field("property") private PrimitiveContainer m_property; - @PersistenceConstructor + @PersistenceCreator public ObjectContainer(@Value("#root.property") PrimitiveContainer a_property) { m_property = a_property; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ObjectPathUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ObjectPathUnitTests.java index b772772444..9e58693faa 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ObjectPathUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ObjectPathUnitTests.java @@ -23,7 +23,7 @@ import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; -import org.springframework.data.util.ClassTypeInformation; +import org.springframework.data.util.TypeInformation; /** * Unit tests for {@link ObjectPath}. @@ -39,9 +39,9 @@ public class ObjectPathUnitTests { @BeforeEach public void setUp() { - one = new BasicMongoPersistentEntity<>(ClassTypeInformation.from(EntityOne.class)); - two = new BasicMongoPersistentEntity<>(ClassTypeInformation.from(EntityTwo.class)); - three = new BasicMongoPersistentEntity<>(ClassTypeInformation.from(EntityThree.class)); + one = new BasicMongoPersistentEntity<>(TypeInformation.of(EntityOne.class)); + two = new BasicMongoPersistentEntity<>(TypeInformation.of(EntityTwo.class)); + three = new BasicMongoPersistentEntity<>(TypeInformation.of(EntityThree.class)); } @Test // DATAMONGO-1703 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java index d8e36c8f67..c646af5539 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java @@ -544,7 +544,7 @@ void doesNotConvertRawDocuments() { } @Test // DATAMONG0-471 - void testUpdateShouldRetainClassTypeInformationWhenUsing$addToSetWith$eachForCustomTypes() { + void testUpdateShouldRetainTypeInformationWhenUsing$addToSetWith$eachForCustomTypes() { Update update = new Update().addToSet("models").each(new ModelImpl(2014), new ModelImpl(1), new ModelImpl(28)); Document mappedObject = mapper.getMappedObject(update.getUpdateObject(), diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoJsonTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoJsonTests.java index b81b51abd5..96c685275f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoJsonTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoJsonTests.java @@ -33,7 +33,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.dao.DataAccessException; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.geo.GeoResults; import org.springframework.data.geo.Metrics; import org.springframework.data.geo.Point; @@ -536,7 +536,7 @@ static class Venue2DSphere { private String name; private @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE) double[] location; - @PersistenceConstructor + @PersistenceCreator public Venue2DSphere(String name, double[] location) { this.name = name; this.location = location; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java index aa26445f2d..d1fa2b1b9a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java @@ -53,7 +53,7 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.Unwrapped; -import org.springframework.data.util.ClassTypeInformation; +import org.springframework.data.util.TypeInformation; /** * Tests for {@link MongoPersistentEntityIndexResolver}. @@ -1186,7 +1186,7 @@ public void shouldNotDetectCycleWhenTypeIsUsedMoreThanOnce() { @SuppressWarnings({ "rawtypes", "unchecked" }) public void shouldCatchCyclicReferenceExceptionOnRoot() { - MongoPersistentEntity entity = new BasicMongoPersistentEntity<>(ClassTypeInformation.from(Object.class)); + MongoPersistentEntity entity = new BasicMongoPersistentEntity<>(TypeInformation.of(Object.class)); MongoPersistentProperty propertyMock = mock(MongoPersistentProperty.class); when(propertyMock.isEntity()).thenReturn(true); @@ -1195,7 +1195,7 @@ public void shouldCatchCyclicReferenceExceptionOnRoot() { new MongoPersistentEntityIndexResolver.CyclicPropertyReferenceException("foo", Object.class, "bar")); MongoPersistentEntity selfCyclingEntity = new BasicMongoPersistentEntity<>( - ClassTypeInformation.from(SelfCyclingViaCollectionType.class)); + TypeInformation.of(SelfCyclingViaCollectionType.class)); new MongoPersistentEntityIndexResolver(prepareMappingContext(SelfCyclingViaCollectionType.class)) .resolveIndexForEntity(selfCyclingEntity); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java index 116505143e..1037ba4f19 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java @@ -39,7 +39,7 @@ import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy; import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.ClassTypeInformation; +import org.springframework.data.util.TypeInformation; import org.springframework.util.ReflectionUtils; /** @@ -56,7 +56,7 @@ public class BasicMongoPersistentPropertyUnitTests { @BeforeEach void setup() { - entity = new BasicMongoPersistentEntity<>(ClassTypeInformation.from(Person.class)); + entity = new BasicMongoPersistentEntity<>(TypeInformation.of(Person.class)); } @Test @@ -90,7 +90,7 @@ void preventsNegativeOrder() { void usesPropertyAccessForThrowableCause() { BasicMongoPersistentEntity entity = new BasicMongoPersistentEntity<>( - ClassTypeInformation.from(Throwable.class)); + TypeInformation.of(Throwable.class)); MongoPersistentProperty property = getPropertyFor(entity, "cause"); assertThat(property.usePropertyAccess()).isTrue(); @@ -99,7 +99,7 @@ void usesPropertyAccessForThrowableCause() { @Test // DATAMONGO-607 void usesCustomFieldNamingStrategyByDefault() throws Exception { - ClassTypeInformation type = ClassTypeInformation.from(Person.class); + TypeInformation type = TypeInformation.of(Person.class); Field field = ReflectionUtils.findField(Person.class, "lastname"); MongoPersistentProperty property = new BasicMongoPersistentProperty(Property.of(type, field), entity, @@ -116,7 +116,7 @@ void usesCustomFieldNamingStrategyByDefault() throws Exception { @Test // DATAMONGO-607 void rejectsInvalidValueReturnedByFieldNamingStrategy() { - ClassTypeInformation type = ClassTypeInformation.from(Person.class); + TypeInformation type = TypeInformation.of(Person.class); Field field = ReflectionUtils.findField(Person.class, "lastname"); MongoPersistentProperty property = new BasicMongoPersistentProperty(Property.of(type, field), entity, @@ -255,7 +255,7 @@ private MongoPersistentProperty getPropertyFor(Field field) { } private static MongoPersistentProperty getPropertyFor(Class type, String fieldname) { - return getPropertyFor(new BasicMongoPersistentEntity<>(ClassTypeInformation.from(type)), fieldname); + return getPropertyFor(new BasicMongoPersistentEntity<>(TypeInformation.of(type)), fieldname); } private static MongoPersistentProperty getPropertyFor(MongoPersistentEntity entity, String fieldname) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/Person.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/Person.java index 06f0db6c35..eaed01fc3b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/Person.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/Person.java @@ -18,7 +18,7 @@ import java.util.List; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.Transient; import org.springframework.data.mongodb.core.index.CompoundIndex; import org.springframework.data.mongodb.core.index.CompoundIndexes; @@ -44,7 +44,7 @@ public Person(Integer ssn) { this.ssn = ssn; } - @PersistenceConstructor + @PersistenceCreator public Person(Integer ssn, String firstName, String lastName, Integer age, T address) { this.ssn = ssn; this.firstName = firstName; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/PersonCustomIdName.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/PersonCustomIdName.java index a68fe0d531..4a4f7fb126 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/PersonCustomIdName.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/PersonCustomIdName.java @@ -16,7 +16,7 @@ package org.springframework.data.mongodb.core.mapping; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; /** * @author Jon Brisbin @@ -30,7 +30,7 @@ public PersonCustomIdName(Integer ssn, String firstName) { this.firstName = firstName; } - @PersistenceConstructor + @PersistenceCreator public PersonCustomIdName(Integer ssn, String firstName, String lastName) { this.ssn = ssn; this.firstName = firstName; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/PerformanceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/PerformanceTests.java index e815cc6e7c..fb8cedd9b1 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/PerformanceTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/PerformanceTests.java @@ -28,7 +28,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.core.Constants; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; @@ -454,7 +454,7 @@ public Address(String zipCode, String city) { this(zipCode, city, new HashSet(pickRandomNumerOfItemsFrom(Arrays.asList(AddressType.values())))); } - @PersistenceConstructor + @PersistenceCreator public Address(String zipCode, String city, Set types) { this.zipCode = zipCode; this.city = city; @@ -512,7 +512,7 @@ public Order(List lineItems, Date createdAt) { this.status = Status.ORDERED; } - @PersistenceConstructor + @PersistenceCreator public Order(List lineItems, Date createdAt, Status status) { this.lineItems = lineItems; this.createdAt = createdAt; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java index edda1aad01..3e5f416caf 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java @@ -32,7 +32,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.core.Constants; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.mongodb.core.ReactiveMongoOperations; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory; @@ -513,7 +513,7 @@ public Address(String zipCode, String city) { this(zipCode, city, new HashSet(pickRandomNumerOfItemsFrom(Arrays.asList(AddressType.values())))); } - @PersistenceConstructor + @PersistenceCreator public Address(String zipCode, String city, Set types) { this.zipCode = zipCode; this.city = city; @@ -571,7 +571,7 @@ public Order(List lineItems, Date createdAt) { this.status = Status.ORDERED; } - @PersistenceConstructor + @PersistenceCreator public Order(List lineItems, Date createdAt, Status status) { this.lineItems = lineItems; this.createdAt = createdAt; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonAggregate.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonAggregate.java index 16b2157bc8..da22801ba6 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonAggregate.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonAggregate.java @@ -22,7 +22,7 @@ import java.util.Set; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; /** * @author Christoph Strobl @@ -37,7 +37,7 @@ public PersonAggregate(String lastname, String name) { this(lastname, Collections.singletonList(name)); } - @PersistenceConstructor + @PersistenceCreator public PersonAggregate(String lastname, Collection names) { this.lastname = lastname; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ReactiveMongoRepositoryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ReactiveMongoRepositoryTests.java index e89dec21bd..1a481b49ed 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ReactiveMongoRepositoryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ReactiveMongoRepositoryTests.java @@ -72,7 +72,6 @@ import org.springframework.data.mongodb.test.util.ReactiveMongoClientClosingTestConfiguration; import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor; import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider; import org.springframework.test.context.junit.jupiter.SpringExtension; /** @@ -111,7 +110,6 @@ ReactiveMongoRepositoryFactory factory(ReactiveMongoOperations template, BeanFac factory.setRepositoryBaseClass(SimpleReactiveMongoRepository.class); factory.setBeanClassLoader(beanFactory.getClass().getClassLoader()); factory.setBeanFactory(beanFactory); - factory.setEvaluationContextProvider(ReactiveQueryMethodEvaluationContextProvider.DEFAULT); return factory; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/SimpleReactiveMongoRepositoryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/SimpleReactiveMongoRepositoryTests.java index 44235c54ef..9198e002c0 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/SimpleReactiveMongoRepositoryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/SimpleReactiveMongoRepositoryTests.java @@ -48,7 +48,6 @@ import org.springframework.data.mongodb.repository.support.SimpleReactiveMongoRepository; import org.springframework.data.mongodb.test.util.EnableIfReplicaSetAvailable; import org.springframework.data.repository.query.FluentQuery; -import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider; import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -96,7 +95,6 @@ void setUp() { factory.setRepositoryBaseClass(SimpleReactiveMongoRepository.class); factory.setBeanClassLoader(classLoader); factory.setBeanFactory(beanFactory); - factory.setEvaluationContextProvider(ReactiveQueryMethodEvaluationContextProvider.DEFAULT); repository = factory.getRepository(ReactivePersonRepository.class); immutableRepository = factory.getRepository(ReactiveImmutablePersonRepository.class); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/config/MongoRepositoryConfigurationExtensionUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/config/MongoRepositoryConfigurationExtensionUnitTests.java index f613beb6d5..a222deca39 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/config/MongoRepositoryConfigurationExtensionUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/config/MongoRepositoryConfigurationExtensionUnitTests.java @@ -27,7 +27,7 @@ import org.springframework.core.env.StandardEnvironment; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.core.type.StandardAnnotationMetadata; +import org.springframework.core.type.AnnotationMetadata; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.repository.Repository; @@ -43,13 +43,13 @@ */ public class MongoRepositoryConfigurationExtensionUnitTests { - StandardAnnotationMetadata metadata = new StandardAnnotationMetadata(Config.class, true); + AnnotationMetadata metadata = AnnotationMetadata.introspect(Config.class); ResourceLoader loader = new PathMatchingResourcePatternResolver(); Environment environment = new StandardEnvironment(); BeanDefinitionRegistry registry = new DefaultListableBeanFactory(); RepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource(metadata, - EnableMongoRepositories.class, loader, environment, registry); + EnableMongoRepositories.class, loader, environment, registry, null); @Test // DATAMONGO-1009 public void isStrictMatchIfDomainTypeIsAnnotatedWithDocument() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/config/ReactiveMongoRepositoryConfigurationExtensionUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/config/ReactiveMongoRepositoryConfigurationExtensionUnitTests.java index 45ecba992f..2b52204f74 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/config/ReactiveMongoRepositoryConfigurationExtensionUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/config/ReactiveMongoRepositoryConfigurationExtensionUnitTests.java @@ -27,7 +27,7 @@ import org.springframework.core.env.StandardEnvironment; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.core.type.StandardAnnotationMetadata; +import org.springframework.core.type.AnnotationMetadata; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; @@ -43,13 +43,13 @@ */ public class ReactiveMongoRepositoryConfigurationExtensionUnitTests { - StandardAnnotationMetadata metadata = new StandardAnnotationMetadata(Config.class, true); + AnnotationMetadata metadata = AnnotationMetadata.introspect(Config.class); ResourceLoader loader = new PathMatchingResourcePatternResolver(); Environment environment = new StandardEnvironment(); BeanDefinitionRegistry registry = new DefaultListableBeanFactory(); RepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource(metadata, - EnableReactiveMongoRepositories.class, loader, environment, registry); + EnableReactiveMongoRepositories.class, loader, environment, registry, null); @Test // DATAMONGO-1444 public void isStrictMatchIfDomainTypeIsAnnotatedWithDocument() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryExecutionUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryExecutionUnitTests.java index 74ff20b148..326ccf5f3a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryExecutionUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryExecutionUnitTests.java @@ -56,8 +56,7 @@ import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.util.ReflectionUtils; import com.mongodb.client.result.DeleteResult; @@ -81,15 +80,13 @@ class MongoQueryExecutionUnitTests { @Mock TerminatingFindNear terminatingGeoMock; @Mock DbRefResolver dbRefResolver; - private SpelExpressionParser EXPRESSION_PARSER = new SpelExpressionParser(); private Point POINT = new Point(10, 20); private Distance DISTANCE = new Distance(2.5, Metrics.KILOMETERS); private RepositoryMetadata metadata = new DefaultRepositoryMetadata(PersonRepository.class); private MongoMappingContext context = new MongoMappingContext(); private ProjectionFactory factory = new SpelAwareProxyProjectionFactory(); private Method method = ReflectionUtils.findMethod(PersonRepository.class, "findByLocationNear", Point.class, - Distance.class, - Pageable.class); + Distance.class, Pageable.class); private MongoQueryMethod queryMethod = new MongoQueryMethod(method, metadata, factory, context); private MappingMongoConverter converter; @@ -152,8 +149,8 @@ void pagingGeoExecutionShouldUseCountFromResultWithOffsetAndResultsWithinPageSiz ConvertingParameterAccessor accessor = new ConvertingParameterAccessor(converter, new MongoParametersParameterAccessor(queryMethod, new Object[] { POINT, DISTANCE, PageRequest.of(0, 10) })); - PartTreeMongoQuery query = new PartTreeMongoQuery(queryMethod, mongoOperationsMock, EXPRESSION_PARSER, - QueryMethodEvaluationContextProvider.DEFAULT); + PartTreeMongoQuery query = new PartTreeMongoQuery(queryMethod, mongoOperationsMock, + ValueExpressionDelegate.create()); PagingGeoNearExecution execution = new PagingGeoNearExecution(findOperationMock, queryMethod, accessor, query); execution.execute(new Query()); @@ -173,8 +170,8 @@ void pagingGeoExecutionRetrievesObjectsForPageableOutOfRange() { ConvertingParameterAccessor accessor = new ConvertingParameterAccessor(converter, new MongoParametersParameterAccessor(queryMethod, new Object[] { POINT, DISTANCE, PageRequest.of(2, 10) })); - PartTreeMongoQuery query = new PartTreeMongoQuery(queryMethod, mongoOperationsMock, EXPRESSION_PARSER, - QueryMethodEvaluationContextProvider.DEFAULT); + PartTreeMongoQuery query = new PartTreeMongoQuery(queryMethod, mongoOperationsMock, + ValueExpressionDelegate.create()); PagingGeoNearExecution execution = new PagingGeoNearExecution(findOperationMock, queryMethod, accessor, query); execution.execute(new Query()); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQueryUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQueryUnitTests.java index e0b9b77099..07c10592d9 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQueryUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQueryUnitTests.java @@ -45,8 +45,7 @@ import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.data.repository.query.ValueExpressionDelegate; /** * Unit tests for {@link PartTreeMongoQuery}. @@ -206,8 +205,7 @@ private PartTreeMongoQuery createQueryForMethod(String methodName, Class... p MongoQueryMethod queryMethod = new MongoQueryMethod(method, new DefaultRepositoryMetadata(Repo.class), factory, mappingContext); - return new PartTreeMongoQuery(queryMethod, mongoOperationsMock, new SpelExpressionParser(), - QueryMethodEvaluationContextProvider.DEFAULT); + return new PartTreeMongoQuery(queryMethod, mongoOperationsMock, ValueExpressionDelegate.create()); } catch (Exception e) { throw new IllegalArgumentException(e.getMessage(), e); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecutionUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecutionUnitTests.java index 21d5dc71fb..d7a3430048 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecutionUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecutionUnitTests.java @@ -46,7 +46,7 @@ import org.springframework.data.mongodb.repository.Person; import org.springframework.data.mongodb.repository.query.ReactiveMongoQueryExecution.DeleteExecution; import org.springframework.data.mongodb.repository.query.ReactiveMongoQueryExecution.GeoNearExecution; -import org.springframework.data.util.ClassTypeInformation; +import org.springframework.data.util.TypeInformation; import org.springframework.util.ClassUtils; import com.mongodb.client.result.DeleteResult; @@ -74,7 +74,7 @@ public void geoNearExecutionShouldApplyQuerySettings() throws Exception { .thenReturn(Range.from(Bound.inclusive(new Distance(10))).to(Bound.inclusive(new Distance(15)))); when(parameterAccessor.getPageable()).thenReturn(PageRequest.of(1, 10)); - new GeoNearExecution(operations, parameterAccessor, ClassTypeInformation.fromReturnTypeOf(geoNear)).execute(query, + new GeoNearExecution(operations, parameterAccessor, TypeInformation.fromReturnTypeOf(geoNear)).execute(query, Person.class, "person"); ArgumentCaptor queryArgumentCaptor = ArgumentCaptor.forClass(NearQuery.class); @@ -96,7 +96,7 @@ public void geoNearExecutionShouldApplyMinimalSettings() throws Exception { when(parameterAccessor.getGeoNearLocation()).thenReturn(new Point(1, 2)); when(parameterAccessor.getDistanceRange()).thenReturn(Range.unbounded()); - new GeoNearExecution(operations, parameterAccessor, ClassTypeInformation.fromReturnTypeOf(geoNear)).execute(query, + new GeoNearExecution(operations, parameterAccessor, TypeInformation.fromReturnTypeOf(geoNear)).execute(query, Person.class, "person"); ArgumentCaptor queryArgumentCaptor = ArgumentCaptor.forClass(NearQuery.class); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregationUnitTests.java index c6047ce30d..b4bc48cadf 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregationUnitTests.java @@ -34,6 +34,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.reactivestreams.Publisher; + import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.mongodb.core.ReactiveMongoOperations; @@ -54,9 +55,8 @@ import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; -import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.repository.reactive.ReactiveCrudRepository; -import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; @@ -71,8 +71,6 @@ @ExtendWith(MockitoExtension.class) public class ReactiveStringBasedAggregationUnitTests { - SpelExpressionParser PARSER = new SpelExpressionParser(); - @Mock ReactiveMongoOperations operations; @Mock DbRefResolver dbRefResolver; MongoConverter converter; @@ -226,8 +224,7 @@ private ReactiveStringBasedAggregation createAggregationForMethod(String name, C ProjectionFactory factory = new SpelAwareProxyProjectionFactory(); ReactiveMongoQueryMethod queryMethod = new ReactiveMongoQueryMethod(method, new DefaultRepositoryMetadata(SampleRepository.class), factory, converter.getMappingContext()); - return new ReactiveStringBasedAggregation(queryMethod, operations, PARSER, - ReactiveQueryMethodEvaluationContextProvider.DEFAULT); + return new ReactiveStringBasedAggregation(queryMethod, operations, ValueExpressionDelegate.create()); } private List pipelineOf(AggregationInvocation invocation) { @@ -250,19 +247,18 @@ private Collation collationOf(AggregationInvocation invocation) { @Nullable private Object hintOf(AggregationInvocation invocation) { - return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().getHintObject().orElse(null) + return invocation.aggregation.getOptions() != null + ? invocation.aggregation.getOptions().getHintObject().orElse(null) : null; } private Boolean skipResultsOf(AggregationInvocation invocation) { - return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().isSkipResults() - : false; + return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().isSkipResults() : false; } @Nullable private ReadPreference readPreferenceOf(AggregationInvocation invocation) { - return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().getReadPreference() - : null; + return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().getReadPreference() : null; } private Class targetTypeOf(AggregationInvocation invocation) { @@ -284,7 +280,7 @@ private interface SampleRepository extends ReactiveCrudRepository @Aggregation(GROUP_BY_LASTNAME_STRING_WITH_SPEL_PARAMETER_PLACEHOLDER) Mono spelParameterReplacementAggregation(String arg0); - @Aggregation(pipeline = {RAW_GROUP_BY_LASTNAME_STRING, GROUP_BY_LASTNAME_STRING_WITH_SPEL_PARAMETER_PLACEHOLDER}) + @Aggregation(pipeline = { RAW_GROUP_BY_LASTNAME_STRING, GROUP_BY_LASTNAME_STRING_WITH_SPEL_PARAMETER_PLACEHOLDER }) Mono multiOperationPipeline(String arg0); @Aggregation(pipeline = RAW_GROUP_BY_LASTNAME_STRING, collation = "de_AT") diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQueryUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQueryUnitTests.java index 72f9626a57..7358bf4ce6 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQueryUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQueryUnitTests.java @@ -56,8 +56,6 @@ import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor; -import org.springframework.data.repository.query.ReactiveExtensionAwareQueryMethodEvaluationContextProvider; -import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.spel.spi.EvaluationContextExtension; import org.springframework.data.spel.spi.ReactiveEvaluationContextExtension; @@ -248,8 +246,8 @@ public void shouldSupportNonQuotedBinaryDataReplacement() throws Exception { ReactiveStringBasedMongoQuery mongoQuery = createQueryForMethod("findByLastnameAsBinary", byte[].class); org.springframework.data.mongodb.core.query.Query query = mongoQuery.createQuery(accesor).block(); - org.springframework.data.mongodb.core.query.Query reference = new BasicQuery( - "{'lastname' : { '$binary' : '" + Base64.getEncoder().encodeToString(binaryData) + "', '$type' : '" + 0 + "'}}"); + org.springframework.data.mongodb.core.query.Query reference = new BasicQuery("{'lastname' : { '$binary' : '" + + Base64.getEncoder().encodeToString(binaryData) + "', '$type' : '" + 0 + "'}}"); assertThat(query.getQueryObject().toJson()).isEqualTo(reference.getQueryObject().toJson()); } @@ -266,16 +264,14 @@ void shouldConsiderReactiveSpelExtension() throws Exception { assertThat(query.getQueryObject().toJson()).isEqualTo(reference.getQueryObject().toJson()); } - private ReactiveStringBasedMongoQuery createQueryForMethod( - String name, Class... parameters) - throws Exception { + private ReactiveStringBasedMongoQuery createQueryForMethod(String name, Class... parameters) throws Exception { Method method = SampleRepository.class.getMethod(name, parameters); ProjectionFactory factory = new SpelAwareProxyProjectionFactory(); ReactiveMongoQueryMethod queryMethod = new ReactiveMongoQueryMethod(method, new DefaultRepositoryMetadata(SampleRepository.class), factory, converter.getMappingContext()); - QueryMethodValueEvaluationContextAccessor accessor = new QueryMethodValueEvaluationContextAccessor( - environment, Collections.singletonList(ReactiveSpelExtension.INSTANCE)); + QueryMethodValueEvaluationContextAccessor accessor = new QueryMethodValueEvaluationContextAccessor(environment, + Collections.singletonList(ReactiveSpelExtension.INSTANCE)); return new ReactiveStringBasedMongoQuery(queryMethod, operations, new ValueExpressionDelegate(accessor, PARSER)); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedAggregationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedAggregationUnitTests.java index 85a8650b26..463bb2a22a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedAggregationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedAggregationUnitTests.java @@ -35,6 +35,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; + import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -62,8 +63,7 @@ import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; @@ -81,8 +81,6 @@ @MockitoSettings(strictness = Strictness.LENIENT) public class StringBasedAggregationUnitTests { - private SpelExpressionParser PARSER = new SpelExpressionParser(); - @Mock MongoOperations operations; @Mock DbRefResolver dbRefResolver; @Mock AggregationResults aggregationResults; @@ -254,8 +252,7 @@ void aggregateRaisesErrorOnInvalidReturnType() { factory, converter.getMappingContext()); assertThatExceptionOfType(InvalidMongoDbApiUsageException.class) // - .isThrownBy(() -> new StringBasedAggregation(queryMethod, operations, PARSER, - QueryMethodEvaluationContextProvider.DEFAULT)) // + .isThrownBy(() -> new StringBasedAggregation(queryMethod, operations, ValueExpressionDelegate.create())) // .withMessageContaining("pageIsUnsupported") // .withMessageContaining("Page"); } @@ -311,7 +308,7 @@ private StringBasedAggregation createAggregationForMethod(String name, Class. ProjectionFactory factory = new SpelAwareProxyProjectionFactory(); MongoQueryMethod queryMethod = new MongoQueryMethod(method, new DefaultRepositoryMetadata(SampleRepository.class), factory, converter.getMappingContext()); - return new StringBasedAggregation(queryMethod, operations, PARSER, QueryMethodEvaluationContextProvider.DEFAULT); + return new StringBasedAggregation(queryMethod, operations, ValueExpressionDelegate.create()); } private List pipelineOf(AggregationInvocation invocation) { @@ -334,19 +331,18 @@ private Collation collationOf(AggregationInvocation invocation) { @Nullable private Object hintOf(AggregationInvocation invocation) { - return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().getHintObject().orElse(null) + return invocation.aggregation.getOptions() != null + ? invocation.aggregation.getOptions().getHintObject().orElse(null) : null; } private Boolean skipResultsOf(AggregationInvocation invocation) { - return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().isSkipResults() - : false; + return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().isSkipResults() : false; } @Nullable private ReadPreference readPreferenceOf(AggregationInvocation invocation) { - return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().getReadPreference() - : null; + return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().getReadPreference() : null; } private Class targetTypeOf(AggregationInvocation invocation) { diff --git a/src/main/antora/modules/ROOT/pages/mongodb/mapping/mapping.adoc b/src/main/antora/modules/ROOT/pages/mongodb/mapping/mapping.adoc index d76266c36a..3b5b4e49fe 100644 --- a/src/main/antora/modules/ROOT/pages/mongodb/mapping/mapping.adoc +++ b/src/main/antora/modules/ROOT/pages/mongodb/mapping/mapping.adoc @@ -465,7 +465,7 @@ This can be a single value (the _id_ by default), or a `Document` provided via a * `@Transient`: By default, all fields are mapped to the document. This annotation excludes the field where it is applied from being stored in the database. Transient properties cannot be used within a persistence constructor as the converter cannot materialize a value for the constructor argument. -* `@PersistenceConstructor`: Marks a given constructor - even a package protected one - to use when instantiating the object from the database. +* `@PersistenceCreator`: Marks a given constructor or a `static` factory method - even a package protected one - to use when instantiating the object from the database. Constructor arguments are mapped by name to the key values in the retrieved Document. * `@Value`: This annotation is part of the Spring Framework . Within the mapping framework it can be applied to constructor arguments. This lets you use a Spring Expression Language statement to transform a key's value retrieved in the database before it is used to construct a domain object. @@ -513,7 +513,7 @@ public class Person { this.ssn = ssn; } - @PersistenceConstructor + @PersistenceCreator public Person(Integer ssn, String firstName, String lastName, Integer age, T address) { this.ssn = ssn; this.firstName = firstName; @@ -673,7 +673,7 @@ Increased levels of nesting increase the complexity of the aggregation expressio [[mapping-custom-object-construction]] === Customized Object Construction -The mapping subsystem allows the customization of the object construction by annotating a constructor with the `@PersistenceConstructor` annotation. +The mapping subsystem allows the customization of the object construction by annotating a constructor with the `@PersistenceCreator` annotation. The values to be used for the constructor parameters are resolved in the following way: * If a parameter is annotated with the `@Value` annotation, the given expression is evaluated and the result is used as the parameter value. @@ -706,7 +706,7 @@ OrderItem item = converter.read(OrderItem.class, input); NOTE: The SpEL expression in the `@Value` annotation of the `quantity` parameter falls back to the value `0` if the given property path cannot be resolved. -Additional examples for using the `@PersistenceConstructor` annotation can be found in the https://github.com/spring-projects/spring-data-mongodb/blob/master/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java[MappingMongoConverterUnitTests] test suite. +Additional examples for using the `@PersistenceCreator` annotation can be found in the https://github.com/spring-projects/spring-data-mongodb/blob/master/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java[MappingMongoConverterUnitTests] test suite. [[mapping-usage-events]] === Mapping Framework Events diff --git a/src/main/antora/modules/ROOT/pages/mongodb/template-query-operations.adoc b/src/main/antora/modules/ROOT/pages/mongodb/template-query-operations.adoc index a424748205..697af23a9e 100644 --- a/src/main/antora/modules/ROOT/pages/mongodb/template-query-operations.adoc +++ b/src/main/antora/modules/ROOT/pages/mongodb/template-query-operations.adoc @@ -342,7 +342,7 @@ public class Venue { private String name; private double[] location; - @PersistenceConstructor + @PersistenceCreator Venue(String name, double[] location) { super(); this.name = name; From 0a114c1daffd6f18cb0fdc15730e6d0919d8891a Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 8 Jan 2025 15:05:23 +0100 Subject: [PATCH 04/17] Remove commons-logging exclusion. Closes #4870 --- spring-data-mongodb/pom.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index 77e77d83de..b60817b7e7 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -43,12 +43,6 @@ org.springframework spring-core - - - commons-logging - commons-logging - - org.springframework From 40a83fad37e18999860ee2e9e2393104a3699be2 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 24 Jan 2025 10:47:59 +0100 Subject: [PATCH 05/17] Prepare 5.0 M1 (2025.1.0). See #4836 --- pom.xml | 20 ++++---------------- src/main/resources/notice.txt | 3 +-- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index a6f11626cc..7d84b81ae0 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.data.build spring-data-parent - 4.0.0-SNAPSHOT + 4.0.0-M1 @@ -26,7 +26,7 @@ multi spring-data-mongodb - 4.0.0-SNAPSHOT + 4.0.0-M1 5.3.1 ${mongo} ${mongo} @@ -154,20 +154,8 @@ - - spring-snapshot - https://repo.spring.io/snapshot - - true - - - false - - - - spring-milestone - https://repo.spring.io/milestone - + + diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index 61b472b23b..776445bac4 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data MongoDB 4.5 M2 (2025.0.0) +Spring Data MongoDB 5.0 M1 (2025.1.0) Copyright (c) [2010-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -58,6 +58,5 @@ conditions of the subcomponent's license, as noted in the LICENSE file. - From d0aa88eea6642c6f675f6ba8385d44430ee181d9 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 24 Jan 2025 10:48:55 +0100 Subject: [PATCH 06/17] Release version 5.0 M1 (2025.1.0). See #4836 --- pom.xml | 2 +- spring-data-mongodb-distribution/pom.xml | 2 +- spring-data-mongodb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 7d84b81ae0..4bd1603965 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 5.0.0-SNAPSHOT + 5.0.0-M1 pom Spring Data MongoDB diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index fc88571622..b401fe9fbc 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -15,7 +15,7 @@ org.springframework.data spring-data-mongodb-parent - 5.0.0-SNAPSHOT + 5.0.0-M1 ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index b60817b7e7..1073f33754 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -13,7 +13,7 @@ org.springframework.data spring-data-mongodb-parent - 5.0.0-SNAPSHOT + 5.0.0-M1 ../pom.xml From d1d6bfc4c632b79f123e7ecb84e59663fec076e1 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 24 Jan 2025 10:53:09 +0100 Subject: [PATCH 07/17] Prepare next development iteration. See #4836 --- pom.xml | 2 +- spring-data-mongodb-distribution/pom.xml | 2 +- spring-data-mongodb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 4bd1603965..7d84b81ae0 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 5.0.0-M1 + 5.0.0-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index b401fe9fbc..fc88571622 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -15,7 +15,7 @@ org.springframework.data spring-data-mongodb-parent - 5.0.0-M1 + 5.0.0-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index 1073f33754..b60817b7e7 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -13,7 +13,7 @@ org.springframework.data spring-data-mongodb-parent - 5.0.0-M1 + 5.0.0-SNAPSHOT ../pom.xml From ad88d98409ad4cbed12f75742199a8ad8b1ba30a Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 24 Jan 2025 10:53:11 +0100 Subject: [PATCH 08/17] After release cleanups. See #4836 --- pom.xml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 7d84b81ae0..a6f11626cc 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.data.build spring-data-parent - 4.0.0-M1 + 4.0.0-SNAPSHOT @@ -26,7 +26,7 @@ multi spring-data-mongodb - 4.0.0-M1 + 4.0.0-SNAPSHOT 5.3.1 ${mongo} ${mongo} @@ -154,8 +154,20 @@ - - + + spring-snapshot + https://repo.spring.io/snapshot + + true + + + false + + + + spring-milestone + https://repo.spring.io/milestone + From ec2af21d8d2f0f48076de4056b7761be08c570e1 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 9 Apr 2025 08:41:01 +0200 Subject: [PATCH 09/17] Retrieve MongoDB driver version reflectively. To avoid inlining of the final/static version value, we're using reflection to look up the version value. Closes #4937 --- .../data/mongodb/util/MongoClientVersion.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java index 991a7292fd..8fc4b108ff 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java @@ -15,9 +15,12 @@ */ package org.springframework.data.mongodb.util; +import java.lang.reflect.Field; + import org.springframework.data.util.Version; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; +import org.springframework.util.ReflectionUtils; import com.mongodb.internal.build.MongoDriverVersion; @@ -96,8 +99,9 @@ private static Version getVersionFromPackage(ClassLoader classLoader) { if (ClassUtils.isPresent("com.mongodb.internal.build.MongoDriverVersion", classLoader)) { try { - return Version.parse(MongoDriverVersion.VERSION); - } catch (IllegalArgumentException exception) { + Field field = ReflectionUtils.findField(MongoDriverVersion.class, "VERSION"); + return field != null ? Version.parse("" + field.get(null)) : null; + } catch (ReflectiveOperationException | IllegalArgumentException exception) { // well not much we can do, right? } } From 478df69680adc36593aa6bf98868a1861e31e092 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 9 Apr 2025 11:08:54 +0200 Subject: [PATCH 10/17] Remove JMX support. Closes #4940 --- .../data/mongodb/config/MongoJmxParser.java | 76 -- .../mongodb/config/MongoNamespaceHandler.java | 1 - .../data/mongodb/monitor/AbstractMonitor.java | 64 -- .../data/mongodb/monitor/AssertMetrics.java | 72 -- .../monitor/BackgroundFlushingMetrics.java | 80 -- .../mongodb/monitor/BtreeIndexCounters.java | 79 -- .../mongodb/monitor/ConnectionMetrics.java | 58 -- .../mongodb/monitor/GlobalLockMetrics.java | 83 -- .../data/mongodb/monitor/MemoryMetrics.java | 73 -- .../mongodb/monitor/OperationCounters.java | 76 -- .../data/mongodb/monitor/ServerInfo.java | 81 -- .../data/mongodb/monitor/package-info.java | 6 - .../main/resources/META-INF/spring.schemas | 6 +- .../data/mongodb/config/spring-mongo-5.0.xsd | 935 ++++++++++++++++++ .../data/mongodb/core/JmxServer.java | 36 - .../monitor/MongoMonitorIntegrationTests.java | 68 -- .../data/mongodb/monitor/Resumeable.java | 27 - .../src/test/resources/server-jmx.xml | 23 - 18 files changed, 939 insertions(+), 905 deletions(-) delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoJmxParser.java delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/AbstractMonitor.java delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/AssertMetrics.java delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/BackgroundFlushingMetrics.java delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/BtreeIndexCounters.java delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/ConnectionMetrics.java delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/GlobalLockMetrics.java delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/MemoryMetrics.java delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/OperationCounters.java delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/ServerInfo.java delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/package-info.java create mode 100644 spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-5.0.xsd delete mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JmxServer.java delete mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/MongoMonitorIntegrationTests.java delete mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/Resumeable.java delete mode 100644 spring-data-mongodb/src/test/resources/server-jmx.xml diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoJmxParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoJmxParser.java deleted file mode 100644 index 07e9aace0c..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoJmxParser.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2011-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.config; - -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.parsing.BeanComponentDefinition; -import org.springframework.beans.factory.parsing.CompositeComponentDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.xml.BeanDefinitionParser; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.data.mongodb.core.MongoAdmin; -import org.springframework.data.mongodb.monitor.*; -import org.springframework.util.StringUtils; -import org.w3c.dom.Element; - -/** - * @author Mark Pollack - * @author Thomas Risberg - * @author John Brisbin - * @author Oliver Gierke - * @author Christoph Strobl - */ -public class MongoJmxParser implements BeanDefinitionParser { - - public BeanDefinition parse(Element element, ParserContext parserContext) { - String name = element.getAttribute("mongo-ref"); - if (!StringUtils.hasText(name)) { - name = BeanNames.MONGO_BEAN_NAME; - } - registerJmxComponents(name, element, parserContext); - return null; - } - - protected void registerJmxComponents(String mongoRefName, Element element, ParserContext parserContext) { - Object eleSource = parserContext.extractSource(element); - - CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource); - - createBeanDefEntry(AssertMetrics.class, compositeDef, mongoRefName, eleSource, parserContext); - createBeanDefEntry(BackgroundFlushingMetrics.class, compositeDef, mongoRefName, eleSource, parserContext); - createBeanDefEntry(BtreeIndexCounters.class, compositeDef, mongoRefName, eleSource, parserContext); - createBeanDefEntry(ConnectionMetrics.class, compositeDef, mongoRefName, eleSource, parserContext); - createBeanDefEntry(GlobalLockMetrics.class, compositeDef, mongoRefName, eleSource, parserContext); - createBeanDefEntry(MemoryMetrics.class, compositeDef, mongoRefName, eleSource, parserContext); - createBeanDefEntry(OperationCounters.class, compositeDef, mongoRefName, eleSource, parserContext); - createBeanDefEntry(ServerInfo.class, compositeDef, mongoRefName, eleSource, parserContext); - createBeanDefEntry(MongoAdmin.class, compositeDef, mongoRefName, eleSource, parserContext); - - parserContext.registerComponent(compositeDef); - - } - - protected void createBeanDefEntry(Class clazz, CompositeComponentDefinition compositeDef, String mongoRefName, - Object eleSource, ParserContext parserContext) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz); - builder.getRawBeanDefinition().setSource(eleSource); - builder.addConstructorArgReference(mongoRefName); - BeanDefinition assertDef = builder.getBeanDefinition(); - String assertName = parserContext.getReaderContext().registerWithGeneratedName(assertDef); - compositeDef.addNestedComponent(new BeanComponentDefinition(assertDef, assertName)); - } - -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java index 47519ca615..62a4a1082d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java @@ -31,7 +31,6 @@ public void init() { registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser()); registerBeanDefinitionParser("mongo-client", new MongoClientParser()); registerBeanDefinitionParser("db-factory", new MongoDbFactoryParser()); - registerBeanDefinitionParser("jmx", new MongoJmxParser()); registerBeanDefinitionParser("auditing", new MongoAuditingBeanDefinitionParser()); registerBeanDefinitionParser("template", new MongoTemplateParser()); registerBeanDefinitionParser("gridFsTemplate", new GridFsTemplateParser()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/AbstractMonitor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/AbstractMonitor.java deleted file mode 100644 index 9572f53702..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/AbstractMonitor.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2002-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.monitor; - -import java.util.List; -import java.util.stream.Collectors; - -import org.bson.Document; - -import com.mongodb.ServerAddress; -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoDatabase; -import com.mongodb.connection.ServerDescription; - -/** - * Base class to encapsulate common configuration settings when connecting to a database - * - * @author Mark Pollack - * @author Oliver Gierke - * @author Christoph Strobl - */ -public abstract class AbstractMonitor { - - private final MongoClient mongoClient; - - /** - * @param mongoClient must not be {@literal null}. - * @since 2.2 - */ - protected AbstractMonitor(MongoClient mongoClient) { - this.mongoClient = mongoClient; - } - - public Document getServerStatus() { - return getDb("admin").runCommand(new Document("serverStatus", 1).append("rangeDeleter", 1).append("repl", 1)); - } - - public MongoDatabase getDb(String databaseName) { - return mongoClient.getDatabase(databaseName); - } - - protected MongoClient getMongoClient() { - return mongoClient; - } - - protected List hosts() { - - return mongoClient.getClusterDescription().getServerDescriptions().stream().map(ServerDescription::getAddress) - .collect(Collectors.toList()); - } -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/AssertMetrics.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/AssertMetrics.java deleted file mode 100644 index ec8186e30e..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/AssertMetrics.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2002-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.monitor; - -import org.bson.Document; -import org.springframework.jmx.export.annotation.ManagedMetric; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.jmx.support.MetricType; - -import com.mongodb.client.MongoClient; - -/** - * JMX Metrics for assertions - * - * @author Mark Pollack - */ -@ManagedResource(description = "Assertion Metrics") -public class AssertMetrics extends AbstractMonitor { - - /** - * @param mongoClient must not be {@literal null}. - * @since 2.2 - */ - public AssertMetrics(MongoClient mongoClient) { - super(mongoClient); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Regular") - public int getRegular() { - return getBtree("regular"); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Warning") - public int getWarning() { - return getBtree("warning"); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Msg") - public int getMsg() { - return getBtree("msg"); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "User") - public int getUser() { - return getBtree("user"); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Rollovers") - public int getRollovers() { - return getBtree("rollovers"); - } - - private int getBtree(String key) { - Document asserts = (Document) getServerStatus().get("asserts"); - // Class c = btree.get(key).getClass(); - return (Integer) asserts.get(key); - } - -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/BackgroundFlushingMetrics.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/BackgroundFlushingMetrics.java deleted file mode 100644 index 67fa8f6562..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/BackgroundFlushingMetrics.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2002-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.monitor; - -import java.util.Date; - -import org.bson.Document; -import org.springframework.jmx.export.annotation.ManagedMetric; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.jmx.support.MetricType; - -import com.mongodb.client.MongoClient; - -/** - * JMX Metrics for Background Flushing - * - * @author Mark Pollack - */ -@ManagedResource(description = "Background Flushing Metrics") -public class BackgroundFlushingMetrics extends AbstractMonitor { - - /** - * @param mongoClient must not be {@literal null}. - * @since 2.2 - */ - public BackgroundFlushingMetrics(MongoClient mongoClient) { - super(mongoClient); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Flushes") - public int getFlushes() { - return getFlushingData("flushes", java.lang.Integer.class); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Total ms", unit = "ms") - public int getTotalMs() { - return getFlushingData("total_ms", java.lang.Integer.class); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Average ms", unit = "ms") - public double getAverageMs() { - return getFlushingData("average_ms", java.lang.Double.class); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Last Ms", unit = "ms") - public int getLastMs() { - return getFlushingData("last_ms", java.lang.Integer.class); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Last finished") - public Date getLastFinished() { - return getLast(); - } - - @SuppressWarnings("unchecked") - private T getFlushingData(String key, Class targetClass) { - Document mem = (Document) getServerStatus().get("backgroundFlushing"); - return (T) mem.get(key); - } - - private Date getLast() { - Document bgFlush = (Document) getServerStatus().get("backgroundFlushing"); - Date lastFinished = (Date) bgFlush.get("last_finished"); - return lastFinished; - } - -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/BtreeIndexCounters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/BtreeIndexCounters.java deleted file mode 100644 index 03924d88a0..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/BtreeIndexCounters.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2002-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.monitor; - -import org.bson.Document; -import org.springframework.jmx.export.annotation.ManagedMetric; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.jmx.support.MetricType; - -import com.mongodb.client.MongoClient; - -/** - * JMX Metrics for B-tree index counters - * - * @author Mark Pollack - */ -@ManagedResource(description = "Btree Metrics") -public class BtreeIndexCounters extends AbstractMonitor { - - /** - * @param mongoClient must not be {@literal null}. - * @since 2.2 - */ - public BtreeIndexCounters(MongoClient mongoClient) { - super(mongoClient); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Accesses") - public int getAccesses() { - return getBtree("accesses"); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Hits") - public int getHits() { - return getBtree("hits"); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Misses") - public int getMisses() { - return getBtree("misses"); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Resets") - public int getResets() { - return getBtree("resets"); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Miss Ratio") - public int getMissRatio() { - return getBtree("missRatio"); - } - - private int getBtree(String key) { - Document indexCounters = (Document) getServerStatus().get("indexCounters"); - if (indexCounters.get("note") != null) { - String message = (String) indexCounters.get("note"); - if (message.contains("not supported")) { - return -1; - } - } - Document btree = (Document) indexCounters.get("btree"); - // Class c = btree.get(key).getClass(); - return (Integer) btree.get(key); - } - -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/ConnectionMetrics.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/ConnectionMetrics.java deleted file mode 100644 index beb3932ea4..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/ConnectionMetrics.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2002-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.monitor; - -import org.bson.Document; -import org.springframework.jmx.export.annotation.ManagedMetric; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.jmx.support.MetricType; - -import com.mongodb.client.MongoClient; - -/** - * JMX Metrics for Connections - * - * @author Mark Pollack - */ -@ManagedResource(description = "Connection metrics") -public class ConnectionMetrics extends AbstractMonitor { - - /** - * @param mongoClient must not be {@literal null}. - * @since 2.2 - */ - public ConnectionMetrics(MongoClient mongoClient) { - super(mongoClient); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Current Connections") - public int getCurrent() { - return getConnectionData("current", java.lang.Integer.class); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Available Connections") - public int getAvailable() { - return getConnectionData("available", java.lang.Integer.class); - } - - @SuppressWarnings("unchecked") - private T getConnectionData(String key, Class targetClass) { - Document mem = (Document) getServerStatus().get("connections"); - // Class c = mem.get(key).getClass(); - return (T) mem.get(key); - } - -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/GlobalLockMetrics.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/GlobalLockMetrics.java deleted file mode 100644 index 096c67b1a0..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/GlobalLockMetrics.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2002-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.monitor; - -import org.bson.Document; -import org.springframework.jmx.export.annotation.ManagedMetric; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.jmx.support.MetricType; - -import com.mongodb.DBObject; -import com.mongodb.client.MongoClient; - -/** - * JMX Metrics for Global Locks - * - * @author Mark Pollack - */ -@ManagedResource(description = "Global Lock Metrics") -public class GlobalLockMetrics extends AbstractMonitor { - - /** - * @param mongoClient must not be {@literal null}. - * @since 2.2 - */ - public GlobalLockMetrics(MongoClient mongoClient) { - super(mongoClient); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Total time") - public double getTotalTime() { - return getGlobalLockData("totalTime", java.lang.Double.class); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Lock time", unit = "s") - public double getLockTime() { - return getGlobalLockData("lockTime", java.lang.Double.class); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Lock time") - public double getLockTimeRatio() { - return getGlobalLockData("ratio", java.lang.Double.class); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Current Queue") - public int getCurrentQueueTotal() { - return getCurrentQueue("total"); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Reader Queue") - public int getCurrentQueueReaders() { - return getCurrentQueue("readers"); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Writer Queue") - public int getCurrentQueueWriters() { - return getCurrentQueue("writers"); - } - - @SuppressWarnings("unchecked") - private T getGlobalLockData(String key, Class targetClass) { - DBObject globalLock = (DBObject) getServerStatus().get("globalLock"); - return (T) globalLock.get(key); - } - - private int getCurrentQueue(String key) { - Document globalLock = (Document) getServerStatus().get("globalLock"); - Document currentQueue = (Document) globalLock.get("currentQueue"); - return (Integer) currentQueue.get(key); - } -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/MemoryMetrics.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/MemoryMetrics.java deleted file mode 100644 index 75daa3de55..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/MemoryMetrics.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2002-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.monitor; - -import org.bson.Document; -import org.springframework.jmx.export.annotation.ManagedMetric; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.jmx.support.MetricType; - -import com.mongodb.client.MongoClient; - -/** - * JMX Metrics for Memory - * - * @author Mark Pollack - */ -@ManagedResource(description = "Memory Metrics") -public class MemoryMetrics extends AbstractMonitor { - - /** - * @param mongoClient - * @since 2.2 - */ - public MemoryMetrics(MongoClient mongoClient) { - super(mongoClient); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Memory address size") - public int getBits() { - return getMemData("bits", java.lang.Integer.class); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Resident in Physical Memory", unit = "MB") - public int getResidentSpace() { - return getMemData("resident", java.lang.Integer.class); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Virtual Address Space", unit = "MB") - public int getVirtualAddressSpace() { - return getMemData("virtual", java.lang.Integer.class); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Is memory info supported on this platform") - public boolean getMemoryInfoSupported() { - return getMemData("supported", java.lang.Boolean.class); - } - - @ManagedMetric(metricType = MetricType.GAUGE, displayName = "Memory Mapped Space", unit = "MB") - public int getMemoryMappedSpace() { - return getMemData("mapped", java.lang.Integer.class); - } - - @SuppressWarnings("unchecked") - private T getMemData(String key, Class targetClass) { - Document mem = (Document) getServerStatus().get("mem"); - // Class c = mem.get(key).getClass(); - return (T) mem.get(key); - } - -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/OperationCounters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/OperationCounters.java deleted file mode 100644 index 35281753e6..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/OperationCounters.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2002-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.monitor; - -import org.bson.Document; -import org.springframework.jmx.export.annotation.ManagedMetric; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.jmx.support.MetricType; -import org.springframework.util.NumberUtils; - -import com.mongodb.client.MongoClient; - -/** - * JMX Metrics for Operation counters - * - * @author Mark Pollack - */ -@ManagedResource(description = "Operation Counters") -public class OperationCounters extends AbstractMonitor { - - /** - * @param mongoClient - * @since 2.2 - */ - public OperationCounters(MongoClient mongoClient) { - super(mongoClient); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Insert operation count") - public int getInsertCount() { - return getOpCounter("insert"); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Query operation count") - public int getQueryCount() { - return getOpCounter("query"); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Update operation count") - public int getUpdateCount() { - return getOpCounter("update"); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Delete operation count") - public int getDeleteCount() { - return getOpCounter("delete"); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "GetMore operation count") - public int getGetMoreCount() { - return getOpCounter("getmore"); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Command operation count") - public int getCommandCount() { - return getOpCounter("command"); - } - - private int getOpCounter(String key) { - Document opCounters = (Document) getServerStatus().get("opcounters"); - return NumberUtils.convertNumberToTargetClass((Number) opCounters.get(key), Integer.class); - } -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/ServerInfo.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/ServerInfo.java deleted file mode 100644 index bddf62d028..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/ServerInfo.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2012-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.monitor; - -import java.net.UnknownHostException; - -import org.springframework.jmx.export.annotation.ManagedMetric; -import org.springframework.jmx.export.annotation.ManagedOperation; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.jmx.support.MetricType; -import org.springframework.util.StringUtils; - -import com.mongodb.client.MongoClient; - -/** - * Expose basic server information via JMX - * - * @author Mark Pollack - * @author Thomas Darimont - * @author Christoph Strobl - */ -@ManagedResource(description = "Server Information") -public class ServerInfo extends AbstractMonitor { - - /** - * @param mongoClient - * @since 2.2 - */ - protected ServerInfo(MongoClient mongoClient) { - super(mongoClient); - } - - /** - * Returns the hostname of the used server reported by MongoDB. - * - * @return the reported hostname can also be an IP address. - * @throws UnknownHostException - */ - @ManagedOperation(description = "Server host name") - public String getHostName() throws UnknownHostException { - - /* - * UnknownHostException is not necessary anymore, but clients could have - * called this method in a try..catch(UnknownHostException) already - */ - return StringUtils.collectionToDelimitedString(hosts(), ","); - } - - @ManagedMetric(displayName = "Uptime Estimate") - public double getUptimeEstimate() { - return (Double) getServerStatus().get("uptimeEstimate"); - } - - @ManagedOperation(description = "MongoDB Server Version") - public String getVersion() { - return (String) getServerStatus().get("version"); - } - - @ManagedOperation(description = "Local Time") - public String getLocalTime() { - return (String) getServerStatus().get("localTime"); - } - - @ManagedMetric(metricType = MetricType.COUNTER, displayName = "Server uptime in seconds", unit = "seconds") - public double getUptime() { - return (Double) getServerStatus().get("uptime"); - } -} 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 deleted file mode 100644 index 0d495584a9..0000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * MongoDB specific JMX monitoring support. - */ -@org.springframework.lang.NonNullApi -package org.springframework.data.mongodb.monitor; - diff --git a/spring-data-mongodb/src/main/resources/META-INF/spring.schemas b/spring-data-mongodb/src/main/resources/META-INF/spring.schemas index 57920f7449..c6c28dbab1 100644 --- a/spring-data-mongodb/src/main/resources/META-INF/spring.schemas +++ b/spring-data-mongodb/src/main/resources/META-INF/spring.schemas @@ -13,7 +13,8 @@ http\://www.springframework.org/schema/data/mongo/spring-mongo-2.2.xsd=org/sprin http\://www.springframework.org/schema/data/mongo/spring-mongo-3.0.xsd=org/springframework/data/mongodb/config/spring-mongo-3.0.xsd http\://www.springframework.org/schema/data/mongo/spring-mongo-3.3.xsd=org/springframework/data/mongodb/config/spring-mongo-3.3.xsd http\://www.springframework.org/schema/data/mongo/spring-mongo-4.0.xsd=org/springframework/data/mongodb/config/spring-mongo-4.0.xsd -http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-4.0.xsd +http\://www.springframework.org/schema/data/mongo/spring-mongo-5.0.xsd=org/springframework/data/mongodb/config/spring-mongo-5.0.xsd +http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-5.0.xsd https\://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd=org/springframework/data/mongodb/config/spring-mongo-1.0.xsd https\://www.springframework.org/schema/data/mongo/spring-mongo-1.1.xsd=org/springframework/data/mongodb/config/spring-mongo-1.1.xsd https\://www.springframework.org/schema/data/mongo/spring-mongo-1.2.xsd=org/springframework/data/mongodb/config/spring-mongo-1.2.xsd @@ -29,4 +30,5 @@ https\://www.springframework.org/schema/data/mongo/spring-mongo-2.2.xsd=org/spri https\://www.springframework.org/schema/data/mongo/spring-mongo-3.0.xsd=org/springframework/data/mongodb/config/spring-mongo-3.0.xsd https\://www.springframework.org/schema/data/mongo/spring-mongo-3.3.xsd=org/springframework/data/mongodb/config/spring-mongo-3.3.xsd https\://www.springframework.org/schema/data/mongo/spring-mongo-4.0.xsd=org/springframework/data/mongodb/config/spring-mongo-4.0.xsd -https\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-4.0.xsd +https\://www.springframework.org/schema/data/mongo/spring-mongo-5.0.xsd=org/springframework/data/mongodb/config/spring-mongo-5.0.xsd +https\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-5.0.xsd diff --git a/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-5.0.xsd b/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-5.0.xsd new file mode 100644 index 0000000000..5fae630b6b --- /dev/null +++ b/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-5.0.xsd @@ -0,0 +1,935 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The WriteConcern that will be the default value used when asking + the MongoDatabaseFactory for a DB object + + + + + + + + + + + + + + The reference to a MongoTemplate. Will default to 'mongoTemplate'. + + + + + + + Enables creation of indexes for queries that get derived from the + method name + and thus reference domain class properties. Defaults to false. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The reference to a MongoDatabaseFactory. + + + + + + + + + + + + The reference to a MongoTypeMapper to be used by this + MappingMongoConverter. + + + + + + + The reference to a MappingContext. Will default to + 'mappingContext'. + + + + + + + Disables JSR-303 validation on MongoDB documents before they are + saved. By default it is set to false. + + + + + + + + + + Enables abbreviating the field names for domain class properties + to the + first character of their camel case names, e.g. fooBar -> fb. + Defaults to false. + + + + + + + + + + The reference to a FieldNamingStrategy. + + + + + + + Enable/Disable index creation for annotated properties/entities. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A reference to a custom converter. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The reference to a MongoDatabaseFactory. + + + + + + + + + + + + The WriteConcern that will be the default value used when asking + the MongoDatabaseFactory for a DB object + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The reference to a MongoDatabaseFactory. + + + + + + + + + + + + + + + + diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JmxServer.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JmxServer.java deleted file mode 100644 index cb8a8dcf45..0000000000 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JmxServer.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2002-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.core; - -import org.springframework.context.support.ClassPathXmlApplicationContext; - -/** - * Server application than can be run as an app or unit test. - * - * @author Mark Pollack - * @author Oliver Gierke - */ -public class JmxServer { - - public static void main(String[] args) { - new JmxServer().run(); - } - - @SuppressWarnings("resource") - public void run() { - new ClassPathXmlApplicationContext(new String[] { "infrastructure.xml", "server-jmx.xml" }); - } -} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/MongoMonitorIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/MongoMonitorIntegrationTests.java deleted file mode 100644 index e70b398f7f..0000000000 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/MongoMonitorIntegrationTests.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2002-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.monitor; - -import static org.assertj.core.api.Assertions.*; - -import java.net.UnknownHostException; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; - -import com.mongodb.client.MongoClient; - -/** - * This test class assumes that you are already running the MongoDB server. - * - * @author Mark Pollack - * @author Thomas Darimont - * @author Mark Paluch - */ -@ExtendWith(MongoClientExtension.class) -public class MongoMonitorIntegrationTests { - - static @Client MongoClient mongoClient; - - @Test - public void serverInfo() { - ServerInfo serverInfo = new ServerInfo(mongoClient); - serverInfo.getVersion(); - } - - @Test // DATAMONGO-685 - public void getHostNameShouldReturnServerNameReportedByMongo() throws UnknownHostException { - - ServerInfo serverInfo = new ServerInfo(mongoClient); - - String hostName = null; - try { - hostName = serverInfo.getHostName(); - } catch (UnknownHostException e) { - throw e; - } - - assertThat(hostName).isNotNull(); - assertThat(hostName).isEqualTo("127.0.0.1:27017"); - } - - @Test - public void operationCounters() { - OperationCounters operationCounters = new OperationCounters(mongoClient); - operationCounters.getInsertCount(); - } -} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/Resumeable.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/Resumeable.java deleted file mode 100644 index 1fdbb1f188..0000000000 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/Resumeable.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2018-2025 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.monitor; - -import java.util.function.Supplier; - -/** - * @author Christoph Strobl - * @since 2018/01 - */ -interface Resumeable { - - void resumeAt(Supplier token); -} diff --git a/spring-data-mongodb/src/test/resources/server-jmx.xml b/spring-data-mongodb/src/test/resources/server-jmx.xml deleted file mode 100644 index 54f985f4cb..0000000000 --- a/spring-data-mongodb/src/test/resources/server-jmx.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file From 957127ca70347753220d0ce68f0773a667ca1ae7 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 12 Mar 2025 09:59:13 +0100 Subject: [PATCH 11/17] Prepare issue branch. --- pom.xml | 2 +- spring-data-mongodb-distribution/pom.xml | 2 +- spring-data-mongodb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a6f11626cc..5f78acf4a6 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 5.0.0-SNAPSHOT + 5.0.x-GH-4874-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index fc88571622..5d61bbb01c 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -15,7 +15,7 @@ org.springframework.data spring-data-mongodb-parent - 5.0.0-SNAPSHOT + 5.0.x-GH-4874-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index b60817b7e7..dbb34aeb56 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -13,7 +13,7 @@ org.springframework.data spring-data-mongodb-parent - 5.0.0-SNAPSHOT + 5.0.x-GH-4874-SNAPSHOT ../pom.xml From fc68f61a0eea0bd74a9b53f3fdc7592c06f41903 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 12 Mar 2025 11:06:41 +0100 Subject: [PATCH 12/17] Migrate to jspecify annotation - next fix the errors --- spring-data-mongodb/pom.xml | 70 ++++++++- .../data/mongodb/BindableMongoExpression.java | 8 +- .../data/mongodb/ClientSessionException.java | 2 +- ...efaultMongoTransactionOptionsResolver.java | 5 +- .../data/mongodb/MongoDatabaseUtils.java | 5 +- .../data/mongodb/MongoResourceHolder.java | 2 +- .../mongodb/MongoTransactionException.java | 2 +- .../data/mongodb/MongoTransactionManager.java | 8 +- .../data/mongodb/MongoTransactionOptions.java | 38 ++--- .../MongoTransactionOptionsResolver.java | 2 +- .../mongodb/ReactiveMongoDatabaseUtils.java | 3 +- .../mongodb/ReactiveMongoResourceHolder.java | 5 +- .../ReactiveMongoTransactionManager.java | 8 +- .../SessionAwareMethodInterceptor.java | 5 +- .../SimpleMongoTransactionOptions.java | 29 ++-- .../data/mongodb/TransactionMetadata.java | 2 +- .../mongodb/TransactionOptionResolver.java | 2 +- .../UncategorizedMongoDbException.java | 2 +- .../data/mongodb/aot/MongoAotPredicates.java | 2 +- ...agedTypesBeanRegistrationAotProcessor.java | 2 +- .../data/mongodb/aot/MongoRuntimeHints.java | 2 +- .../ConnectionStringPropertyEditor.java | 2 +- .../config/MappingMongoConverterParser.java | 11 +- .../MongoAuditingBeanDefinitionParser.java | 2 +- .../config/MongoCredentialPropertyEditor.java | 2 +- .../mongodb/config/MongoDbFactoryParser.java | 5 +- .../config/ReadConcernPropertyEditor.java | 2 +- .../config/ReadPreferencePropertyEditor.java | 4 +- .../config/ServerAddressPropertyEditor.java | 5 +- .../UUidRepresentationPropertyEditor.java | 2 +- .../config/WriteConcernPropertyEditor.java | 2 +- .../data/mongodb/config/package-info.java | 2 +- .../data/mongodb/core/AggregationUtil.java | 3 +- .../data/mongodb/core/ChangeStreamEvent.java | 20 +-- .../mongodb/core/ChangeStreamOptions.java | 2 +- .../data/mongodb/core/CollectionCallback.java | 2 +- .../data/mongodb/core/CollectionOptions.java | 5 +- .../data/mongodb/core/CountQuery.java | 2 +- .../data/mongodb/core/CursorPreparer.java | 5 +- .../data/mongodb/core/DbCallback.java | 2 +- .../mongodb/core/DefaultBulkOperations.java | 2 +- .../mongodb/core/DefaultIndexOperations.java | 8 +- .../core/DefaultReactiveBulkOperations.java | 2 +- .../core/DefaultReactiveIndexOperations.java | 5 +- .../core/EntityLifecycleEventDelegate.java | 2 +- .../data/mongodb/core/EntityOperations.java | 17 +-- .../mongodb/core/ExecutableFindOperation.java | 2 +- .../core/ExecutableFindOperationSupport.java | 14 +- .../ExecutableInsertOperationSupport.java | 2 +- .../ExecutableMapReduceOperationSupport.java | 2 +- .../ExecutableRemoveOperationSupport.java | 2 +- .../core/ExecutableUpdateOperation.java | 2 +- .../ExecutableUpdateOperationSupport.java | 2 +- .../mongodb/core/FindAndModifyOptions.java | 2 +- .../mongodb/core/FindPublisherPreparer.java | 5 +- .../data/mongodb/core/HintFunction.java | 2 +- .../data/mongodb/core/IndexConverters.java | 6 +- .../data/mongodb/core/MongoAction.java | 17 +-- .../mongodb/core/MongoClientFactoryBean.java | 7 +- .../core/MongoClientSettingsFactoryBean.java | 3 +- .../core/MongoDatabaseFactorySupport.java | 2 +- .../MongoEncryptionSettingsFactoryBean.java | 2 +- .../core/MongoExceptionTranslator.java | 6 +- .../data/mongodb/core/MongoOperations.java | 20 +-- .../core/MongoServerApiFactoryBean.java | 5 +- .../data/mongodb/core/MongoTemplate.java | 140 ++++++------------ .../data/mongodb/core/QueryOperations.java | 2 +- .../ReactiveChangeStreamOperationSupport.java | 2 +- .../core/ReactiveFindOperationSupport.java | 2 +- .../ReactiveMapReduceOperationSupport.java | 2 +- .../core/ReactiveMongoClientFactoryBean.java | 2 +- .../mongodb/core/ReactiveMongoOperations.java | 2 +- .../mongodb/core/ReactiveMongoTemplate.java | 16 +- .../core/ReactiveUpdateOperationSupport.java | 2 +- .../data/mongodb/core/ReadConcernAware.java | 2 +- .../mongodb/core/ReadPreferenceAware.java | 2 +- .../data/mongodb/core/ScriptOperations.java | 2 +- .../data/mongodb/core/SessionCallback.java | 2 +- .../data/mongodb/core/SessionScoped.java | 10 +- .../SimpleReactiveMongoDatabaseFactory.java | 2 +- .../data/mongodb/core/ViewOptions.java | 2 +- .../data/mongodb/core/WriteConcernAware.java | 2 +- .../mongodb/core/WriteConcernResolver.java | 2 +- .../core/aggregation/AddFieldsOperation.java | 2 +- .../AggregationExpressionTransformer.java | 2 +- .../AggregationOperationContext.java | 2 +- .../AggregationOperationRenderer.java | 2 +- .../core/aggregation/AggregationOptions.java | 2 +- .../core/aggregation/AggregationResults.java | 8 +- .../core/aggregation/AggregationUpdate.java | 3 +- .../core/aggregation/AggregationVariable.java | 2 +- .../core/aggregation/ArithmeticOperators.java | 2 +- .../core/aggregation/ArrayOperators.java | 2 +- .../aggregation/ConditionalOperators.java | 2 +- .../core/aggregation/ConvertOperators.java | 2 +- .../core/aggregation/DateOperators.java | 2 +- .../core/aggregation/DensifyOperation.java | 2 +- .../core/aggregation/ExposedFields.java | 5 +- ...osedFieldsAggregationOperationContext.java | 6 +- .../data/mongodb/core/aggregation/Fields.java | 5 +- .../core/aggregation/GeoNearOperation.java | 2 +- .../aggregation/GraphLookupOperation.java | 2 +- .../core/aggregation/GroupOperation.java | 2 +- ...osedFieldsAggregationOperationContext.java | 2 +- .../core/aggregation/MergeOperation.java | 2 +- .../core/aggregation/OutOperation.java | 2 +- ...DelegatingAggregationOperationContext.java | 2 +- .../core/aggregation/ProjectionOperation.java | 2 +- .../core/aggregation/ScriptOperators.java | 2 +- .../core/aggregation/SetOperation.java | 2 +- .../aggregation/SetWindowFieldsOperation.java | 5 +- .../aggregation/SortByCountOperation.java | 2 +- .../SpelExpressionTransformer.java | 5 +- .../core/aggregation/SystemVariable.java | 5 +- .../TypeBasedAggregationOperationContext.java | 3 +- .../core/aggregation/UnionWithOperation.java | 2 +- .../core/aggregation/UnwindOperation.java | 2 +- .../core/aggregation/VariableOperators.java | 5 +- .../core/aggregation/package-info.java | 2 +- .../mongodb/core/annotation/package-info.java | 2 +- .../core/convert/AbstractMongoConverter.java | 2 +- .../core/convert/DbRefProxyHandler.java | 2 +- .../mongodb/core/convert/DbRefResolver.java | 4 +- .../convert/DefaultDbRefProxyHandler.java | 3 +- .../core/convert/DefaultDbRefResolver.java | 2 +- .../core/convert/DefaultMongoTypeMapper.java | 2 +- .../core/convert/DocumentAccessor.java | 8 +- .../convert/DocumentPropertyAccessor.java | 2 +- .../core/convert/DocumentReferenceSource.java | 8 +- .../core/convert/LazyLoadingProxy.java | 5 +- .../core/convert/LazyLoadingProxyFactory.java | 17 +-- .../core/convert/MappingMongoConverter.java | 30 ++-- .../core/convert/MongoConversionContext.java | 9 +- .../mongodb/core/convert/MongoConverter.java | 5 +- .../core/convert/MongoCustomConversions.java | 2 +- .../core/convert/MongoJsonSchemaMapper.java | 2 +- .../mongodb/core/convert/MongoWriter.java | 5 +- .../core/convert/NoOpDbRefResolver.java | 9 +- .../data/mongodb/core/convert/ObjectPath.java | 11 +- .../mongodb/core/convert/QueryMapper.java | 48 ++---- .../mongodb/core/convert/ReferenceLoader.java | 5 +- .../core/convert/ReferenceLookupDelegate.java | 5 +- .../core/convert/ReferenceResolver.java | 8 +- .../mongodb/core/convert/UpdateMapper.java | 2 +- .../mongodb/core/convert/ValueResolver.java | 3 +- .../encryption/ExplicitEncryptionContext.java | 5 +- .../encryption/MongoEncryptionConverter.java | 5 +- .../core/convert/encryption/package-info.java | 2 +- .../mongodb/core/convert/package-info.java | 2 +- .../core/encryption/EncryptionContext.java | 11 +- .../mongodb/core/encryption/package-info.java | 2 +- .../core/geo/GeoJsonGeometryCollection.java | 2 +- .../data/mongodb/core/geo/GeoJsonModule.java | 18 +-- .../core/geo/GeoJsonMultiLineString.java | 2 +- .../mongodb/core/geo/GeoJsonMultiPoint.java | 2 +- .../mongodb/core/geo/GeoJsonMultiPolygon.java | 2 +- .../data/mongodb/core/geo/GeoJsonPolygon.java | 2 +- .../data/mongodb/core/geo/Sphere.java | 2 +- .../data/mongodb/core/geo/package-info.java | 2 +- .../mongodb/core/index/GeospatialIndex.java | 2 +- .../data/mongodb/core/index/Index.java | 2 +- .../data/mongodb/core/index/IndexField.java | 5 +- .../data/mongodb/core/index/IndexInfo.java | 5 +- .../core/index/IndexOperationsProvider.java | 2 +- .../data/mongodb/core/index/IndexOptions.java | 17 +-- .../mongodb/core/index/IndexPredicate.java | 5 +- .../MongoPersistentEntityIndexCreator.java | 6 +- .../MongoPersistentEntityIndexResolver.java | 14 +- .../core/index/TextIndexDefinition.java | 2 +- .../mongodb/core/index/WildcardIndex.java | 2 +- .../data/mongodb/core/index/package-info.java | 2 +- .../mapping/BasicMongoPersistentEntity.java | 8 +- .../mapping/BasicMongoPersistentProperty.java | 9 +- .../CachingMongoPersistentProperty.java | 2 +- .../core/mapping/MongoMappingContext.java | 8 +- .../core/mapping/MongoPersistentEntity.java | 5 +- .../core/mapping/MongoPersistentProperty.java | 4 +- .../mapping/PersistentPropertyTranslator.java | 2 +- .../data/mongodb/core/mapping/ShardKey.java | 2 +- .../core/mapping/UnwrapEntityContext.java | 2 +- .../UnwrappedMongoPersistentEntity.java | 23 +-- .../UnwrappedMongoPersistentProperty.java | 41 ++--- .../mapping/event/AbstractDeleteEvent.java | 5 +- .../core/mapping/event/AfterDeleteEvent.java | 2 +- .../core/mapping/event/BeforeDeleteEvent.java | 2 +- .../core/mapping/event/MongoMappingEvent.java | 2 +- .../core/mapping/event/package-info.java | 2 +- .../mongodb/core/mapping/package-info.java | 2 +- .../core/mapreduce/MapReduceCounts.java | 2 +- .../core/mapreduce/MapReduceOptions.java | 11 +- .../core/mapreduce/MapReduceResults.java | 8 +- .../core/mapreduce/MapReduceTiming.java | 2 +- .../mongodb/core/mapreduce/package-info.java | 2 +- .../core/messaging/ChangeStreamRequest.java | 2 +- .../core/messaging/ChangeStreamTask.java | 11 +- .../core/messaging/CursorReadingTask.java | 8 +- .../DefaultMessageListenerContainer.java | 2 +- .../data/mongodb/core/messaging/Message.java | 11 +- .../mongodb/core/messaging/SimpleMessage.java | 2 +- .../core/messaging/SubscriptionRequest.java | 5 +- .../core/messaging/TailableCursorRequest.java | 2 +- .../mongodb/core/messaging/package-info.java | 2 +- .../data/mongodb/core/package-info.java | 2 +- .../data/mongodb/core/query/BasicQuery.java | 2 +- .../data/mongodb/core/query/BasicUpdate.java | 80 ++-------- .../data/mongodb/core/query/Collation.java | 2 +- .../data/mongodb/core/query/Criteria.java | 5 +- .../core/query/CriteriaDefinition.java | 2 +- .../data/mongodb/core/query/Field.java | 2 +- .../data/mongodb/core/query/GeoCommand.java | 2 +- .../data/mongodb/core/query/Meta.java | 11 +- .../mongodb/core/query/MongoRegexCreator.java | 5 +- .../data/mongodb/core/query/NearQuery.java | 17 +-- .../data/mongodb/core/query/Query.java | 5 +- .../core/query/SerializationUtils.java | 6 +- .../data/mongodb/core/query/Term.java | 2 +- .../data/mongodb/core/query/TextCriteria.java | 2 +- .../data/mongodb/core/query/TextQuery.java | 2 +- .../core/query/UntypedExampleMatcher.java | 2 +- .../data/mongodb/core/query/Update.java | 2 +- .../data/mongodb/core/query/package-info.java | 2 +- .../core/schema/DefaultMongoJsonSchema.java | 5 +- .../IdentifiableJsonSchemaProperty.java | 6 +- .../mongodb/core/schema/JsonSchemaObject.java | 2 +- .../core/schema/JsonSchemaProperty.java | 2 +- .../mongodb/core/schema/MongoJsonSchema.java | 5 +- .../schema/TypeUnifyingMergeFunction.java | 5 +- .../core/schema/TypedJsonSchemaObject.java | 5 +- .../core/schema/UntypedJsonSchemaObject.java | 5 +- .../mongodb/core/schema/package-info.java | 2 +- .../mongodb/core/script/package-info.java | 2 +- .../mongodb/core/spel/ExpressionNode.java | 5 +- ...xpressionTransformationContextSupport.java | 8 +- .../data/mongodb/core/spel/LiteralNode.java | 2 +- .../core/spel/MethodReferenceNode.java | 15 +- .../data/mongodb/core/spel/package-info.java | 2 +- .../core/validation/CriteriaValidator.java | 2 +- .../core/validation/DocumentValidator.java | 2 +- .../core/validation/JsonSchemaValidator.java | 2 +- .../mongodb/core/validation/package-info.java | 2 +- .../data/mongodb/gridfs/GridFsCriteria.java | 2 +- .../data/mongodb/gridfs/GridFsObject.java | 2 +- .../data/mongodb/gridfs/GridFsOperations.java | 5 +- .../gridfs/GridFsOperationsSupport.java | 2 +- .../data/mongodb/gridfs/GridFsResource.java | 5 +- .../data/mongodb/gridfs/GridFsTemplate.java | 2 +- .../data/mongodb/gridfs/GridFsUpload.java | 6 +- .../gridfs/ReactiveGridFsOperations.java | 2 +- .../gridfs/ReactiveGridFsResource.java | 2 +- .../gridfs/ReactiveGridFsTemplate.java | 2 +- .../mongodb/gridfs/ReactiveGridFsUpload.java | 5 +- .../data/mongodb/gridfs/package-info.java | 2 +- .../data/mongodb/monitor/package-info.java | 6 + .../observability/MongoHandlerContext.java | 9 +- .../MongoObservationCommandListener.java | 5 +- .../mongodb/observability/package-info.java | 2 +- .../data/mongodb/package-info.java | 2 +- .../aot/RepositoryRuntimeHints.java | 2 +- .../mongodb/repository/aot/package-info.java | 2 +- .../mongodb/repository/cdi/package-info.java | 2 +- .../repository/config/package-info.java | 2 +- .../data/mongodb/repository/package-info.java | 2 +- .../repository/query/AbstractMongoQuery.java | 6 +- .../query/AbstractReactiveMongoQuery.java | 2 +- .../repository/query/AggregationUtils.java | 12 +- .../repository/query/CollationUtils.java | 6 +- .../query/ConvertingParameterAccessor.java | 5 +- .../query/MongoEntityInformation.java | 5 +- .../query/MongoParameterAccessor.java | 2 +- .../repository/query/MongoParameters.java | 2 +- .../MongoParametersParameterAccessor.java | 5 +- .../repository/query/MongoQueryCreator.java | 5 +- .../repository/query/MongoQueryExecution.java | 2 +- .../repository/query/MongoQueryMethod.java | 2 +- .../mongodb/repository/query/QueryUtils.java | 3 +- .../query/ReactiveMongoQueryExecution.java | 2 +- .../query/ReactiveStringBasedAggregation.java | 2 +- .../query/ReactiveStringBasedMongoQuery.java | 3 +- .../query/StringAggregationOperation.java | 2 +- .../query/StringBasedAggregation.java | 6 +- .../repository/query/package-info.java | 2 +- .../CrudMethodMetadataPostProcessor.java | 2 +- .../MappingMongoEntityInformation.java | 5 +- .../support/MongoAnnotationProcessor.java | 3 +- .../MongoEntityInformationSupport.java | 2 +- .../support/MongoRepositoryFactory.java | 2 +- .../support/MongoRepositoryFactoryBean.java | 2 +- .../ReactiveMongoRepositoryFactory.java | 2 +- .../ReactiveMongoRepositoryFactoryBean.java | 2 +- .../ReactiveSpringDataMongodbQuery.java | 2 +- .../support/SimpleMongoRepository.java | 2 +- .../SimpleReactiveMongoRepository.java | 2 +- .../support/SpringDataMongodbQuery.java | 19 +-- .../support/SpringDataMongodbSerializer.java | 8 +- .../repository/support/package-info.java | 2 +- .../data/mongodb/util/BsonUtils.java | 17 +-- .../data/mongodb/util/DotPath.java | 2 +- .../data/mongodb/util/DurationUtil.java | 8 +- .../data/mongodb/util/EmptyDocument.java | 3 +- .../data/mongodb/util/MongoClientVersion.java | 13 +- .../util/MongoCompatibilityAdapter.java | 17 +-- .../data/mongodb/util/MongoDbErrorCodes.java | 7 +- .../data/mongodb/util/RegexFlags.java | 2 +- .../aggregation/TestAggregationContext.java | 2 +- .../util/encryption/EncryptionUtils.java | 5 +- .../EvaluationContextExpressionEvaluator.java | 5 +- .../util/json/ParameterBindingContext.java | 11 +- .../json/ParameterBindingDocumentCodec.java | 6 +- .../util/json/ParameterBindingJsonReader.java | 8 +- .../data/mongodb/util/json/ValueProvider.java | 2 +- .../data/mongodb/util/json/package-info.java | 2 +- .../data/mongodb/util/package-info.java | 2 +- .../mongodb/util/spel/ExpressionUtils.java | 8 +- .../CapturingTransactionOptionsResolver.java | 5 +- .../MongoTransactionOptionsUnitTests.java | 14 +- .../MongoExceptionTranslatorUnitTests.java | 2 +- .../MongoTemplateDocumentReferenceTests.java | 11 +- .../core/MongoTemplateScrollTests.java | 2 +- .../data/mongodb/core/MongoTemplateTests.java | 2 +- .../mongodb/core/MongoTemplateUnitTests.java | 5 +- .../core/MongoTemplateValidationTests.java | 8 +- .../data/mongodb/core/Person.java | 2 +- .../core/ReactiveMongoTemplateUnitTests.java | 2 +- .../core/TransactionOptionsTestService.java | 23 +-- .../core/UpdateOperationsUnitTests.java | 4 +- .../data/mongodb/core/User.java | 2 +- .../AddFieldsOperationUnitTests.java | 2 +- .../DensifyOperationUnitTests.java | 2 +- .../GeoNearOperationUnitTests.java | 2 +- .../aggregation/MergeOperationUnitTests.java | 2 +- .../aggregation/RedactOperationUnitTests.java | 2 +- .../aggregation/SetOperationUnitTests.java | 2 +- .../SetWindowFieldsOperationUnitTests.java | 2 +- .../UnionWithOperationUnitTests.java | 2 +- .../aggregation/UnsetOperationUnitTests.java | 2 +- .../DbRefMappingMongoConverterUnitTests.java | 2 +- .../MappingMongoConverterUnitTests.java | 32 ++-- .../core/convert/ReversingValueConverter.java | 2 +- .../mongodb/core/query/TextQueryTests.java | 2 +- .../performance/ReactivePerformanceTests.java | 5 +- .../data/mongodb/repository/Address.java | 3 +- ...oRepositoryTextSearchIntegrationTests.java | 2 +- .../data/mongodb/repository/MyId.java | 2 +- .../data/mongodb/repository/Person.java | 2 +- .../mongodb/repository/PersonRepository.java | 2 +- .../PersonRepositoryTransactionalTests.java | 5 +- .../SimpleReactiveMongoRepositoryTests.java | 2 +- .../mongodb/repository/UserWithComplexId.java | 2 +- .../mongodb/repository/VersionedPerson.java | 5 +- ...activeStringBasedAggregationUnitTests.java | 8 +- .../StringBasedAggregationUnitTests.java | 8 +- .../query/StubParameterAccessor.java | 2 +- .../test/util/MappingContextConfigurer.java | 2 +- .../util/MongoTestTemplateConfiguration.java | 2 +- 354 files changed, 806 insertions(+), 1172 deletions(-) create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/package-info.java diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index dbb34aeb56..597905ce54 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -354,8 +354,76 @@ - + + + nullaway + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + com.querydsl + querydsl-apt + ${querydsl} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh} + + + com.google.errorprone + error_prone_core + ${errorprone} + + + com.uber.nullaway + nullaway + ${nullaway} + + + + + + default-compile + none + + + default-testCompile + none + + + java-compile + compile + + compile + + + + -XDcompilePolicy=simple + --should-stop=ifError=FLOW + -Xplugin:ErrorProne -XepDisableAllChecks -Xep:NullAway:ERROR -XepOpt:NullAway:OnlyNullMarked=true -XepOpt:NullAway:TreatGeneratedAsUnannotated=true -XepOpt:NullAway:CustomContractAnnotations=org.springframework.lang.Contract + + + + + java-test-compile + test-compile + + testCompile + + + + + + + + + diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java index 1f6875c080..470964252c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java @@ -20,9 +20,9 @@ import org.bson.Document; import org.bson.codecs.DocumentCodec; import org.bson.codecs.configuration.CodecRegistry; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -55,7 +55,7 @@ public class BindableMongoExpression implements MongoExpression { private final @Nullable CodecRegistryProvider codecRegistryProvider; - private final @Nullable Object[] args; + private final Object @Nullable[] args; private final Lazy target; @@ -65,7 +65,7 @@ public class BindableMongoExpression implements MongoExpression { * @param expression must not be {@literal null}. * @param args can be {@literal null}. */ - public BindableMongoExpression(String expression, @Nullable Object[] args) { + public BindableMongoExpression(String expression, Object @Nullable[] args) { this(expression, null, args); } @@ -77,7 +77,7 @@ public BindableMongoExpression(String expression, @Nullable Object[] args) { * @param args can be {@literal null}. */ public BindableMongoExpression(String expression, @Nullable CodecRegistryProvider codecRegistryProvider, - @Nullable Object[] args) { + Object @Nullable[] args) { Assert.notNull(expression, "Expression must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ClientSessionException.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ClientSessionException.java index 53acf65470..c59eecb43a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ClientSessionException.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ClientSessionException.java @@ -15,8 +15,8 @@ */ package org.springframework.data.mongodb; +import org.jspecify.annotations.Nullable; import org.springframework.dao.NonTransientDataAccessException; -import org.springframework.lang.Nullable; /** * {@link NonTransientDataAccessException} specific to MongoDB {@link com.mongodb.session.ClientSession} related data diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/DefaultMongoTransactionOptionsResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/DefaultMongoTransactionOptionsResolver.java index c07e2dbe4a..87201ef9ee 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/DefaultMongoTransactionOptionsResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/DefaultMongoTransactionOptionsResolver.java @@ -18,7 +18,7 @@ import java.util.Map; import java.util.Set; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Default implementation of {@link MongoTransactionOptions} using {@literal mongo:} as {@link #getLabelPrefix() label @@ -42,9 +42,8 @@ public MongoTransactionOptions convert(Map options) { return SimpleMongoTransactionOptions.of(options); } - @Nullable @Override - public String getLabelPrefix() { + public @Nullable String getLabelPrefix() { return PREFIX; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java index f73f9fb7ed..acc406de26 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.transaction.support.ResourceHolderSynchronization; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; @@ -139,8 +139,7 @@ public static boolean isTransactionActive(MongoDatabaseFactory dbFactory) { return resourceHolder != null && resourceHolder.hasActiveTransaction(); } - @Nullable - private static ClientSession doGetSession(MongoDatabaseFactory dbFactory, + private static @Nullable ClientSession doGetSession(MongoDatabaseFactory dbFactory, SessionSynchronization sessionSynchronization) { MongoResourceHolder resourceHolder = (MongoResourceHolder) TransactionSynchronizationManager.getResource(dbFactory); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java index a1e8344a9f..2998a0c9b1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.support.ResourceHolderSupport; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionException.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionException.java index 4215479f62..3d7bec6780 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionException.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionException.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * A specific {@link ClientSessionException} related to issues with a transaction such as aborted or non existing diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java index eda657f5f1..f19acc6ff6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java @@ -15,8 +15,8 @@ */ package org.springframework.data.mongodb; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionSystemException; @@ -302,8 +302,7 @@ public void setOptions(@Nullable TransactionOptions options) { * * @return can be {@literal null}. */ - @Nullable - public MongoDatabaseFactory getDatabaseFactory() { + public @Nullable MongoDatabaseFactory getDatabaseFactory() { return databaseFactory; } @@ -461,8 +460,7 @@ void closeSession() { } } - @Nullable - public ClientSession getSession() { + public @Nullable ClientSession getSession() { return resourceHolder != null ? resourceHolder.getSession() : null; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java index e411bd5d2d..e8ad1c713b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java @@ -19,10 +19,10 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.ReadConcernAware; import org.springframework.data.mongodb.core.ReadPreferenceAware; import org.springframework.data.mongodb.core.WriteConcernAware; -import org.springframework.lang.Nullable; import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; @@ -43,27 +43,23 @@ public interface MongoTransactionOptions */ MongoTransactionOptions NONE = new MongoTransactionOptions() { - @Nullable @Override - public Duration getMaxCommitTime() { + public @Nullable Duration getMaxCommitTime() { return null; } - @Nullable @Override - public ReadConcern getReadConcern() { + public @Nullable ReadConcern getReadConcern() { return null; } - @Nullable @Override - public ReadPreference getReadPreference() { + public @Nullable ReadPreference getReadPreference() { return null; } - @Nullable @Override - public WriteConcern getWriteConcern() { + public @Nullable WriteConcern getWriteConcern() { return null; } }; @@ -84,16 +80,14 @@ default MongoTransactionOptions mergeWith(@Nullable MongoTransactionOptions fall return new MongoTransactionOptions() { - @Nullable @Override - public Duration getMaxCommitTime() { + public @Nullable Duration getMaxCommitTime() { return MongoTransactionOptions.this.hasMaxCommitTime() ? MongoTransactionOptions.this.getMaxCommitTime() : fallbackOptions.getMaxCommitTime(); } - @Nullable @Override - public ReadConcern getReadConcern() { + public @Nullable ReadConcern getReadConcern() { return MongoTransactionOptions.this.hasReadConcern() ? MongoTransactionOptions.this.getReadConcern() : fallbackOptions.getReadConcern(); } @@ -105,9 +99,8 @@ public ReadPreference getReadPreference() { : fallbackOptions.getReadPreference(); } - @Nullable @Override - public WriteConcern getWriteConcern() { + public @Nullable WriteConcern getWriteConcern() { return MongoTransactionOptions.this.hasWriteConcern() ? MongoTransactionOptions.this.getWriteConcern() : fallbackOptions.getWriteConcern(); } @@ -168,35 +161,30 @@ static MongoTransactionOptions of(@Nullable TransactionOptions options) { return new MongoTransactionOptions() { - @Nullable @Override - public Duration getMaxCommitTime() { + public @Nullable Duration getMaxCommitTime() { Long millis = options.getMaxCommitTime(TimeUnit.MILLISECONDS); return millis != null ? Duration.ofMillis(millis) : null; } - @Nullable @Override - public ReadConcern getReadConcern() { + public @Nullable ReadConcern getReadConcern() { return options.getReadConcern(); } - @Nullable @Override - public ReadPreference getReadPreference() { + public @Nullable ReadPreference getReadPreference() { return options.getReadPreference(); } - @Nullable @Override - public WriteConcern getWriteConcern() { + public @Nullable WriteConcern getWriteConcern() { return options.getWriteConcern(); } - @Nullable @Override - public TransactionOptions toDriverOptions() { + public @Nullable TransactionOptions toDriverOptions() { return options; } }; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptionsResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptionsResolver.java index b73b079a99..c4bdbcca53 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptionsResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptionsResolver.java @@ -18,7 +18,7 @@ import java.util.Map; import java.util.stream.Collectors; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.interceptor.TransactionAttribute; import org.springframework.util.Assert; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java index f397818a4c..0b63cde870 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java @@ -16,9 +16,10 @@ package org.springframework.data.mongodb; import reactor.core.publisher.Mono; + +import org.jspecify.annotations.Nullable; import reactor.util.context.Context; -import org.springframework.lang.Nullable; import org.springframework.transaction.NoTransactionException; import org.springframework.transaction.reactive.ReactiveResourceSynchronization; import org.springframework.transaction.reactive.TransactionSynchronization; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java index 33caa5e7fe..6705ffe526 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java @@ -15,8 +15,8 @@ */ package org.springframework.data.mongodb; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; -import org.springframework.lang.Nullable; import org.springframework.transaction.support.ResourceHolderSupport; import com.mongodb.reactivestreams.client.ClientSession; @@ -103,8 +103,7 @@ boolean hasSession() { * @param session * @return */ - @Nullable - public ClientSession setSessionIfAbsent(@Nullable ClientSession session) { + public @Nullable ClientSession setSessionIfAbsent(@Nullable ClientSession session) { if (!hasSession()) { setSession(session); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java index 2c65c26b79..5ae44955a0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java @@ -17,8 +17,8 @@ import reactor.core.publisher.Mono; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionSystemException; @@ -318,8 +318,7 @@ public void setOptions(@Nullable TransactionOptions options) { * * @return can be {@literal null}. */ - @Nullable - public ReactiveMongoDatabaseFactory getDatabaseFactory() { + public @Nullable ReactiveMongoDatabaseFactory getDatabaseFactory() { return databaseFactory; } @@ -470,8 +469,7 @@ void closeSession() { } } - @Nullable - public ClientSession getSession() { + public @Nullable ClientSession getSession() { return resourceHolder != null ? resourceHolder.getSession() : null; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java index 93dbf5db69..76d718b1e4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java @@ -22,8 +22,8 @@ import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; +import org.jspecify.annotations.Nullable; import org.springframework.core.MethodClassKey; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ConcurrentReferenceHashMap; @@ -95,9 +95,8 @@ public SessionAwareMethodInterceptor(ClientSession session, T target, Class< this.sessionType = sessionType; } - @Nullable @Override - public Object invoke(MethodInvocation methodInvocation) throws Throwable { + public @Nullable Object invoke(MethodInvocation methodInvocation) throws Throwable { if (requiresDecoration(methodInvocation.getMethod())) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java index b52fc0bd71..0dfe5d9e5a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java @@ -21,7 +21,7 @@ import java.util.Set; import java.util.stream.Collectors; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import com.mongodb.Function; @@ -58,27 +58,23 @@ private SimpleMongoTransactionOptions(Map options) { this.writeConcern = doGetWriteConcern(options); } - @Nullable @Override - public Duration getMaxCommitTime() { + public @Nullable Duration getMaxCommitTime() { return maxCommitTime; } - @Nullable @Override - public ReadConcern getReadConcern() { + public @Nullable ReadConcern getReadConcern() { return readConcern; } - @Nullable @Override - public ReadPreference getReadPreference() { + public @Nullable ReadPreference getReadPreference() { return readPreference; } - @Nullable @Override - public WriteConcern getWriteConcern() { + public @Nullable WriteConcern getWriteConcern() { return writeConcern; } @@ -89,8 +85,7 @@ public String toString() { + ", readPreference=" + readPreference + ", writeConcern=" + writeConcern + '}'; } - @Nullable - private static Duration doGetMaxCommitTime(Map options) { + private static @Nullable Duration doGetMaxCommitTime(Map options) { return getValue(options, OptionKey.MAX_COMMIT_TIME, value -> { @@ -100,18 +95,15 @@ private static Duration doGetMaxCommitTime(Map options) { }); } - @Nullable - private static ReadConcern doGetReadConcern(Map options) { + private static @Nullable ReadConcern doGetReadConcern(Map options) { return getValue(options, OptionKey.READ_CONCERN, value -> new ReadConcern(ReadConcernLevel.fromString(value))); } - @Nullable - private static ReadPreference doGetReadPreference(Map options) { + private static @Nullable ReadPreference doGetReadPreference(Map options) { return getValue(options, OptionKey.READ_PREFERENCE, ReadPreference::valueOf); } - @Nullable - private static WriteConcern doGetWriteConcern(Map options) { + private static @Nullable WriteConcern doGetWriteConcern(Map options) { return getValue(options, OptionKey.WRITE_CONCERN, value -> { @@ -123,8 +115,7 @@ private static WriteConcern doGetWriteConcern(Map options) { }); } - @Nullable - private static T getValue(Map options, OptionKey key, Function convertFunction) { + private static @Nullable T getValue(Map options, OptionKey key, Function convertFunction) { String value = options.get(key.getKey()); return value != null ? convertFunction.apply(value) : null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionMetadata.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionMetadata.java index cd5f58d5b1..57ecec0342 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionMetadata.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionMetadata.java @@ -17,7 +17,7 @@ import java.time.Duration; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * MongoDB-specific transaction metadata. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionOptionResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionOptionResolver.java index 37c7e3686b..e42c26d95a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionOptionResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionOptionResolver.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.transaction.TransactionDefinition; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/UncategorizedMongoDbException.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/UncategorizedMongoDbException.java index bec05d0d68..69ec086e5a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/UncategorizedMongoDbException.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/UncategorizedMongoDbException.java @@ -15,8 +15,8 @@ */ package org.springframework.data.mongodb; +import org.jspecify.annotations.Nullable; import org.springframework.dao.UncategorizedDataAccessException; -import org.springframework.lang.Nullable; public class UncategorizedMongoDbException extends UncategorizedDataAccessException { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoAotPredicates.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoAotPredicates.java index 2fe27a2c9e..86a70600a8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoAotPredicates.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoAotPredicates.java @@ -17,11 +17,11 @@ import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes; import org.springframework.data.util.ReactiveWrappers; import org.springframework.data.util.ReactiveWrappers.ReactiveLibrary; import org.springframework.data.util.TypeUtils; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoManagedTypesBeanRegistrationAotProcessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoManagedTypesBeanRegistrationAotProcessor.java index a33f20ffb6..4b7aa10c3f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoManagedTypesBeanRegistrationAotProcessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoManagedTypesBeanRegistrationAotProcessor.java @@ -15,11 +15,11 @@ */ package org.springframework.data.mongodb.aot; +import org.jspecify.annotations.Nullable; import org.springframework.aot.generate.GenerationContext; import org.springframework.core.ResolvableType; import org.springframework.data.aot.ManagedTypesBeanRegistrationAotProcessor; import org.springframework.data.mongodb.MongoManagedTypes; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java index 538fe4e812..453418ffd6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java @@ -19,6 +19,7 @@ import java.util.Arrays; +import org.jspecify.annotations.Nullable; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; @@ -31,7 +32,6 @@ import org.springframework.data.mongodb.core.mapping.event.ReactiveAfterSaveCallback; import org.springframework.data.mongodb.core.mapping.event.ReactiveBeforeConvertCallback; import org.springframework.data.mongodb.core.mapping.event.ReactiveBeforeSaveCallback; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import com.mongodb.MongoClientSettings; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ConnectionStringPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ConnectionStringPropertyEditor.java index b070a0190f..0f6ba01704 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ConnectionStringPropertyEditor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ConnectionStringPropertyEditor.java @@ -17,7 +17,7 @@ import java.beans.PropertyEditorSupport; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.StringUtils; import com.mongodb.ConnectionString; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java index 164b4defb6..b9ab066181 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; @@ -56,7 +57,6 @@ import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -157,8 +157,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { return null; } - @Nullable - private BeanDefinition potentiallyCreateValidatingMongoEventListener(Element element, ParserContext parserContext) { + private @Nullable BeanDefinition potentiallyCreateValidatingMongoEventListener(Element element, ParserContext parserContext) { String disableValidation = element.getAttribute("disable-validation"); boolean validationDisabled = StringUtils.hasText(disableValidation) && Boolean.parseBoolean(disableValidation); @@ -291,8 +290,7 @@ private static void parseFieldNamingStrategy(Element element, ReaderContext cont } } - @Nullable - private BeanDefinition getCustomConversions(Element element, ParserContext parserContext) { + private @Nullable BeanDefinition getCustomConversions(Element element, ParserContext parserContext) { List customConvertersElements = DomUtils.getChildElementsByTagName(element, "custom-converters"); @@ -354,8 +352,7 @@ private static Set getInitialEntityClasses(Element element) { return classes; } - @Nullable - public BeanMetadataElement parseConverter(Element element, ParserContext parserContext) { + public @Nullable BeanMetadataElement parseConverter(Element element, ParserContext parserContext) { String converterRef = element.getAttribute("ref"); if (StringUtils.hasText(converterRef)) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java index 4e05fe6c39..786827eb55 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java @@ -18,6 +18,7 @@ import static org.springframework.data.config.ParsingUtils.*; import static org.springframework.data.mongodb.config.BeanNames.*; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; @@ -29,7 +30,6 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback; import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; 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 b8f23a35af..93d778c861 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 @@ -26,7 +26,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java index 2e733cc79f..2a6939fbdc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java @@ -20,6 +20,7 @@ import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.parsing.BeanComponentDefinition; @@ -31,7 +32,6 @@ import org.springframework.data.config.BeanComponentDefinitionBuilder; import org.springframework.data.mongodb.core.MongoClientFactoryBean; import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; -import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; import org.w3c.dom.Element; @@ -125,8 +125,7 @@ private BeanDefinition registerMongoBeanDefinition(Element element, ParserContex * @param parserContext * @return {@literal null} in case no client-/uri defined. */ - @Nullable - private BeanDefinition getConnectionString(Element element, ParserContext parserContext) { + private @Nullable BeanDefinition getConnectionString(Element element, ParserContext parserContext) { String type = null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadConcernPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadConcernPropertyEditor.java index 60bf126ae7..3f5cb0ca62 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadConcernPropertyEditor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadConcernPropertyEditor.java @@ -17,7 +17,7 @@ import java.beans.PropertyEditorSupport; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.StringUtils; import com.mongodb.ReadConcern; 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 5ed9b66619..f24c435348 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 @@ -17,10 +17,10 @@ import java.beans.PropertyEditorSupport; -import org.springframework.lang.Nullable; - import com.mongodb.ReadPreference; +import org.jspecify.annotations.Nullable; + /** * Parse a {@link String} to a {@link ReadPreference}. * 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 9c51900902..a09a5e2486 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 @@ -23,7 +23,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -80,8 +80,7 @@ public void setAsText(@Nullable String replicaSetString) { * @param source * @return the */ - @Nullable - private ServerAddress parseServerAddress(String source) { + private @Nullable ServerAddress parseServerAddress(String source) { if (!StringUtils.hasText(source)) { if(LOG.isWarnEnabled()) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/UUidRepresentationPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/UUidRepresentationPropertyEditor.java index b777969967..23c15102ac 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/UUidRepresentationPropertyEditor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/UUidRepresentationPropertyEditor.java @@ -18,7 +18,7 @@ import java.beans.PropertyEditorSupport; import org.bson.UuidRepresentation; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.StringUtils; /** 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 ee0d09e555..32c19e24c3 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 @@ -17,7 +17,7 @@ import java.beans.PropertyEditorSupport; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.StringUtils; import com.mongodb.WriteConcern; 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 5a1e5b725e..555cc9f66e 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,6 +1,6 @@ /** * Spring XML namespace configuration for MongoDB specific repositories. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.config; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/AggregationUtil.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/AggregationUtil.java index a00d95a9ad..ec7c368eaf 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/AggregationUtil.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/AggregationUtil.java @@ -18,7 +18,7 @@ import java.util.List; import org.bson.Document; - +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext; @@ -30,7 +30,6 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; /** * Utility methods to map {@link org.springframework.data.mongodb.core.aggregation.Aggregation} pipeline definitions and diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java index 17b8835b7e..42f436c21d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java @@ -21,9 +21,9 @@ import org.bson.BsonTimestamp; import org.bson.BsonValue; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.messaging.Message; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -78,8 +78,7 @@ public ChangeStreamEvent(@Nullable ChangeStreamDocument raw, Class * * @return can be {@literal null}. */ - @Nullable - public ChangeStreamDocument getRaw() { + public @Nullable ChangeStreamDocument getRaw() { return raw; } @@ -88,8 +87,7 @@ public ChangeStreamDocument getRaw() { * * @return can be {@literal null}. */ - @Nullable - public Instant getTimestamp() { + public @Nullable Instant getTimestamp() { return getBsonTimestamp() != null ? converter.getConversionService().convert(raw.getClusterTime(), Instant.class) : null; @@ -111,8 +109,7 @@ public BsonTimestamp getBsonTimestamp() { * * @return can be {@literal null}. */ - @Nullable - public BsonValue getResumeToken() { + public @Nullable BsonValue getResumeToken() { return raw != null ? raw.getResumeToken() : null; } @@ -121,8 +118,7 @@ public BsonValue getResumeToken() { * * @return can be {@literal null}. */ - @Nullable - public OperationType getOperationType() { + public @Nullable OperationType getOperationType() { return raw != null ? raw.getOperationType() : null; } @@ -131,8 +127,7 @@ public OperationType getOperationType() { * * @return can be {@literal null}. */ - @Nullable - public String getDatabaseName() { + public @Nullable String getDatabaseName() { return raw != null ? raw.getNamespace().getDatabaseName() : null; } @@ -152,8 +147,7 @@ public String getCollectionName() { * @return {@literal null} when {@link #getRaw()} or {@link ChangeStreamDocument#getFullDocument()} is * {@literal null}. */ - @Nullable - public T getBody() { + public @Nullable T getBody() { if (raw == null || raw.getFullDocument() == null) { return null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java index aaee3b76af..4ff8a130c0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java @@ -23,9 +23,9 @@ import org.bson.BsonTimestamp; import org.bson.BsonValue; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.query.Collation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; 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 c142aca173..bf8be5ba69 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 @@ -16,8 +16,8 @@ package org.springframework.data.mongodb.core; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; -import org.springframework.lang.Nullable; import com.mongodb.MongoException; import com.mongodb.client.MongoCollection; 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 d627ba2468..5d6b87cf45 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 @@ -19,6 +19,7 @@ import java.util.Optional; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.core.schema.MongoJsonSchema; @@ -26,7 +27,6 @@ import org.springframework.data.mongodb.core.timeseries.GranularityDefinition; import org.springframework.data.mongodb.core.validation.Validator; import org.springframework.data.util.Optionals; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -715,8 +715,7 @@ public String getTimeField() { * @return can be {@literal null}. Might be an {@literal empty} {@link String} as well, so maybe check via * {@link org.springframework.util.StringUtils#hasText(String)}. */ - @Nullable - public String getMetaField() { + public @Nullable String getMetaField() { return metaField; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java index 4fa6b3e97d..3f3025cf90 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java @@ -23,9 +23,9 @@ import java.util.Map; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; import org.springframework.data.mongodb.core.query.MetricConversion; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CursorPreparer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CursorPreparer.java index 9b7408b0cf..3b53cef8d0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CursorPreparer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CursorPreparer.java @@ -18,7 +18,7 @@ import java.util.function.Function; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import com.mongodb.ReadPreference; @@ -76,8 +76,7 @@ default FindIterable initiateFind(MongoCollection collection * @since 2.2 */ @Override - @Nullable - default ReadPreference getReadPreference() { + default @Nullable ReadPreference getReadPreference() { return null; } } 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 9d588ad16d..f450bddb30 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 @@ -15,8 +15,8 @@ */ package org.springframework.data.mongodb.core; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; -import org.springframework.lang.Nullable; import com.mongodb.MongoException; import com.mongodb.client.MongoDatabase; 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 52343522a7..7d3798d83f 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 @@ -21,6 +21,7 @@ import java.util.stream.Collectors; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.dao.DataIntegrityViolationException; @@ -40,7 +41,6 @@ import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.data.util.Pair; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.MongoBulkWriteException; 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 2057e2f046..3293a233c8 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 @@ -20,6 +20,7 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.UncategorizedMongoDbException; @@ -28,7 +29,6 @@ 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 org.springframework.util.NumberUtils; @@ -131,8 +131,7 @@ public String ensureIndex(IndexDefinition indexDefinition) { }); } - @Nullable - private MongoPersistentEntity lookupPersistentEntity(@Nullable Class entityType, String collection) { + private @Nullable MongoPersistentEntity lookupPersistentEntity(@Nullable Class entityType, String collection) { if (entityType != null) { return mapper.getMappingContext().getRequiredPersistentEntity(entityType); @@ -208,8 +207,7 @@ private List getIndexData(MongoCursor cursor) { }); } - @Nullable - public T execute(CollectionCallback callback) { + public @Nullable 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/DefaultReactiveBulkOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java index 59b7ccd63e..22daa71799 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java @@ -24,6 +24,7 @@ import java.util.stream.Collectors; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.mapping.callback.EntityCallback; @@ -40,7 +41,6 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.UpdateDefinition; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.WriteConcern; 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 8e78f421f4..1fdcb574ec 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 @@ -22,13 +22,13 @@ import java.util.Optional; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.UncategorizedMongoDbException; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.index.IndexDefinition; import org.springframework.data.mongodb.core.index.IndexInfo; import org.springframework.data.mongodb.core.index.ReactiveIndexOperations; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.NumberUtils; @@ -124,8 +124,7 @@ public Mono alterIndex(String name, org.springframework.data.mongodb.core. }).then(); } - @Nullable - private MongoPersistentEntity lookupPersistentEntity(String collection) { + private @Nullable MongoPersistentEntity lookupPersistentEntity(String collection) { Collection> entities = queryMapper.getMappingContext().getPersistentEntities(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityLifecycleEventDelegate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityLifecycleEventDelegate.java index 94352ad65c..d577ec9cd0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityLifecycleEventDelegate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityLifecycleEventDelegate.java @@ -15,8 +15,8 @@ */ package org.springframework.data.mongodb.core; +import org.jspecify.annotations.Nullable; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.lang.Nullable; /** * Delegate class to encapsulate lifecycle event configuration and publishing. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java index 65a5131dd1..7551b6ea4a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java @@ -25,6 +25,7 @@ import org.bson.BsonNull; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.ConversionService; import org.springframework.core.env.Environment; import org.springframework.core.env.EnvironmentCapable; @@ -63,7 +64,6 @@ import org.springframework.data.projection.TargetAware; import org.springframework.data.util.Optionals; import org.springframework.expression.spel.support.SimpleEvaluationContext; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.LinkedMultiValueMap; @@ -578,9 +578,8 @@ public Query getByIdQuery() { return Query.query(Criteria.where(ID_FIELD).is(map.get(ID_FIELD))); } - @Nullable @Override - public T populateIdIfNecessary(@Nullable Object id) { + public @Nullable T populateIdIfNecessary(@Nullable Object id) { map.put(ID_FIELD, id); @@ -605,8 +604,7 @@ public T initializeVersionProperty() { } @Override - @Nullable - public Number getVersion() { + public @Nullable Number getVersion() { return null; } @@ -790,8 +788,7 @@ public boolean isVersionedEntity() { } @Override - @Nullable - public Object getVersion() { + public @Nullable Object getVersion() { return propertyAccessor.getProperty(entity.getRequiredVersionProperty()); } @@ -888,9 +885,8 @@ private static AdaptibleEntity of(T bean, new ConvertingPropertyAccessor<>(propertyAccessor, conversionService), entityOperations); } - @Nullable @Override - public T populateIdIfNecessary(@Nullable Object id) { + public @Nullable T populateIdIfNecessary(@Nullable Object id) { if (id == null) { return propertyAccessor.getBean(); @@ -910,8 +906,7 @@ public T populateIdIfNecessary(@Nullable Object id) { } @Override - @Nullable - public Number getVersion() { + public @Nullable Number getVersion() { MongoPersistentProperty versionProperty = entity.getRequiredVersionProperty(); 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 3358ff2b17..21cb37ae86 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 @@ -19,6 +19,7 @@ import java.util.Optional; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.data.domain.KeysetScrollPosition; import org.springframework.data.domain.ScrollPosition; @@ -27,7 +28,6 @@ import org.springframework.data.mongodb.core.query.CriteriaDefinition; import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.lang.Nullable; import com.mongodb.client.MongoCollection; 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 4e6c3547c5..2bba87ed2d 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 @@ -20,14 +20,13 @@ import java.util.stream.Stream; import org.bson.Document; - +import org.jspecify.annotations.Nullable; import org.springframework.dao.IncorrectResultSizeDataAccessException; -import org.springframework.data.domain.ScrollPosition; import org.springframework.data.domain.Window; +import org.springframework.data.domain.ScrollPosition; import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.SerializationUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -206,7 +205,7 @@ private String asString() { * @author Christoph Strobl * @since 2.0 */ - static class DelegatingQueryCursorPreparer implements SortingQueryCursorPreparer { + static class DelegatingQueryCursorPreparer implements CursorPreparer { private final @Nullable CursorPreparer delegate; private Optional limit = Optional.empty(); @@ -229,16 +228,9 @@ CursorPreparer limit(int limit) { } @Override - @Nullable public ReadPreference getReadPreference() { return delegate.getReadPreference(); } - - @Override - @Nullable - public Document getSortObject() { - return delegate instanceof SortingQueryCursorPreparer sqcp ? sqcp.getSortObject() : null; - } } /** 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 47b7127deb..f786ac0700 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 @@ -18,8 +18,8 @@ import java.util.ArrayList; import java.util.Collection; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.BulkOperations.BulkMode; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java index 9f78693540..4f0ff6a283 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java @@ -17,9 +17,9 @@ import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; 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 8e84aa7dd6..3d52c33fc1 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 @@ -17,8 +17,8 @@ import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; 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 a5c63e9b67..69365459ba 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 @@ -17,12 +17,12 @@ import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.AggregationUpdate; import org.springframework.data.mongodb.core.query.CriteriaDefinition; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.UpdateDefinition; -import org.springframework.lang.Nullable; import com.mongodb.client.result.UpdateResult; 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 593d863d39..133581ada6 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 @@ -15,9 +15,9 @@ */ package org.springframework.data.mongodb.core; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.UpdateDefinition; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; 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 51a2c5b86a..6497d156c4 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 @@ -17,8 +17,8 @@ import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Collation; -import org.springframework.lang.Nullable; /** * @author Mark Pollak diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindPublisherPreparer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindPublisherPreparer.java index 625a85950e..f04417325c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindPublisherPreparer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindPublisherPreparer.java @@ -18,7 +18,7 @@ import java.util.function.Function; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import com.mongodb.ReadPreference; @@ -76,8 +76,7 @@ default FindPublisher initiateFind(MongoCollection collectio * @since 2.2 */ @Override - @Nullable - default ReadPreference getReadPreference() { + default @Nullable ReadPreference getReadPreference() { return null; } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/HintFunction.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/HintFunction.java index 57abe9a529..043613122a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/HintFunction.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/HintFunction.java @@ -18,9 +18,9 @@ import java.util.function.Function; import org.bson.conversions.Bson; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.CodecRegistryProvider; import org.springframework.data.mongodb.util.BsonUtils; -import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; /** 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 f5856100d0..c206593fdc 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 @@ -18,12 +18,11 @@ import java.util.concurrent.TimeUnit; import org.bson.Document; - +import org.jspecify.annotations.Nullable; 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.data.mongodb.util.MongoCompatibilityAdapter; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import com.mongodb.client.model.Collation; @@ -129,8 +128,7 @@ private static Converter getIndexDefinitionIndexO }; } - @Nullable - public static Collation fromDocument(@Nullable Document source) { + public static @Nullable 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 fdfeaa81ad..c827c5b8a9 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 @@ -16,7 +16,7 @@ package org.springframework.data.mongodb.core; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import com.mongodb.WriteConcern; @@ -72,28 +72,23 @@ public String getCollectionName() { return collectionName; } - @Nullable - public WriteConcern getDefaultWriteConcern() { + public @Nullable WriteConcern getDefaultWriteConcern() { return defaultWriteConcern; } - @Nullable - public Class getEntityType() { + public @Nullable Class getEntityType() { return entityType; } - @Nullable - public MongoActionOperation getMongoActionOperation() { + public @Nullable MongoActionOperation getMongoActionOperation() { return mongoActionOperation; } - @Nullable - public Document getQuery() { + public @Nullable Document getQuery() { return query; } - @Nullable - public Document getDocument() { + public @Nullable Document getDocument() { return document; } 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 c5fee9cf54..5a1f5088a3 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 @@ -24,11 +24,11 @@ import java.util.stream.Collectors; import org.bson.UuidRepresentation; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.mongodb.SpringDataMongoDB; -import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -78,7 +78,7 @@ public void setMongoClientSettings(@Nullable MongoClientSettings mongoClientOpti * * @param credential can be {@literal null}. */ - public void setCredential(@Nullable MongoCredential[] credential) { + public void setCredential(MongoCredential @Nullable[] credential) { this.credential = Arrays.asList(credential); } @@ -119,8 +119,7 @@ public void setExceptionTranslator(@Nullable PersistenceExceptionTranslator exce } @Override - @Nullable - public DataAccessException translateExceptionIfPossible(RuntimeException ex) { + public @Nullable DataAccessException translateExceptionIfPossible(RuntimeException ex) { return exceptionTranslator.translateExceptionIfPossible(ex); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientSettingsFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientSettingsFactoryBean.java index 02913b4303..0bce8db304 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientSettingsFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientSettingsFactoryBean.java @@ -25,10 +25,9 @@ import org.bson.UuidRepresentation; import org.bson.codecs.configuration.CodecRegistry; - +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.data.mongodb.util.MongoCompatibilityAdapter; -import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDatabaseFactorySupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDatabaseFactorySupport.java index eab6b5d7f4..59651e7cca 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDatabaseFactorySupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDatabaseFactorySupport.java @@ -15,12 +15,12 @@ */ package org.springframework.data.mongodb.core; +import org.jspecify.annotations.Nullable; import org.springframework.aop.framework.ProxyFactory; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.SessionAwareMethodInterceptor; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java index 7aef5a3a82..cd850ac304 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java @@ -19,8 +19,8 @@ import java.util.Map; import org.bson.BsonDocument; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.FactoryBean; -import org.springframework.lang.Nullable; import com.mongodb.AutoEncryptionSettings; import com.mongodb.MongoClientSettings; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java index 1ec7d3ffc0..a07d0085ff 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java @@ -18,7 +18,7 @@ import java.util.Set; import org.bson.BsonInvalidOperationException; - +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; @@ -31,7 +31,6 @@ import org.springframework.data.mongodb.TransientClientSessionException; import org.springframework.data.mongodb.UncategorizedMongoDbException; import org.springframework.data.mongodb.util.MongoDbErrorCodes; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import com.mongodb.MongoBulkWriteException; @@ -69,8 +68,7 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator private static final Set SECURITY_EXCEPTIONS = Set.of("MongoCryptException"); @Override - @Nullable - public DataAccessException translateExceptionIfPossible(RuntimeException ex) { + public @Nullable DataAccessException translateExceptionIfPossible(RuntimeException ex) { return doTranslateException(ex); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java index f400b35a68..6d604bef37 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java @@ -24,6 +24,7 @@ import java.util.stream.Stream; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.KeysetScrollPosition; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Window; @@ -49,7 +50,6 @@ import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.data.util.Lock; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -1047,8 +1047,7 @@ T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions o * {@link #getCollectionName(Class) derived} from the given replacement value. * @since 2.1 */ - @Nullable - default T findAndReplace(Query query, T replacement) { + default @Nullable T findAndReplace(Query query, T replacement) { return findAndReplace(query, replacement, FindAndReplaceOptions.empty()); } @@ -1067,8 +1066,7 @@ default T findAndReplace(Query query, T replacement) { * @return the converted object that was updated or {@literal null}, if not found. * @since 2.1 */ - @Nullable - default T findAndReplace(Query query, T replacement, String collectionName) { + default @Nullable T findAndReplace(Query query, T replacement, String collectionName) { return findAndReplace(query, replacement, FindAndReplaceOptions.empty(), collectionName); } @@ -1090,8 +1088,7 @@ default T findAndReplace(Query query, T replacement, String collectionName) * {@link #getCollectionName(Class) derived} from the given replacement value. * @since 2.1 */ - @Nullable - default T findAndReplace(Query query, T replacement, FindAndReplaceOptions options) { + default @Nullable T findAndReplace(Query query, T replacement, FindAndReplaceOptions options) { return findAndReplace(query, replacement, options, getCollectionName(ClassUtils.getUserClass(replacement))); } @@ -1111,8 +1108,7 @@ default T findAndReplace(Query query, T replacement, FindAndReplaceOptions o * as it is after the update. * @since 2.1 */ - @Nullable - default T findAndReplace(Query query, T replacement, FindAndReplaceOptions options, String collectionName) { + default @Nullable T findAndReplace(Query query, T replacement, FindAndReplaceOptions options, String collectionName) { Assert.notNull(replacement, "Replacement must not be null"); return findAndReplace(query, replacement, options, (Class) ClassUtils.getUserClass(replacement), collectionName); @@ -1136,8 +1132,7 @@ default T findAndReplace(Query query, T replacement, FindAndReplaceOptions o * as it is after the update. * @since 2.1 */ - @Nullable - default T findAndReplace(Query query, T replacement, FindAndReplaceOptions options, Class entityType, + default @Nullable T findAndReplace(Query query, T replacement, FindAndReplaceOptions options, Class entityType, String collectionName) { return findAndReplace(query, replacement, options, entityType, collectionName, entityType); @@ -1165,8 +1160,7 @@ default T findAndReplace(Query query, T replacement, FindAndReplaceOptions o * {@link #getCollectionName(Class) derived} from the given replacement value. * @since 2.1 */ - @Nullable - default T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class entityType, + default @Nullable T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class entityType, Class resultType) { return findAndReplace(query, replacement, options, entityType, diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBean.java index 37001faa4e..9223ad9ece 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBean.java @@ -15,8 +15,8 @@ */ package org.springframework.data.mongodb.core; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.FactoryBean; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import com.mongodb.ServerApi; @@ -59,9 +59,8 @@ public void setStrict(@Nullable Boolean strict) { this.strict = strict; } - @Nullable @Override - public ServerApi getObject() throws Exception { + public @Nullable ServerApi getObject() throws Exception { Builder builder = ServerApi.builder().version(version()); 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 67ef3a3081..0be01a0465 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 @@ -30,7 +30,7 @@ import org.apache.commons.logging.LogFactory; import org.bson.Document; import org.bson.conversions.Bson; - +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -85,13 +85,10 @@ import org.springframework.data.mongodb.core.convert.MongoWriter; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.convert.UpdateMapper; -import org.springframework.data.mongodb.core.index.DefaultSearchIndexOperations; import org.springframework.data.mongodb.core.index.IndexOperations; import org.springframework.data.mongodb.core.index.IndexOperationsProvider; import org.springframework.data.mongodb.core.index.MongoMappingEventPublisher; import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator; -import org.springframework.data.mongodb.core.index.SearchIndexOperations; -import org.springframework.data.mongodb.core.index.SearchIndexOperationsProvider; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; @@ -111,7 +108,6 @@ import org.springframework.data.projection.EntityProjection; import org.springframework.data.util.CloseableIterator; import org.springframework.data.util.Optionals; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -184,10 +180,9 @@ * @author Bartłomiej Mazur * @author Michael Krog * @author Jakub Zurawa - * @author Florian Lüdiger */ -public class MongoTemplate implements MongoOperations, ApplicationContextAware, IndexOperationsProvider, - SearchIndexOperationsProvider, ReadPreferenceAware { +public class MongoTemplate + implements MongoOperations, ApplicationContextAware, IndexOperationsProvider, ReadPreferenceAware { private static final Log LOGGER = LogFactory.getLog(MongoTemplate.class); private static final WriteResultChecking DEFAULT_WRITE_RESULT_CHECKING = WriteResultChecking.NONE; @@ -772,21 +767,6 @@ public IndexOperations indexOps(Class entityClass) { return indexOps(getCollectionName(entityClass), entityClass); } - @Override - public SearchIndexOperations searchIndexOps(String collectionName) { - return searchIndexOps(null, collectionName); - } - - @Override - public SearchIndexOperations searchIndexOps(Class type) { - return new DefaultSearchIndexOperations(this, type); - } - - @Override - public SearchIndexOperations searchIndexOps(@Nullable Class type, String collectionName) { - return new DefaultSearchIndexOperations(this, collectionName, type); - } - @Override public BulkOperations bulkOps(BulkMode mode, String collectionName) { return bulkOps(mode, null, collectionName); @@ -819,15 +799,13 @@ public ScriptOperations scriptOps() { // 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) { + public @Nullable T findOne(Query query, Class entityClass) { return findOne(query, entityClass, getCollectionName(entityClass)); } - @Nullable @Override - public T findOne(Query query, Class entityClass, String collectionName) { + public @Nullable T findOne(Query query, Class entityClass, String collectionName) { Assert.notNull(query, "Query must not be null"); Assert.notNull(entityClass, "EntityClass must not be null"); @@ -931,15 +909,13 @@ sourceClass, new QueryCursorPreparer(query, query.getSortObject(), limit, query. return ScrollUtils.createWindow(result, query.getLimit(), OffsetScrollPosition.positionFunction(query.getSkip())); } - @Nullable @Override - public T findById(Object id, Class entityClass) { + public @Nullable T findById(Object id, Class entityClass) { return findById(id, entityClass, getCollectionName(entityClass)); } - @Nullable @Override - public T findById(Object id, Class entityClass, String collectionName) { + public @Nullable T findById(Object id, Class entityClass, String collectionName) { Assert.notNull(id, "Id must not be null"); Assert.notNull(entityClass, "EntityClass must not be null"); @@ -1067,27 +1043,23 @@ public GeoResults geoNear(NearQuery near, Class domainType, String col return new GeoResults<>(result, avgDistance); } - @Nullable @Override - public T findAndModify(Query query, UpdateDefinition update, Class entityClass) { + public @Nullable T findAndModify(Query query, UpdateDefinition update, Class entityClass) { return findAndModify(query, update, new FindAndModifyOptions(), entityClass, getCollectionName(entityClass)); } - @Nullable @Override - public T findAndModify(Query query, UpdateDefinition update, Class entityClass, String collectionName) { + public @Nullable T findAndModify(Query query, UpdateDefinition update, Class entityClass, String collectionName) { return findAndModify(query, update, new FindAndModifyOptions(), entityClass, collectionName); } - @Nullable @Override - public T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class entityClass) { + public @Nullable T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class entityClass) { return findAndModify(query, update, options, entityClass, getCollectionName(entityClass)); } - @Nullable @Override - public T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class entityClass, + public @Nullable T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class entityClass, String collectionName) { Assert.notNull(query, "Query must not be null"); @@ -1154,15 +1126,13 @@ public T findAndReplace(Query query, S replacement, FindAndReplaceOptions // 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) { + public @Nullable T findAndRemove(Query query, Class entityClass) { return findAndRemove(query, entityClass, getCollectionName(entityClass)); } - @Nullable @Override - public T findAndRemove(Query query, Class entityClass, String collectionName) { + public @Nullable T findAndRemove(Query query, Class entityClass, String collectionName) { Assert.notNull(query, "Query must not be null"); Assert.notNull(entityClass, "EntityClass must not be null"); @@ -1320,19 +1290,17 @@ protected MongoCollection prepareCollection(MongoCollection * @param mongoAction any MongoAction already configured or null * @return The prepared WriteConcern or null */ - @Nullable - protected WriteConcern prepareWriteConcern(MongoAction mongoAction) { + protected @Nullable WriteConcern prepareWriteConcern(MongoAction mongoAction) { WriteConcern wc = writeConcernResolver.resolve(mongoAction); return potentiallyForceAcknowledgedWrite(wc); } - @Nullable - private WriteConcern potentiallyForceAcknowledgedWrite(@Nullable WriteConcern wc) { + private @Nullable WriteConcern potentiallyForceAcknowledgedWrite(@Nullable WriteConcern wc) { if (ObjectUtils.nullSafeEquals(WriteResultChecking.EXCEPTION, writeResultChecking)) { if (wc == null || wc.getWObject() == null - || (wc.getWObject() instanceof Number concern && concern.intValue() < 1)) { + || (wc.getWObject()instanceof Number concern && concern.intValue() < 1)) { return WriteConcern.ACKNOWLEDGED; } } @@ -1701,6 +1669,12 @@ protected UpdateResult doUpdate(String collectionName, Query query, UpdateDefini Assert.notNull(query, "Query must not be null"); Assert.notNull(update, "Update must not be null"); + if (query.isSorted() && LOGGER.isWarnEnabled()) { + + LOGGER.warn(String.format("%s does not support sort ('%s'); Please use findAndModify() instead", + upsert ? "Upsert" : "UpdateFirst", serializeToJsonSafely(query.getSortObject()))); + } + MongoPersistentEntity entity = entityClass == null ? null : getPersistentEntity(entityClass); UpdateContext updateContext = multi ? queryOperations.updateContext(update, query, upsert) @@ -1708,7 +1682,7 @@ protected UpdateResult doUpdate(String collectionName, Query query, UpdateDefini updateContext.increaseVersionForUpdateIfNecessary(entity); Document queryObj = updateContext.getMappedQuery(entity); - UpdateOptions opts = updateContext.getUpdateOptions(entityClass, query); + UpdateOptions opts = updateContext.getUpdateOptions(entityClass); if (updateContext.isAggregationUpdate()) { @@ -1978,8 +1952,7 @@ public List mapReduce(Query query, Class domainType, String inputColle } if (mapReduceOptions.getOutputSharded().isPresent()) { - MongoCompatibilityAdapter.mapReduceIterableAdapter(mapReduce) - .sharded(mapReduceOptions.getOutputSharded().get()); + MongoCompatibilityAdapter.mapReduceIterableAdapter(mapReduce).sharded(mapReduceOptions.getOutputSharded().get()); } if (StringUtils.hasText(mapReduceOptions.getOutputCollection()) && !mapReduceOptions.usesInlineOutput()) { @@ -2078,7 +2051,7 @@ public List findAllAndRemove(Query query, Class entityClass, String co } @Override - public UpdateResult replace(Query query, T replacement, ReplaceOptions options, String collectionName) { + public UpdateResult replace(Query query, T replacement, ReplaceOptions options, String collectionName){ Assert.notNull(replacement, "Replacement must not be null"); return replace(query, (Class) ClassUtils.getUserClass(replacement), replacement, options, collectionName); @@ -2522,8 +2495,7 @@ private CreateCollectionOptions getCreateCollectionOptions(Document document) { * @param entityClass the parameterized type of the returned list. * @return the converted object or {@literal null} if none exists. */ - @Nullable - protected T doFindOne(String collectionName, CollectionPreparer> collectionPreparer, + protected @Nullable T doFindOne(String collectionName, CollectionPreparer> collectionPreparer, Document query, Document fields, Class entityClass) { return doFindOne(collectionName, collectionPreparer, query, fields, CursorPreparer.NO_OP_PREPARER, entityClass); } @@ -2541,9 +2513,8 @@ protected T doFindOne(String collectionName, CollectionPreparer T doFindOne(String collectionName, CollectionPreparer> collectionPreparer, + protected @Nullable T doFindOne(String collectionName, CollectionPreparer> collectionPreparer, Document query, Document fields, CursorPreparer preparer, Class entityClass) { MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); @@ -2610,7 +2581,7 @@ protected List doFind(String collectionName, if (LOGGER.isDebugEnabled()) { - Document mappedSort = preparer instanceof SortingQueryCursorPreparer sqcp ? getMappedSortObject(sqcp.getSortObject(), entity) : null; + Document mappedSort = getMappedSortObject(query, entityClass); LOGGER.debug(String.format("find using query: %s fields: %s sort: %s for class: %s in collection: %s", serializeToJsonSafely(mappedQuery), mappedFields, serializeToJsonSafely(mappedSort), entityClass, collectionName)); @@ -2635,12 +2606,9 @@ List doFind(CollectionPreparer> collectionPr QueryContext queryContext = queryOperations.createQueryContext(new BasicQuery(query, fields)); Document mappedFields = queryContext.getMappedFields(entity, projection); Document mappedQuery = queryContext.getMappedQuery(entity); + Document mappedSort = getMappedSortObject(query, sourceClass); if (LOGGER.isDebugEnabled()) { - - Document mappedSort = preparer instanceof SortingQueryCursorPreparer sqcp - ? getMappedSortObject(sqcp.getSortObject(), entity) - : null; LOGGER.debug(String.format("find using query: %s fields: %s sort: %s for class: %s in collection: %s", serializeToJsonSafely(mappedQuery), mappedFields, serializeToJsonSafely(mappedSort), sourceClass, collectionName)); @@ -2757,7 +2725,8 @@ protected T doFindAndModify(CollectionPreparer collectionPreparer, String co LOGGER.debug(String.format( "findAndModify using query: %s fields: %s sort: %s for class: %s and update: %s in collection: %s", serializeToJsonSafely(mappedQuery), fields, serializeToJsonSafely(sort), entityClass, - serializeToJsonSafely(mappedUpdate), collectionName)); + serializeToJsonSafely(mappedUpdate), + collectionName)); } return executeFindOneInternal( @@ -2781,9 +2750,8 @@ protected T doFindAndModify(CollectionPreparer collectionPreparer, String co * @return {@literal null} if object does not exist, {@link FindAndReplaceOptions#isReturnNew() return new} is * {@literal false} and {@link FindAndReplaceOptions#isUpsert() upsert} is {@literal false}. */ - @Nullable - protected T doFindAndReplace(CollectionPreparer collectionPreparer, String collectionName, Document mappedQuery, - Document mappedFields, Document mappedSort, @Nullable com.mongodb.client.model.Collation collation, + protected @Nullable T doFindAndReplace(CollectionPreparer collectionPreparer, String collectionName, Document mappedQuery, + Document mappedFields, Document mappedSort, com.mongodb.client.model.@Nullable Collation collation, Class entityType, Document replacement, FindAndReplaceOptions options, Class resultType) { EntityProjection projection = operations.introspectProjection(resultType, entityType); @@ -2823,9 +2791,8 @@ CollectionPreparer> createCollectionPreparer(Query que * {@literal false} and {@link FindAndReplaceOptions#isUpsert() upsert} is {@literal false}. * @since 3.4 */ - @Nullable - private T doFindAndReplace(CollectionPreparer collectionPreparer, String collectionName, Document mappedQuery, - Document mappedFields, Document mappedSort, @Nullable com.mongodb.client.model.Collation collation, + private @Nullable T doFindAndReplace(CollectionPreparer collectionPreparer, String collectionName, Document mappedQuery, + Document mappedFields, Document mappedSort, com.mongodb.client.model.@Nullable Collation collation, Class entityType, Document replacement, FindAndReplaceOptions options, EntityProjection projection) { if (LOGGER.isDebugEnabled()) { @@ -2896,8 +2863,7 @@ private MongoCollection getAndPrepareCollection(MongoDatabase db, Stri * @param collectionName the collection to be queried * @return */ - @Nullable - private T executeFindOneInternal(CollectionCallback collectionCallback, + private @Nullable T executeFindOneInternal(CollectionCallback collectionCallback, DocumentCallback documentCallback, String collectionName) { try { @@ -2992,8 +2958,7 @@ private static MongoConverter getDefaultMongoConverter(MongoDatabaseFactory fact return converter; } - @Nullable - private Document getMappedSortObject(@Nullable Query query, Class type) { + private @Nullable Document getMappedSortObject(@Nullable Query query, Class type) { if (query == null) { return null; @@ -3002,19 +2967,13 @@ private Document getMappedSortObject(@Nullable Query query, Class type) { return getMappedSortObject(query.getSortObject(), type); } - @Nullable - private Document getMappedSortObject(Document sortObject, Class type) { - return getMappedSortObject(sortObject, mappingContext.getPersistentEntity(type)); - } - - @Nullable - private Document getMappedSortObject(Document sortObject, @Nullable MongoPersistentEntity entity) { + private @Nullable Document getMappedSortObject(Document sortObject, Class type) { if (ObjectUtils.isEmpty(sortObject)) { return null; } - return queryMapper.getMappedSort(sortObject, entity); + return queryMapper.getMappedSort(sortObject, mappingContext.getPersistentEntity(type)); } /** @@ -3084,10 +3043,10 @@ private static class FindCallback implements CollectionCallback> collectionPreparer; private final Document query; private final Document fields; - private final @Nullable com.mongodb.client.model.Collation collation; + private final com.mongodb.client.model.@Nullable Collation collation; public FindCallback(CollectionPreparer> collectionPreparer, Document query, - Document fields, @Nullable com.mongodb.client.model.Collation collation) { + Document fields, com.mongodb.client.model.@Nullable Collation collation) { Assert.notNull(query, "Query must not be null"); Assert.notNull(fields, "Fields must not be null"); @@ -3240,11 +3199,11 @@ private static class FindAndReplaceCallback implements CollectionCallback> collectionPreparer, Document query, - Document fields, Document sort, Document update, @Nullable com.mongodb.client.model.Collation collation, + Document fields, Document sort, Document update, com.mongodb.client.model.@Nullable Collation collation, FindAndReplaceOptions options) { this.collectionPreparer = collectionPreparer; this.query = query; @@ -3367,11 +3326,14 @@ public T doWith(Document document) { } } - class QueryCursorPreparer implements SortingQueryCursorPreparer { + class QueryCursorPreparer implements CursorPreparer { private final Query query; + private final Document sortObject; + private final int limit; + private final long skip; private final @Nullable Class type; @@ -3462,11 +3424,6 @@ public FindIterable prepare(FindIterable iterable) { return cursorToUse; } - @Nullable - @Override - public Document getSortObject() { - return sortObject; - } } /** @@ -3568,9 +3525,8 @@ public boolean hasNext() { } } - @Nullable @Override - public T next() { + public @Nullable T next() { if (cursor == null) { return null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java index 28ca85fbd7..ffb89dd300 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java @@ -31,6 +31,7 @@ import org.bson.codecs.Codec; import org.bson.conversions.Bson; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.data.mapping.context.MappingContext; @@ -62,7 +63,6 @@ import org.springframework.data.mongodb.util.BsonUtils; import org.springframework.data.projection.EntityProjection; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import com.mongodb.client.model.CountOptions; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveChangeStreamOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveChangeStreamOperationSupport.java index afeb6c5e0e..589f264f17 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveChangeStreamOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveChangeStreamOperationSupport.java @@ -24,11 +24,11 @@ import org.bson.BsonTimestamp; import org.bson.BsonValue; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.ChangeStreamOptions.ChangeStreamOptionsBuilder; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.MatchOperation; import org.springframework.data.mongodb.core.query.CriteriaDefinition; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** 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 d1aec8af36..918267e073 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 reactor.core.publisher.Mono; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.data.domain.Window; import org.springframework.data.domain.ScrollPosition; @@ -26,7 +27,6 @@ import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.SerializationUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupport.java index 4f0d395950..34edba0e80 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupport.java @@ -17,9 +17,9 @@ import reactor.core.publisher.Flux; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; 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 89d1cd78ac..e35cf66a19 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 @@ -16,10 +16,10 @@ package org.springframework.data.mongodb.core; +import org.jspecify.annotations.Nullable; 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.MongoClientSettings; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java index 90f2d2345d..ebec41e3aa 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java @@ -23,6 +23,7 @@ import java.util.function.Supplier; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.reactivestreams.Subscription; import org.springframework.data.domain.KeysetScrollPosition; @@ -48,7 +49,6 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.UpdateDefinition; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; 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 ea427a3e1f..68402651ab 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 @@ -44,6 +44,7 @@ import org.bson.Document; import org.bson.conversions.Bson; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.reactivestreams.Subscriber; @@ -121,7 +122,6 @@ import org.springframework.data.mongodb.util.MongoCompatibilityAdapter; import org.springframework.data.projection.EntityProjection; import org.springframework.data.util.Optionals; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -2659,8 +2659,7 @@ protected MongoDatabase prepareDatabase(MongoDatabase database) { * @see #setWriteConcern(WriteConcern) * @see #setWriteConcernResolver(WriteConcernResolver) */ - @Nullable - protected WriteConcern prepareWriteConcern(MongoAction mongoAction) { + protected @Nullable WriteConcern prepareWriteConcern(MongoAction mongoAction) { WriteConcern wc = writeConcernResolver.resolve(mongoAction); return potentiallyForceAcknowledgedWrite(wc); @@ -2764,8 +2763,7 @@ private static RuntimeException potentiallyConvertRuntimeException(RuntimeExcept return resolved == null ? ex : resolved; } - @Nullable - private MongoPersistentEntity getPersistentEntity(@Nullable Class type) { + private @Nullable MongoPersistentEntity getPersistentEntity(@Nullable Class type) { return type == null ? null : mappingContext.getPersistentEntity(type); } @@ -2785,8 +2783,7 @@ private MappingMongoConverter getDefaultMongoConverter() { return converter; } - @Nullable - private Document getMappedSortObject(Query query, Class type) { + private @Nullable Document getMappedSortObject(Query query, Class type) { if (query == null) { return null; @@ -2795,8 +2792,7 @@ private Document getMappedSortObject(Query query, Class type) { return getMappedSortObject(query.getSortObject(), type); } - @Nullable - private Document getMappedSortObject(Document sortObject, Class type) { + private @Nullable Document getMappedSortObject(Document sortObject, Class type) { if (ObjectUtils.isEmpty(sortObject)) { return null; @@ -3009,7 +3005,7 @@ private static class FindAndReplaceCallback implements ReactiveCollectionCallbac private final Document fields; private final Document sort; private final Document update; - private final @Nullable com.mongodb.client.model.Collation collation; + private final com.mongodb.client.model.@Nullable Collation collation; private final FindAndReplaceOptions options; FindAndReplaceCallback(CollectionPreparer> collectionPreparer, Document query, diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupport.java index 51cd99dc93..60df4fcc30 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupport.java @@ -17,9 +17,9 @@ import reactor.core.publisher.Mono; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.UpdateDefinition; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReadConcernAware.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReadConcernAware.java index 00c5815fc9..7a7e5fdfb2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReadConcernAware.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReadConcernAware.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import com.mongodb.ReadConcern; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReadPreferenceAware.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReadPreferenceAware.java index 74bca9abea..e6f3fc0daf 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReadPreferenceAware.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReadPreferenceAware.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import com.mongodb.ReadPreference; 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 a01760368a..2ec71b415a 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 @@ -17,9 +17,9 @@ import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.script.ExecutableMongoScript; import org.springframework.data.mongodb.core.script.NamedMongoScript; -import org.springframework.lang.Nullable; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SessionCallback.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SessionCallback.java index 55a87ecadf..76a6d525f8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SessionCallback.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SessionCallback.java @@ -15,8 +15,8 @@ */ package org.springframework.data.mongodb.core; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.lang.Nullable; /** * Callback interface for executing operations within a {@link com.mongodb.session.ClientSession}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SessionScoped.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SessionScoped.java index 33ad9d7318..906d682685 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SessionScoped.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SessionScoped.java @@ -17,10 +17,10 @@ import java.util.function.Consumer; -import org.springframework.lang.Nullable; - import com.mongodb.client.ClientSession; +import org.jspecify.annotations.Nullable; + /** * Gateway interface to execute {@link ClientSession} bound operations against MongoDB via a {@link SessionCallback}. *
@@ -42,8 +42,7 @@ public interface SessionScoped { * @param return type. * @return a result object returned by the action. Can be {@literal null}. */ - @Nullable - default T execute(SessionCallback action) { + default @Nullable T execute(SessionCallback action) { return execute(action, session -> {}); } @@ -60,6 +59,5 @@ default T execute(SessionCallback action) { * @param return type. * @return a result object returned by the action. Can be {@literal null}. */ - @Nullable - T execute(SessionCallback action, Consumer doFinally); + @Nullable T execute(SessionCallback action, Consumer doFinally); } 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 84edf13d57..529f912e6c 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 @@ -18,13 +18,13 @@ import reactor.core.publisher.Mono; import org.bson.codecs.configuration.CodecRegistry; +import org.jspecify.annotations.Nullable; import org.springframework.aop.framework.ProxyFactory; 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.data.mongodb.SessionAwareMethodInterceptor; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ViewOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ViewOptions.java index e50e1088cb..a0f5e56034 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ViewOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ViewOptions.java @@ -17,8 +17,8 @@ import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Collation; -import org.springframework.lang.Nullable; /** * Immutable object holding additional options to be applied when creating a MongoDB diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernAware.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernAware.java index d6e4119b20..bdc7de6663 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernAware.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernAware.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import com.mongodb.WriteConcern; 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 8df4171844..a72c656e47 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 @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import com.mongodb.WriteConcern; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java index 0dc1588bf8..debc7c61f3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java @@ -19,8 +19,8 @@ import java.util.LinkedHashMap; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.AddFieldsOperation.AddFieldsOperationBuilder.ValueAppender; -import org.springframework.lang.Nullable; /** * Adds new fields to documents. {@code $addFields} outputs documents that contain all existing fields from the input diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpressionTransformer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpressionTransformer.java index 00db38329f..e33c565d11 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpressionTransformer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpressionTransformer.java @@ -16,12 +16,12 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.AggregationExpressionTransformer.AggregationExpressionTransformationContext; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; import org.springframework.data.mongodb.core.spel.ExpressionNode; import org.springframework.data.mongodb.core.spel.ExpressionTransformationContextSupport; import org.springframework.data.mongodb.core.spel.ExpressionTransformer; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOperationContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOperationContext.java index a49c7e46d5..5027328461 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOperationContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOperationContext.java @@ -21,10 +21,10 @@ import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeanUtils; import org.springframework.data.mongodb.CodecRegistryProvider; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOperationRenderer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOperationRenderer.java index fd5f7ed979..6437ec981d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOperationRenderer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationOperationRenderer.java @@ -19,12 +19,12 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ExposedFields.DirectFieldReference; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; import org.springframework.data.mongodb.core.aggregation.Fields.AggregationField; import org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation; -import org.springframework.lang.Nullable; /** * Rendering support for {@link AggregationOperation} into a {@link List} of {@link org.bson.Document}. 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 327d40b8c7..b9934b5f53 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,11 +19,11 @@ import java.util.Optional; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.ReadConcernAware; import org.springframework.data.mongodb.core.ReadPreferenceAware; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.util.BsonUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.ReadConcern; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationResults.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationResults.java index 438eb9e49f..f5a861cddd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationResults.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationResults.java @@ -20,7 +20,7 @@ import java.util.List; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** @@ -71,8 +71,7 @@ public List getMappedResults() { * @return the single already mapped result object or raise an error if more than one found. * @throws IllegalArgumentException in case more than one result is available. */ - @Nullable - public T getUniqueMappedResult() { + public @Nullable T getUniqueMappedResult() { Assert.isTrue(mappedResults.size() < 2, "Expected unique result or null, but got more than one"); return mappedResults.size() == 1 ? mappedResults.get(0) : null; } @@ -101,8 +100,7 @@ public Document getRawResults() { return rawResults; } - @Nullable - private String parseServerUsed() { + private @Nullable String parseServerUsed() { Object object = rawResults.get("serverUsed"); return object instanceof String stringValue ? stringValue : null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationUpdate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationUpdate.java index 15d700309e..e3471178e6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationUpdate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationUpdate.java @@ -25,11 +25,10 @@ import java.util.stream.Collectors; import org.bson.Document; - +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.SerializationUtils; import org.springframework.data.mongodb.core.query.UpdateDefinition; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationVariable.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationVariable.java index ed79202345..522dd5eae5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationVariable.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationVariable.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core.aggregation; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java index e2c31c6346..2554c328b6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java @@ -20,6 +20,7 @@ import java.util.Locale; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.Avg; import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.CovariancePop; import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.CovarianceSamp; @@ -32,7 +33,6 @@ import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.Sum; import org.springframework.data.mongodb.core.aggregation.SetWindowFieldsOperation.WindowUnit; import org.springframework.data.mongodb.core.aggregation.SetWindowFieldsOperation.WindowUnits; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; 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 41688bfc62..e13626c933 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 @@ -22,12 +22,12 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.domain.Sort; 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; /** 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 323a11895b..699cacacf7 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 @@ -22,12 +22,12 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond.OtherwiseBuilder; 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; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConvertOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConvertOperators.java index aa085b2a29..a8af4f27dc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConvertOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConvertOperators.java @@ -17,8 +17,8 @@ import java.util.Collections; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.schema.JsonSchemaObject.Type; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java index ff6ed7e983..7b1379ed49 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java @@ -26,7 +26,7 @@ import java.util.TimeZone; import java.util.concurrent.TimeUnit; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java index 0da9343ddf..93688d0618 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java @@ -25,7 +25,7 @@ import java.util.stream.Collectors; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFields.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFields.java index 458bc43437..703d5d5f06 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFields.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFields.java @@ -21,8 +21,8 @@ import java.util.Iterator; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CompositeIterator; import org.springframework.util.ObjectUtils; @@ -154,8 +154,7 @@ public ExposedFields and(ExposedField field) { * @param name must not be {@literal null}. * @return can be {@literal null}. */ - @Nullable - public ExposedField getField(String name) { + public @Nullable ExposedField getField(String name) { for (ExposedField field : this) { if (field.canBeReferredToBy(name)) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFieldsAggregationOperationContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFieldsAggregationOperationContext.java index 131fa8a845..1639a54d48 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFieldsAggregationOperationContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFieldsAggregationOperationContext.java @@ -17,11 +17,10 @@ import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; - +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ExposedFields.DirectFieldReference; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -119,8 +118,7 @@ private FieldReference getReference(@Nullable Field field, String name) { * @param name must not be {@literal null}. * @return the resolved reference or {@literal null}. */ - @Nullable - protected FieldReference resolveExposedField(@Nullable Field field, String name) { + protected @Nullable FieldReference resolveExposedField(@Nullable Field field, String name) { ExposedField exposedField = exposedFields.getField(name); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java index 83fc7c2b87..f554a5b78a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java @@ -23,8 +23,8 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.FieldName; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -172,8 +172,7 @@ public int size() { return fields.size(); } - @Nullable - public Field getField(String name) { + public @Nullable Field getField(String name) { for (Field field : fields) { if (field.getName().equals(name)) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java index f4a5fb4498..c2a041deef 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java @@ -19,8 +19,8 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.NearQuery; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; 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 72a917c599..ea6cfe6080 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 @@ -21,10 +21,10 @@ import java.util.Set; import org.bson.Document; +import org.jspecify.annotations.Nullable; 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; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GroupOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GroupOperation.java index 10d58a7682..ef3c76f733 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GroupOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GroupOperation.java @@ -20,10 +20,10 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; import org.springframework.data.mongodb.core.aggregation.ScriptOperators.Accumulator; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/InheritingExposedFieldsAggregationOperationContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/InheritingExposedFieldsAggregationOperationContext.java index ca6a2e2754..739b7c52a9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/InheritingExposedFieldsAggregationOperationContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/InheritingExposedFieldsAggregationOperationContext.java @@ -16,8 +16,8 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; -import org.springframework.lang.Nullable; /** * {@link ExposedFieldsAggregationOperationContext} that inherits fields from its parent diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java index 314f83fc7c..19ce76c6fa 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java @@ -22,10 +22,10 @@ import java.util.stream.Collectors; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; import org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation; import org.springframework.data.mongodb.core.aggregation.VariableOperators.Let; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java index 51520f0868..a46b2fde57 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java @@ -16,8 +16,8 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.util.BsonUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/PrefixingDelegatingAggregationOperationContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/PrefixingDelegatingAggregationOperationContext.java index 9524171fed..54ed40b035 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/PrefixingDelegatingAggregationOperationContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/PrefixingDelegatingAggregationOperationContext.java @@ -25,8 +25,8 @@ import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; -import org.springframework.lang.Nullable; /** * {@link AggregationOperationContext} implementation prefixing non-command keys on root level with the given prefix. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java index 35db2214f5..a3517be20d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java @@ -23,13 +23,13 @@ import java.util.stream.Collectors; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond; import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.IfNull; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.data.mongodb.core.aggregation.Fields.AggregationField; import org.springframework.data.mongodb.core.aggregation.ProjectionOperation.ProjectionOperationBuilder.FieldProjection; import org.springframework.data.mongodb.core.aggregation.VariableOperators.Let.ExpressionVariable; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java index 9eab041e88..9d1f1deeef 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java @@ -22,9 +22,9 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ScriptOperators.Accumulator.AccumulatorBuilder; import org.springframework.data.mongodb.core.aggregation.ScriptOperators.Accumulator.AccumulatorInitBuilder; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java index 7f5c1c7722..0a67cee5fd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java @@ -19,8 +19,8 @@ import java.util.LinkedHashMap; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.SetOperation.FieldAppender.ValueAppender; -import org.springframework.lang.Nullable; /** * Adds new fields to documents. {@code $set} outputs documents that contain all existing fields from the input diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java index 2b8df539e1..55d3ae4cbe 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java @@ -22,8 +22,8 @@ import java.util.concurrent.TimeUnit; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Sort; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -249,8 +249,7 @@ public AggregationExpression getWindowOperator() { return windowOperator; } - @Nullable - public Window getWindow() { + public @Nullable Window getWindow() { return window; } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SortByCountOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SortByCountOperation.java index ffc0aa0654..84160885eb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SortByCountOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SortByCountOperation.java @@ -16,7 +16,7 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformer.java index 3119e2729c..c8c1b9c553 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformer.java @@ -20,6 +20,7 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.core.GenericTypeResolver; import org.springframework.data.mongodb.core.spel.ExpressionNode; import org.springframework.data.mongodb.core.spel.ExpressionTransformationContextSupport; @@ -42,7 +43,6 @@ import org.springframework.expression.spel.standard.SpelExpression; 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.NumberUtils; import org.springframework.util.ObjectUtils; @@ -322,9 +322,8 @@ private static class InlineListNodeConversion extends ExpressionNodeConversion context) { + protected @Nullable Object convert(AggregationExpressionTransformationContext context) { ExpressionNode currentNode = context.getCurrentNode(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SystemVariable.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SystemVariable.java index 1fcf87d2a0..cc0296c900 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SystemVariable.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SystemVariable.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core.aggregation; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Describes the system variables available in MongoDB aggregation framework pipeline expressions. @@ -116,8 +116,7 @@ public String getTarget() { return toString(); } - @Nullable - static String variableNameFrom(@Nullable String fieldRef) { + static @Nullable String variableNameFrom(@Nullable String fieldRef) { if (fieldRef == null || !fieldRef.startsWith(PREFIX) || fieldRef.length() <= 2) { return null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContext.java index f30ebf394b..d2d49abf78 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContext.java @@ -22,7 +22,7 @@ import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; - +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.context.MappingContext; @@ -33,7 +33,6 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnionWithOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnionWithOperation.java index 057ada12d5..c93c1bad9e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnionWithOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnionWithOperation.java @@ -19,7 +19,7 @@ import java.util.List; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** 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 d59ae01b12..918a961cc9 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 @@ -16,8 +16,8 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/VariableOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/VariableOperators.java index 8e676c72bc..bb21d4fc81 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/VariableOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/VariableOperators.java @@ -22,8 +22,8 @@ import java.util.stream.Collectors; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.VariableOperators.Let.ExpressionVariable; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -223,8 +223,7 @@ public static class Let implements AggregationExpression { private final List vars; - @Nullable // - private final AggregationExpression expression; + private final @Nullable AggregationExpression expression; private Let(List vars, @Nullable AggregationExpression expression) { 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 0e30b8b855..2769990ca6 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 @@ -3,6 +3,6 @@ * * @since 1.3 */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.core.aggregation; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/annotation/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/annotation/package-info.java index 3e08dc1014..9ada2014a0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/annotation/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/annotation/package-info.java @@ -1,6 +1,6 @@ /** * Core Spring Data MongoDB annotations not limited to a special use case (like Query,...). */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.core.annotation; 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 7a01677939..9b1c744be2 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 @@ -20,6 +20,7 @@ import org.bson.types.Code; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; @@ -31,7 +32,6 @@ 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; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefProxyHandler.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefProxyHandler.java index 40afbb8c10..3b4dd99d4e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefProxyHandler.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefProxyHandler.java @@ -15,8 +15,8 @@ */ package org.springframework.data.mongodb.core.convert; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; -import org.springframework.lang.Nullable; import com.mongodb.DBRef; 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 0235694030..ee1f568494 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 @@ -18,10 +18,10 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; 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 org.springframework.util.StringUtils; import com.mongodb.DBRef; @@ -60,7 +60,7 @@ Object resolveDbRef(MongoPersistentProperty property, @Nullable DBRef dbref, DbR * @param id will never be {@literal null}. * @return new instance of {@link DBRef}. */ - default DBRef createDbRef(@Nullable org.springframework.data.mongodb.core.mapping.DBRef annotation, + default DBRef createDbRef(org.springframework.data.mongodb.core.mapping.@Nullable DBRef annotation, MongoPersistentEntity entity, Object id) { if (annotation != null && StringUtils.hasText(annotation.db())) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefProxyHandler.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefProxyHandler.java index 22b1ce7981..13c0198aa0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefProxyHandler.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefProxyHandler.java @@ -18,13 +18,12 @@ import java.util.function.Function; import org.bson.Document; - +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.ValueExpressionEvaluator; 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; 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 de66c3ea94..5858f38e6b 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 @@ -25,6 +25,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.MongoDatabaseUtils; @@ -32,7 +33,6 @@ import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java index 2c2b52afd5..07752caa6b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java @@ -23,6 +23,7 @@ import org.bson.Document; import org.bson.conversions.Bson; +import org.jspecify.annotations.Nullable; import org.springframework.data.convert.CustomConversions; import org.springframework.data.convert.DefaultTypeMapper; import org.springframework.data.convert.SimpleTypeInformationMapper; @@ -32,7 +33,6 @@ import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import com.mongodb.BasicDBList; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java index c795add9c8..ff50dd5df3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java @@ -21,11 +21,11 @@ import org.bson.Document; import org.bson.conversions.Bson; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.util.BsonUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.DBObject; @@ -119,8 +119,7 @@ public void put(MongoPersistentProperty prop, @Nullable Object value) { * @param property must not be {@literal null}. * @return can be {@literal null}. */ - @Nullable - public Object get(MongoPersistentProperty property) { + public @Nullable Object get(MongoPersistentProperty property) { return BsonUtils.resolveValue(document, getFieldName(property)); } @@ -131,8 +130,7 @@ public Object get(MongoPersistentProperty property) { * @param entity must not be {@literal null}. * @return */ - @Nullable - public Object getRawId(MongoPersistentEntity entity) { + public @Nullable Object getRawId(MongoPersistentEntity entity) { return entity.hasIdProperty() ? get(entity.getRequiredIdProperty()) : BsonUtils.get(document, FieldName.ID.name()); } 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 ea5ce01b44..a41e17c0ec 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 @@ -18,11 +18,11 @@ import java.util.Map; import org.bson.Document; +import org.jspecify.annotations.Nullable; 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. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java index bf21781058..ed8530d0c5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core.convert; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * The source object to resolve document references upon. Encapsulates the actual source and the reference specific @@ -56,8 +56,7 @@ public Object getSelf() { * * @return can be {@literal null}. */ - @Nullable - public Object getTargetSource() { + public @Nullable Object getTargetSource() { return targetSource; } @@ -67,8 +66,7 @@ public Object getTargetSource() { * @param source * @return */ - @Nullable - static Object getTargetSource(Object source) { + static @Nullable Object getTargetSource(Object source) { return source instanceof DocumentReferenceSource referenceSource ? referenceSource.getTargetSource() : source; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxy.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxy.java index 77aac55813..6329d74d4f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxy.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxy.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core.convert; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import com.mongodb.DBRef; @@ -53,8 +53,7 @@ public interface LazyLoadingProxy { * @return can be {@literal null}. * @since 3.3 */ - @Nullable - default Object getSource() { + default @Nullable Object getSource() { return toDBRef(); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java index 76539ea431..bb5f582468 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java @@ -30,6 +30,7 @@ import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.Nullable; import org.springframework.aop.framework.ProxyFactory; import org.springframework.cglib.core.SpringNamingPolicy; import org.springframework.cglib.proxy.Callback; @@ -43,7 +44,6 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.util.Lock; import org.springframework.data.util.Lock.AcquiredLock; -import org.springframework.lang.Nullable; import org.springframework.objenesis.SpringObjenesis; import org.springframework.util.ReflectionUtils; @@ -194,15 +194,13 @@ public static class LazyLoadingInterceptor public static LazyLoadingInterceptor none() { return new LazyLoadingInterceptor(null, null, null, null) { - @Nullable @Override - public Object invoke(MethodInvocation invocation) throws Throwable { + public @Nullable Object invoke(MethodInvocation invocation) throws Throwable { return intercept(invocation.getThis(), invocation.getMethod(), invocation.getArguments(), null); } - @Nullable @Override - public Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable { + public @Nullable Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable { ReflectionUtils.makeAccessible(method); return method.invoke(o, args); @@ -219,15 +217,13 @@ public LazyLoadingInterceptor(MongoPersistentProperty property, DbRefResolverCal this.exceptionTranslator = exceptionTranslator; } - @Nullable @Override - public Object invoke(MethodInvocation invocation) throws Throwable { + public @Nullable Object invoke(MethodInvocation invocation) throws Throwable { return intercept(invocation.getThis(), invocation.getMethod(), invocation.getArguments(), null); } - @Nullable @Override - public Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable { + public @Nullable Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable { if (INITIALIZE_METHOD.equals(method)) { return ensureResolved(); @@ -347,8 +343,7 @@ private void readObject(ObjectInputStream in) throws IOException { } } - @Nullable - private Object resolve() { + private @Nullable Object resolve() { try (AcquiredLock l = readLock.lock()) { if (resolved) { 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 1d40573b81..e729ab8df3 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 @@ -39,7 +39,7 @@ import org.bson.conversions.Bson; import org.bson.json.JsonReader; import org.bson.types.ObjectId; - +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.context.ApplicationContext; @@ -94,7 +94,6 @@ import org.springframework.data.util.Predicates; import org.springframework.data.util.TypeInformation; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -599,8 +598,7 @@ private S populateProperties(ConversionContext context, MongoPersistentEntit * Reads the identifier from either the bean backing the {@link PersistentPropertyAccessor} or the source document in * case the identifier has not be populated yet. In this case the identifier is set on the bean for further reference. */ - @Nullable - private Object readAndPopulateIdentifier(ConversionContext context, PersistentPropertyAccessor accessor, + private @Nullable Object readAndPopulateIdentifier(ConversionContext context, PersistentPropertyAccessor accessor, DocumentAccessor document, MongoPersistentEntity entity, ValueExpressionEvaluator evaluator) { Object rawId = document.getRawId(entity); @@ -684,8 +682,7 @@ private DbRefResolverCallback getDbRefResolverCallback(ConversionContext context (prop, bson, e, path) -> MappingMongoConverter.this.getValueInternal(context, prop, bson, e)); } - @Nullable - private Object readAssociation(Association association, DocumentAccessor documentAccessor, + private @Nullable Object readAssociation(Association association, DocumentAccessor documentAccessor, DbRefProxyHandler handler, DbRefResolverCallback callback, ConversionContext context) { MongoPersistentProperty property = association.getInverse(); @@ -1332,15 +1329,13 @@ private void writeSimpleInternal(@Nullable Object value, Bson bson, MongoPersist property.hasExplicitWriteTarget() ? property.getFieldType() : Object.class)); } - @Nullable @SuppressWarnings("unchecked") - private Object applyPropertyConversion(@Nullable Object value, MongoPersistentProperty property, + private @Nullable Object applyPropertyConversion(@Nullable Object value, MongoPersistentProperty property, PersistentPropertyAccessor persistentPropertyAccessor) { MongoConversionContext context = new MongoConversionContext(new PropertyValueProvider<>() { - @Nullable @Override - public T getPropertyValue(MongoPersistentProperty property) { + public @Nullable T getPropertyValue(MongoPersistentProperty property) { return (T) persistentPropertyAccessor.getProperty(property); } }, property, this, spELContext); @@ -1455,8 +1450,7 @@ protected DBRef createDBRef(Object target, @Nullable MongoPersistentProperty pro throw new MappingException("No id property found on class " + entity.getType()); } - @Nullable - private Object getValueInternal(ConversionContext context, MongoPersistentProperty prop, Bson bson, + private @Nullable Object getValueInternal(ConversionContext context, MongoPersistentProperty prop, Bson bson, ValueExpressionEvaluator evaluator) { return new MongoDbPropertyValueProvider(context, bson, evaluator).getPropertyValue(prop); } @@ -1714,9 +1708,8 @@ private Object removeTypeInfo(Object object, boolean recursively) { return document; } - @Nullable @SuppressWarnings("unchecked") - T readValue(ConversionContext context, @Nullable Object value, TypeInformation type) { + @Nullable T readValue(ConversionContext context, @Nullable Object value, TypeInformation type) { if (value == null) { return null; @@ -1735,8 +1728,7 @@ T readValue(ConversionContext context, @Nullable Object value, TypeInformati return (T) context.convert(value, type); } - @Nullable - private Object readDBRef(ConversionContext context, @Nullable DBRef dbref, TypeInformation type) { + private @Nullable Object readDBRef(ConversionContext context, @Nullable DBRef dbref, TypeInformation type) { if (type.getType().equals(DBRef.class)) { return dbref; @@ -1971,9 +1963,8 @@ static class MongoDbPropertyValueProvider implements PropertyValueProvider T getPropertyValue(MongoPersistentProperty property) { + public @Nullable T getPropertyValue(MongoPersistentProperty property) { String expression = property.getSpelExpression(); Object value = expression != null ? evaluator.evaluate(expression) : accessor.get(property); @@ -2279,8 +2270,7 @@ default ConversionContext forProperty(MongoPersistentProperty property) { * @return * @param */ - @Nullable - default S findContextualEntity(MongoPersistentEntity entity, Document document) { + default @Nullable S findContextualEntity(MongoPersistentEntity entity, Document document) { return null; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConversionContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConversionContext.java index 5fde0acddd..8deb2bbc89 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConversionContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConversionContext.java @@ -16,13 +16,12 @@ package org.springframework.data.mongodb.core.convert; import org.bson.conversions.Bson; - +import org.jspecify.annotations.Nullable; import org.springframework.data.convert.ValueConversionContext; import org.springframework.data.mapping.model.PropertyValueProvider; import org.springframework.data.mapping.model.SpELContext; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; /** * {@link ValueConversionContext} that allows to delegate read/write to an underlying {@link MongoConverter}. @@ -63,8 +62,7 @@ public MongoPersistentProperty getProperty() { return persistentProperty; } - @Nullable - public Object getValue(String propertyPath) { + public @Nullable Object getValue(String propertyPath) { return accessor.getPropertyValue(getProperty().getOwner().getRequiredPersistentProperty(propertyPath)); } @@ -80,8 +78,7 @@ public T read(@Nullable Object value, TypeInformation target) { : ValueConversionContext.super.read(value, target); } - @Nullable - public SpELContext getSpELContext() { + public @Nullable SpELContext getSpELContext() { return spELContext; } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverter.java index 3676e74c8b..658ea5cfdb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverter.java @@ -21,6 +21,7 @@ import org.bson.codecs.configuration.CodecRegistry; import org.bson.conversions.Bson; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.ConversionException; import org.springframework.data.convert.CustomConversions; import org.springframework.data.convert.EntityConverter; @@ -33,7 +34,6 @@ import org.springframework.data.projection.EntityProjection; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -102,8 +102,7 @@ public interface MongoConverter * @since 2.1 */ @SuppressWarnings("unchecked") - @Nullable - default T mapValueToTargetType(S source, Class targetType, DbRefResolver dbRefResolver) { + default @Nullable T mapValueToTargetType(S source, Class targetType, DbRefResolver dbRefResolver) { Assert.notNull(targetType, "TargetType must not be null"); Assert.notNull(dbRefResolver, "DbRefResolver must not be null"); 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 050c3bd27d..964ecb6b65 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 @@ -32,6 +32,7 @@ import java.util.Set; import java.util.function.Consumer; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; @@ -51,7 +52,6 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoJsonSchemaMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoJsonSchemaMapper.java index 8d199083e7..a5d329045e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoJsonSchemaMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoJsonSchemaMapper.java @@ -21,12 +21,12 @@ import java.util.stream.Collectors; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.schema.JsonSchemaObject.Type; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** 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 867a6213d2..12aaf24cd9 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 @@ -16,12 +16,12 @@ package org.springframework.data.mongodb.core.convert; import org.bson.conversions.Bson; +import org.jspecify.annotations.Nullable; import org.springframework.data.convert.EntityWriter; import org.springframework.data.mongodb.core.mapping.DocumentPointer; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import com.mongodb.DBRef; @@ -43,8 +43,7 @@ public interface MongoWriter extends EntityWriter { * @param obj can be {@literal null}. * @return */ - @Nullable - default Object convertToMongoType(@Nullable Object obj) { + default @Nullable Object convertToMongoType(@Nullable Object obj) { return convertToMongoType(obj, (TypeInformation) null); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/NoOpDbRefResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/NoOpDbRefResolver.java index 265257af5c..68578f32b9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/NoOpDbRefResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/NoOpDbRefResolver.java @@ -18,9 +18,8 @@ import java.util.List; import org.bson.Document; - +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; -import org.springframework.lang.Nullable; import com.mongodb.DBRef; @@ -37,16 +36,14 @@ public enum NoOpDbRefResolver implements DbRefResolver { INSTANCE; @Override - @Nullable - public Object resolveDbRef(MongoPersistentProperty property, @Nullable DBRef dbref, DbRefResolverCallback callback, + public @Nullable Object resolveDbRef(MongoPersistentProperty property, @Nullable DBRef dbref, DbRefResolverCallback callback, DbRefProxyHandler proxyHandler) { return handle(); } @Override - @Nullable - public Document fetch(DBRef dbRef) { + public @Nullable Document fetch(DBRef dbRef) { return handle(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ObjectPath.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ObjectPath.java index 5fefd472c4..d5f034eb1d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ObjectPath.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ObjectPath.java @@ -18,9 +18,9 @@ import java.util.ArrayList; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -99,8 +99,7 @@ ObjectPath push(Object object, MongoPersistentEntity entity, @Nullable Object * @return {@literal null} when no match found. * @since 2.0 */ - @Nullable - T getPathItem(Object id, String collection, Class type) { + @Nullable T getPathItem(Object id, String collection, Class type) { Assert.notNull(id, "Id must not be null"); Assert.hasText(collection, "Collection name must not be null"); @@ -133,13 +132,11 @@ Object getCurrentObject() { return getObject(); } - @Nullable - private Object getObject() { + private @Nullable Object getObject() { return object; } - @Nullable - private Object getIdValue() { + private @Nullable Object getIdValue() { return idValue; } 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 cce809adc6..27583a2e50 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 @@ -37,7 +37,7 @@ import org.bson.Document; import org.bson.conversions.Bson; import org.bson.types.ObjectId; - +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.converter.Converter; import org.springframework.data.annotation.Reference; @@ -66,7 +66,6 @@ import org.springframework.data.mongodb.util.BsonUtils; import org.springframework.data.mongodb.util.DotPath; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -452,9 +451,8 @@ protected Document getMappedKeyword(Field property, Keyword keyword) { * @param sourceValue the source object to be mapped * @return */ - @Nullable @SuppressWarnings("unchecked") - protected Object getMappedValue(Field documentField, Object sourceValue) { + protected @Nullable Object getMappedValue(Field documentField, Object sourceValue) { Object value = applyFieldTargetTypeHintToValue(documentField, sourceValue); @@ -540,8 +538,7 @@ protected boolean isAssociationConversionNecessary(Field documentField, @Nullabl * @param entity * @return */ - @Nullable - protected Object convertSimpleOrDocument(Object source, @Nullable MongoPersistentEntity entity) { + protected @Nullable Object convertSimpleOrDocument(Object source, @Nullable MongoPersistentEntity entity) { if (source instanceof Example example) { return exampleMapper.getMappedExample(example, entity); @@ -601,8 +598,7 @@ protected Object convertSimpleOrDocument(Object source, @Nullable MongoPersisten * @param entity * @return the converted mongo type or null if source is null */ - @Nullable - protected Object delegateConvertToMongoType(Object source, @Nullable MongoPersistentEntity entity) { + protected @Nullable Object delegateConvertToMongoType(Object source, @Nullable MongoPersistentEntity entity) { if (entity != null && entity.isUnwrapped()) { return converter.convertToMongoType(source, entity); @@ -611,8 +607,7 @@ protected Object delegateConvertToMongoType(Object source, @Nullable MongoPersis return converter.convertToMongoType(source, entity == null ? null : entity.getTypeInformation()); } - @Nullable - protected Object convertAssociation(Object source, Field field) { + protected @Nullable Object convertAssociation(Object source, Field field) { Object value = convertAssociation(source, field.getProperty()); if (value != null && field.isIdField() && field.getFieldType() != value.getClass()) { return convertId(value, field.getFieldType()); @@ -665,8 +660,7 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers return createReferenceFor(source, property); } - @Nullable - private Object convertValue(Field documentField, Object sourceValue, Object value, + private @Nullable Object convertValue(Field documentField, Object sourceValue, Object value, PropertyValueConverter> valueConverter) { MongoPersistentProperty property = documentField.getProperty(); @@ -807,8 +801,7 @@ private Object createReferenceFor(Object source, MongoPersistentProperty propert * @return * @since 2.2 */ - @Nullable - public Object convertId(@Nullable Object id) { + public @Nullable Object convertId(@Nullable Object id) { return convertId(id, ObjectId.class); } @@ -820,8 +813,7 @@ public Object convertId(@Nullable Object id) { * @return the converted {@literal id} or {@literal null} if the source was already {@literal null}. * @since 2.2 */ - @Nullable - public Object convertId(@Nullable Object id, Class targetType) { + public @Nullable Object convertId(@Nullable Object id, Class targetType) { if (Quirks.skipConversion(id)) { return id; @@ -884,8 +876,7 @@ protected boolean isKeyword(String candidate) { * @param value the actual value. Can be {@literal null}. * @return the potentially converted target value. */ - @Nullable - private Object applyFieldTargetTypeHintToValue(Field documentField, @Nullable Object value) { + private @Nullable Object applyFieldTargetTypeHintToValue(Field documentField, @Nullable Object value) { if (value == null || documentField.getProperty() == null || !documentField.getProperty().hasExplicitWriteTarget() || value instanceof Document || value instanceof DBObject || Quirks.skipConversion(value)) { @@ -1053,8 +1044,7 @@ public boolean isIdField() { * * @return can be {@literal null}. */ - @Nullable - public MongoPersistentProperty getProperty() { + public @Nullable MongoPersistentProperty getProperty() { return null; } @@ -1063,8 +1053,7 @@ public MongoPersistentProperty getProperty() { * * @return can be {@literal null}. */ - @Nullable - public MongoPersistentEntity getPropertyEntity() { + public @Nullable MongoPersistentEntity getPropertyEntity() { return null; } @@ -1100,8 +1089,7 @@ public boolean containsAssociation() { return false; } - @Nullable - public Association getAssociation() { + public @Nullable Association getAssociation() { return null; } @@ -1212,9 +1200,8 @@ public MongoPersistentEntity getPropertyEntity() { return property == null ? null : mappingContext.getPersistentEntity(property); } - @Nullable @Override - public MongoPersistentEntity getEntity() { + public @Nullable MongoPersistentEntity getEntity() { return entity; } @@ -1265,8 +1252,7 @@ public String getMappedKey() { return path == null ? name : path.toDotPath(isAssociation() ? getAssociationConverter() : getPropertyConverter()); } - @Nullable - protected PersistentPropertyPath getPath() { + protected @Nullable PersistentPropertyPath getPath() { return path; } @@ -1276,8 +1262,7 @@ protected PersistentPropertyPath getPath() { * @param pathExpression * @return */ - @Nullable - private PersistentPropertyPath getPath(String pathExpression, + private @Nullable PersistentPropertyPath getPath(String pathExpression, @Nullable MongoPersistentProperty sourceProperty) { if (sourceProperty != null && sourceProperty.getOwner().equals(entity)) { @@ -1327,8 +1312,7 @@ private PersistentPropertyPath getPath(String pathExpre return propertyPath; } - @Nullable - private PersistentPropertyPath tryToResolvePersistentPropertyPath(PropertyPath path) { + private @Nullable PersistentPropertyPath tryToResolvePersistentPropertyPath(PropertyPath path) { try { return mappingContext.getPersistentPropertyPath(path); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLoader.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLoader.java index 5a1adf9114..cd7d55311d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLoader.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLoader.java @@ -20,9 +20,9 @@ import org.bson.Document; import org.bson.conversions.Bson; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.convert.ReferenceResolver.ReferenceCollection; import org.springframework.data.mongodb.core.mapping.FieldName; -import org.springframework.lang.Nullable; import com.mongodb.client.MongoCollection; @@ -42,8 +42,7 @@ public interface ReferenceLoader { * @param context must not be {@literal null}. * @return the matching {@link Document} or {@literal null} if none found. */ - @Nullable - default Document fetchOne(DocumentReferenceQuery referenceQuery, ReferenceCollection context) { + default @Nullable Document fetchOne(DocumentReferenceQuery referenceQuery, ReferenceCollection context) { Iterator it = fetchMany(referenceQuery, context).iterator(); return it.hasNext() ? it.next() : null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java index b912cfb540..b686fa7d5e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java @@ -31,6 +31,7 @@ import org.bson.Document; import org.bson.conversions.Bson; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.SpELContext; import org.springframework.data.mongodb.core.convert.ReferenceLoader.DocumentReferenceQuery; @@ -47,7 +48,6 @@ import org.springframework.data.mongodb.util.spel.ExpressionUtils; import org.springframework.data.util.Streamable; import org.springframework.expression.EvaluationContext; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -98,8 +98,7 @@ public ReferenceLookupDelegate( * {@literal null}. * @return can be {@literal null}. */ - @Nullable - public Object readReference(MongoPersistentProperty property, Object source, LookupFunction lookupFunction, + public @Nullable Object readReference(MongoPersistentProperty property, Object source, LookupFunction lookupFunction, MongoEntityReader entityReader) { Object value = source instanceof DocumentReferenceSource documentReferenceSource diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceResolver.java index 715327d18e..0698b08bf8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceResolver.java @@ -15,11 +15,11 @@ */ package org.springframework.data.mongodb.core.convert; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.DBRef; @@ -54,8 +54,7 @@ Object resolveReference(MongoPersistentProperty property, Object source, */ class ReferenceCollection { - @Nullable // - private final String database; + private final @Nullable String database; private final String collection; /** @@ -95,8 +94,7 @@ public String getCollection() { * * @return can be {@literal null}. */ - @Nullable - public String getDatabase() { + public @Nullable String getDatabase() { return database; } } 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 35cb578c23..c0253c2d70 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 @@ -23,6 +23,7 @@ import org.bson.Document; import org.bson.conversions.Bson; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; @@ -34,7 +35,6 @@ import org.springframework.data.mongodb.core.query.Update.Modifier; import org.springframework.data.mongodb.core.query.Update.Modifiers; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ValueResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ValueResolver.java index 0a96cc867a..8eed053a09 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ValueResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ValueResolver.java @@ -17,10 +17,9 @@ import org.bson.Document; import org.bson.conversions.Bson; - +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.model.ValueExpressionEvaluator; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; -import org.springframework.lang.Nullable; /** * Internal API to trigger the resolution of properties. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java index f8d814fee4..fc2d38afc3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java @@ -15,12 +15,12 @@ */ package org.springframework.data.mongodb.core.convert.encryption; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.convert.MongoConversionContext; import org.springframework.data.mongodb.core.encryption.EncryptionContext; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.util.TypeInformation; import org.springframework.expression.EvaluationContext; -import org.springframework.lang.Nullable; /** * Default {@link EncryptionContext} implementation. @@ -41,9 +41,8 @@ public MongoPersistentProperty getProperty() { return conversionContext.getProperty(); } - @Nullable @Override - public Object lookupValue(String path) { + public @Nullable Object lookupValue(String path) { return conversionContext.getValue(path); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java index 1ce24b25fe..e7b427fcf2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java @@ -27,6 +27,7 @@ import org.bson.BsonValue; import org.bson.Document; import org.bson.types.Binary; +import org.jspecify.annotations.Nullable; import org.springframework.core.CollectionFactory; import org.springframework.data.mongodb.core.convert.MongoConversionContext; import org.springframework.data.mongodb.core.encryption.Encryption; @@ -36,7 +37,6 @@ import org.springframework.data.mongodb.core.mapping.Encrypted; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.util.BsonUtils; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** @@ -59,9 +59,8 @@ public MongoEncryptionConverter(Encryption encryption, En this.keyResolver = keyResolver; } - @Nullable @Override - public Object read(Object value, MongoConversionContext context) { + public @Nullable Object read(Object value, MongoConversionContext context) { Object decrypted = EncryptingConverter.super.read(value, context); return decrypted instanceof BsonValue bsonValue ? BsonUtils.toJavaType(bsonValue) : decrypted; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/package-info.java index 4a6f78357a..a0e8ea27f7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/package-info.java @@ -3,5 +3,5 @@ * explicit encryption * mechanism of Client-Side Field Level Encryption. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.core.convert.encryption; 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 cfa07fa8f9..dbef5cbb90 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,6 +1,6 @@ /** * Spring Data MongoDB specific converter infrastructure. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.core.convert; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java index 89beaadedb..f2461d9df6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java @@ -15,11 +15,11 @@ */ package org.springframework.data.mongodb.core.encryption; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.util.TypeInformation; import org.springframework.expression.EvaluationContext; -import org.springframework.lang.Nullable; /** * Context to encapsulate encryption for a specific {@link MongoPersistentProperty}. @@ -88,8 +88,7 @@ default T read(@Nullable Object value, Class target) { * @see PersistentProperty#getTypeInformation() * @see #write(Object, TypeInformation) */ - @Nullable - default T write(@Nullable Object value) { + default @Nullable T write(@Nullable Object value) { return (T) write(value, getProperty().getTypeInformation()); } @@ -101,8 +100,7 @@ default T write(@Nullable Object value) { * @return can be {@literal null}. * @throws IllegalStateException if value cannot be written as an instance of {@link Class type}. */ - @Nullable - default T write(@Nullable Object value, Class target) { + default @Nullable T write(@Nullable Object value, Class target) { return write(value, TypeInformation.of(target)); } @@ -114,8 +112,7 @@ default T write(@Nullable Object value, Class target) { * @return can be {@literal null}. * @throws IllegalStateException if value cannot be written as an instance of {@link Class type}. */ - @Nullable - T write(@Nullable Object value, TypeInformation target); + @Nullable T write(@Nullable Object value, TypeInformation target); /** * Lookup the value for a given path within the current context. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/package-info.java index f3906d89dd..90a3ab8720 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/package-info.java @@ -2,5 +2,5 @@ * Infrastructure for explicit * encryption mechanism of Client-Side Field Level Encryption. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.core.encryption; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonGeometryCollection.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonGeometryCollection.java index 2372700aec..74f36e3198 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonGeometryCollection.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonGeometryCollection.java @@ -19,7 +19,7 @@ import java.util.Collections; import java.util.List; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; 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 bc74a56df3..9f1567c0ec 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 @@ -19,9 +19,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; - +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.Version; @@ -139,9 +138,8 @@ private static void registerDeserializersIn(SimpleModule module) { */ private static abstract class GeoJsonDeserializer> extends JsonDeserializer { - @Nullable @Override - public T deserialize(@Nullable JsonParser jp, @Nullable DeserializationContext ctxt) throws IOException { + public @Nullable T deserialize(@Nullable JsonParser jp, @Nullable DeserializationContext ctxt) throws IOException { JsonNode node = jp.readValueAsTree(); JsonNode coordinates = node.get("coordinates"); @@ -158,8 +156,7 @@ public T deserialize(@Nullable JsonParser jp, @Nullable DeserializationContext c * @param coordinates * @return */ - @Nullable - protected abstract T doDeserialize(ArrayNode coordinates); + protected abstract @Nullable T doDeserialize(ArrayNode coordinates); /** * Get the {@link GeoJsonPoint} representation of given {@link ArrayNode} assuming {@code node.[0]} represents @@ -168,8 +165,7 @@ public T deserialize(@Nullable JsonParser jp, @Nullable DeserializationContext c * @param node can be {@literal null}. * @return {@literal null} when given a {@code null} value. */ - @Nullable - protected GeoJsonPoint toGeoJsonPoint(@Nullable ArrayNode node) { + protected @Nullable GeoJsonPoint toGeoJsonPoint(@Nullable ArrayNode node) { if (node == null) { return null; @@ -185,8 +181,7 @@ protected GeoJsonPoint toGeoJsonPoint(@Nullable ArrayNode node) { * @param node can be {@literal null}. * @return {@literal null} when given a {@code null} value. */ - @Nullable - protected Point toPoint(@Nullable ArrayNode node) { + protected @Nullable Point toPoint(@Nullable ArrayNode node) { if (node == null) { return null; @@ -236,9 +231,8 @@ protected GeoJsonLineString toLineString(ArrayNode node) { */ private static class GeoJsonPointDeserializer extends GeoJsonDeserializer { - @Nullable @Override - protected GeoJsonPoint doDeserialize(ArrayNode coordinates) { + protected @Nullable GeoJsonPoint doDeserialize(ArrayNode coordinates) { return toGeoJsonPoint(coordinates); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiLineString.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiLineString.java index 8dafe9ea00..833a1dd9f6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiLineString.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiLineString.java @@ -19,8 +19,8 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiPoint.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiPoint.java index bcb4c3e79e..e30ed5d6ed 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiPoint.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiPoint.java @@ -20,8 +20,8 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiPolygon.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiPolygon.java index 12b9de9da4..a7e6306b49 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiPolygon.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonMultiPolygon.java @@ -19,7 +19,7 @@ import java.util.Collections; import java.util.List; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonPolygon.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonPolygon.java index 166a10df08..ad3300ee1c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonPolygon.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonPolygon.java @@ -21,9 +21,9 @@ import java.util.Iterator; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; import org.springframework.data.geo.Polygon; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/Sphere.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/Sphere.java index a482c136e7..47be645869 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/Sphere.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/Sphere.java @@ -18,12 +18,12 @@ import java.util.Arrays; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; import org.springframework.data.geo.Point; import org.springframework.data.geo.Shape; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** 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 6cc77f832b..e5adfb26f4 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 @@ -1,6 +1,6 @@ /** * Support for MongoDB geo-spatial queries. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked 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 0949506195..55ead9de14 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 @@ -18,9 +18,9 @@ import java.util.Optional; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.util.MongoClientVersion; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; 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 95f4226e28..66d2eccb66 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 @@ -23,10 +23,10 @@ import java.util.concurrent.TimeUnit; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.mongodb.core.index.IndexOptions.Unique; import org.springframework.data.mongodb.core.query.Collation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexField.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexField.java index a5cbf6c896..2e7268699c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexField.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexField.java @@ -15,8 +15,8 @@ */ package org.springframework.data.mongodb.core.index; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Sort.Direction; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -139,8 +139,7 @@ public String getKey() { * * @return the direction */ - @Nullable - public Direction getDirection() { + public @Nullable Direction getDirection() { return direction; } 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 de7153bfb5..3ea9edc36b 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 @@ -27,8 +27,8 @@ import java.util.stream.Collectors; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.util.BsonUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.NumberUtils; import org.springframework.util.ObjectUtils; @@ -161,8 +161,7 @@ public static IndexInfo indexInfoOf(Document sourceDocument) { * @return the {@link String} representation of the partial filter {@link Document}. * @since 2.1.11 */ - @Nullable - private static String extractPartialFilterString(Document sourceDocument) { + private static @Nullable String extractPartialFilterString(Document sourceDocument) { if (!sourceDocument.containsKey("partialFilterExpression")) { return null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexOperationsProvider.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexOperationsProvider.java index ca3d951c94..aec1ba817d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexOperationsProvider.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexOperationsProvider.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core.index; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Provider interface to obtain {@link IndexOperations} by MongoDB collection name or entity type. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexOptions.java index 887542cb0c..a390d1eb3e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexOptions.java @@ -18,7 +18,7 @@ import java.time.Duration; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Changeable properties of an index. Can be used for index creation and modification. @@ -28,14 +28,11 @@ */ public class IndexOptions { - @Nullable - private Duration expire; + private @Nullable Duration expire; - @Nullable - private Boolean hidden; + private @Nullable Boolean hidden; - @Nullable - private Unique unique; + private @Nullable Unique unique; public enum Unique { @@ -108,8 +105,7 @@ public void setExpire(Duration expire) { /** * @return {@literal true} if hidden, {@literal null} if not set. */ - @Nullable - public Boolean isHidden() { + public @Nullable Boolean isHidden() { return hidden; } @@ -123,8 +119,7 @@ public void setHidden(boolean hidden) { /** * @return the unique property value, {@literal null} if not set. */ - @Nullable - public Unique getUnique() { + public @Nullable Unique getUnique() { return unique; } 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 362247725f..3bb3fdbd0f 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 @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core.index; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * @author Jon Brisbin @@ -26,8 +26,7 @@ public abstract class IndexPredicate { private IndexDirection direction = IndexDirection.ASCENDING; private boolean unique = false; - @Nullable - public String getName() { + public @Nullable String getName() { return name; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java index e20b0704cc..f1550d1501 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java @@ -21,7 +21,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jspecify.annotations.Nullable; import org.springframework.context.ApplicationListener; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.mapping.PersistentEntity; @@ -33,7 +33,6 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.util.MongoDbErrorCodes; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -183,8 +182,7 @@ public boolean isIndexCreatorFor(MappingContext context) { return this.mappingContext.equals(context); } - @Nullable - private IndexInfo fetchIndexInformation(@Nullable IndexDefinitionHolder indexDefinition) { + private @Nullable IndexInfo fetchIndexInformation(@Nullable IndexDefinitionHolder indexDefinition) { if (indexDefinition == null) { return null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java index a5988b8c1d..05a96a7a1b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java @@ -33,6 +33,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.Nullable; import org.springframework.core.annotation.MergedAnnotation; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Sort; @@ -61,7 +62,6 @@ import org.springframework.data.util.TypeInformation; import org.springframework.expression.EvaluationContext; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -520,8 +520,7 @@ private org.bson.Document resolveCompoundIndexKeyFromStringDefinition(String dot * @param persistentProperty * @return */ - @Nullable - protected IndexDefinitionHolder createIndexDefinition(String dotPath, String collection, + protected @Nullable IndexDefinitionHolder createIndexDefinition(String dotPath, String collection, MongoPersistentProperty persistentProperty) { Indexed index = persistentProperty.findAnnotation(Indexed.class); @@ -692,8 +691,7 @@ public void setEvaluationContextProvider(EvaluationContextProvider evaluationCon * @param persistentProperty * @return */ - @Nullable - protected IndexDefinitionHolder createGeoSpatialIndexDefinition(String dotPath, String collection, + protected @Nullable IndexDefinitionHolder createGeoSpatialIndexDefinition(String dotPath, String collection, MongoPersistentProperty persistentProperty) { GeoSpatialIndexed index = persistentProperty.findAnnotation(GeoSpatialIndexed.class); @@ -812,8 +810,7 @@ private static Duration computeIndexTimeout(String timeoutValue, Supplier entity) { + private @Nullable Collation resolveCollation(Annotation annotation, @Nullable PersistentEntity entity) { return MergedAnnotation.from(annotation).getValue("collation", String.class).filter(StringUtils::hasText) .map(it -> evaluateCollation(it, entity)).orElseGet(() -> { @@ -1138,8 +1135,7 @@ public IncludeStrategy getStrategy() { return strategy; } - @Nullable - public TextIndexedFieldSpec getParentFieldSpec() { + public @Nullable TextIndexedFieldSpec getParentFieldSpec() { return parentFieldSpec; } 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 a87b15de45..f8d24414f7 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 @@ -20,9 +20,9 @@ import java.util.Set; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.mongodb.core.query.Collation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/WildcardIndex.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/WildcardIndex.java index dcd2b7c022..3780798b01 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/WildcardIndex.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/WildcardIndex.java @@ -21,8 +21,8 @@ import java.util.concurrent.TimeUnit; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.FieldName; -import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; 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 c49f501d8d..8524ee62f7 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,6 +1,6 @@ /** * Support for MongoDB document indexing. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked 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 3d68dbaac2..6e888c7c9f 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 @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.data.annotation.Id; import org.springframework.data.expression.ValueEvaluationContext; import org.springframework.data.expression.ValueExpression; @@ -42,7 +43,6 @@ import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -139,9 +139,8 @@ public String getLanguage() { return this.language; } - @Nullable @Override - public MongoPersistentProperty getTextScoreProperty() { + public @Nullable MongoPersistentProperty getTextScoreProperty() { return getPersistentProperty(TextScore.class); } @@ -308,8 +307,7 @@ protected MongoPersistentProperty returnPropertyIfBetterIdPropertyCandidateOrNul * @param potentialExpression can be {@literal null} * @return can be {@literal null}. */ - @Nullable - private static ValueExpression detectExpression(@Nullable String potentialExpression) { + private static @Nullable ValueExpression detectExpression(@Nullable String potentialExpression) { if (!StringUtils.hasText(potentialExpression)) { return null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java index 5c3b4e6532..079f571880 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java @@ -23,7 +23,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jspecify.annotations.Nullable; import org.springframework.core.env.StandardEnvironment; import org.springframework.data.expression.ValueEvaluationContext; import org.springframework.data.mapping.Association; @@ -39,7 +39,6 @@ import org.springframework.data.util.Lazy; import org.springframework.expression.EvaluationContext; import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -153,8 +152,7 @@ public boolean hasExplicitFieldName() { return StringUtils.hasText(getAnnotatedFieldName()); } - @Nullable - private String getAnnotatedFieldName() { + private @Nullable String getAnnotatedFieldName() { org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation( org.springframework.data.mongodb.core.mapping.Field.class); @@ -197,9 +195,8 @@ public DBRef getDBRef() { return findAnnotation(DBRef.class); } - @Nullable @Override - public DocumentReference getDocumentReference() { + public @Nullable DocumentReference getDocumentReference() { return findAnnotation(DocumentReference.class); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/CachingMongoPersistentProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/CachingMongoPersistentProperty.java index 105c38b288..be31e2334f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/CachingMongoPersistentProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/CachingMongoPersistentProperty.java @@ -15,11 +15,11 @@ */ package org.springframework.data.mongodb.core.mapping; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.model.FieldNamingStrategy; import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; /** * {@link MongoPersistentProperty} caching access to {@link #isIdProperty()} and {@link #getFieldName()}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java index 76c0269861..4540493124 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java @@ -17,6 +17,7 @@ import java.util.AbstractMap; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -28,7 +29,6 @@ import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.NullableWrapperConverters; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; /** * Default implementation of a {@link MappingContext} for MongoDB using {@link BasicMongoPersistentEntity} and @@ -46,8 +46,7 @@ public class MongoMappingContext extends AbstractMappingContext getPersistentEntity(MongoPersistentProperty persistentProperty) { + public @Nullable MongoPersistentEntity getPersistentEntity(MongoPersistentProperty persistentProperty) { MongoPersistentEntity entity = super.getPersistentEntity(persistentProperty); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java index e02bd00c8d..d6ac5a0882 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java @@ -17,9 +17,9 @@ import java.util.Collection; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.model.MutablePersistentEntity; -import org.springframework.lang.Nullable; /** * MongoDB specific {@link PersistentEntity} abstraction. @@ -68,8 +68,7 @@ public interface MongoPersistentEntity extends MutablePersistentEntity property) { } @Override - @Nullable - public MongoPersistentProperty getIdProperty() { + public @Nullable MongoPersistentProperty getIdProperty() { return delegate.getIdProperty(); } @@ -131,8 +128,7 @@ public MongoPersistentProperty getRequiredIdProperty() { } @Override - @Nullable - public MongoPersistentProperty getVersionProperty() { + public @Nullable MongoPersistentProperty getVersionProperty() { return delegate.getVersionProperty(); } @@ -142,8 +138,7 @@ public MongoPersistentProperty getRequiredVersionProperty() { } @Override - @Nullable - public MongoPersistentProperty getPersistentProperty(String name) { + public @Nullable MongoPersistentProperty getPersistentProperty(String name) { return wrap(delegate.getPersistentProperty(name)); } @@ -159,8 +154,7 @@ public MongoPersistentProperty getRequiredPersistentProperty(String name) { } @Override - @Nullable - public MongoPersistentProperty getPersistentProperty(Class annotationType) { + public @Nullable MongoPersistentProperty getPersistentProperty(Class annotationType) { return wrap(delegate.getPersistentProperty(annotationType)); } @@ -226,8 +220,7 @@ public void doWithAssociations(SimpleAssociationHandler handler) { } @Override - @Nullable - public A findAnnotation(Class annotationType) { + public @Nullable A findAnnotation(Class annotationType) { return delegate.findAnnotation(annotationType); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java index 1d4877478f..d714054693 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java @@ -20,11 +20,11 @@ import java.lang.reflect.Method; import java.util.Collection; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** @@ -108,14 +108,12 @@ public boolean isTextScoreProperty() { } @Override - @Nullable - public DBRef getDBRef() { + public @Nullable DBRef getDBRef() { return delegate.getDBRef(); } @Override - @Nullable - public DocumentReference getDocumentReference() { + public @Nullable DocumentReference getDocumentReference() { return delegate.getDocumentReference(); } @@ -165,8 +163,7 @@ public Iterable> getPersistentEntityTypeInformation } @Override - @Nullable - public Method getGetter() { + public @Nullable Method getGetter() { return delegate.getGetter(); } @@ -176,8 +173,7 @@ public Method getRequiredGetter() { } @Override - @Nullable - public Method getSetter() { + public @Nullable Method getSetter() { return delegate.getSetter(); } @@ -187,8 +183,7 @@ public Method getRequiredSetter() { } @Override - @Nullable - public Method getWither() { + public @Nullable Method getWither() { return delegate.getWither(); } @@ -198,8 +193,7 @@ public Method getRequiredWither() { } @Override - @Nullable - public Field getField() { + public @Nullable Field getField() { return delegate.getField(); } @@ -209,14 +203,12 @@ public Field getRequiredField() { } @Override - @Nullable - public String getSpelExpression() { + public @Nullable String getSpelExpression() { return delegate.getSpelExpression(); } @Override - @Nullable - public Association getAssociation() { + public @Nullable Association getAssociation() { return delegate.getAssociation(); } @@ -291,8 +283,7 @@ public Collection getEncryptionKeyIds() { } @Override - @Nullable - public Class getComponentType() { + public @Nullable Class getComponentType() { return delegate.getComponentType(); } @@ -302,8 +293,7 @@ public Class getRawType() { } @Override - @Nullable - public Class getMapValueType() { + public @Nullable Class getMapValueType() { return delegate.getMapValueType(); } @@ -313,8 +303,7 @@ public Class getActualType() { } @Override - @Nullable - public A findAnnotation(Class annotationType) { + public @Nullable A findAnnotation(Class annotationType) { return delegate.findAnnotation(annotationType); } @@ -324,8 +313,7 @@ public A getRequiredAnnotation(Class annotationType) t } @Override - @Nullable - public A findPropertyOrOwnerAnnotation(Class annotationType) { + public @Nullable A findPropertyOrOwnerAnnotation(Class annotationType) { return delegate.findPropertyOrOwnerAnnotation(annotationType); } @@ -340,8 +328,7 @@ public boolean hasActualTypeAnnotation(Class annotationTyp } @Override - @Nullable - public Class getAssociationTargetType() { + public @Nullable Class getAssociationTargetType() { return delegate.getAssociationTargetType(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AbstractDeleteEvent.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AbstractDeleteEvent.java index 73f4890dec..a8e2c93773 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AbstractDeleteEvent.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AbstractDeleteEvent.java @@ -16,7 +16,7 @@ package org.springframework.data.mongodb.core.mapping.event; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Base class for delete events. @@ -49,8 +49,7 @@ public AbstractDeleteEvent(Document document, @Nullable Class type, String co * * @return can be {@literal null}. */ - @Nullable - public Class getType() { + public @Nullable Class getType() { return type; } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AfterDeleteEvent.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AfterDeleteEvent.java index 55ccaa5f3f..10f4cdbbb7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AfterDeleteEvent.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/AfterDeleteEvent.java @@ -16,7 +16,7 @@ package org.springframework.data.mongodb.core.mapping.event; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Event being thrown after a single or a set of documents has/have been deleted. The {@link Document} held in the event diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/BeforeDeleteEvent.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/BeforeDeleteEvent.java index 49d509fb43..c826cadb4e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/BeforeDeleteEvent.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/BeforeDeleteEvent.java @@ -16,7 +16,7 @@ package org.springframework.data.mongodb.core.mapping.event; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Event being thrown before a document is deleted. The {@link Document} held in the event will represent the query diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/MongoMappingEvent.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/MongoMappingEvent.java index eec9a3edf1..bec1986720 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/MongoMappingEvent.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/MongoMappingEvent.java @@ -18,8 +18,8 @@ import java.util.function.Function; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.context.ApplicationEvent; -import org.springframework.lang.Nullable; /** * Base {@link ApplicationEvent} triggered by Spring Data MongoDB. 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 0cc9d071a3..71ed503b20 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,6 +1,6 @@ /** * Mapping event callback infrastructure for the MongoDB document-to-object mapping subsystem. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked 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 0a513f1a18..f5c917d7d7 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,6 +1,6 @@ /** * Infrastructure for the MongoDB document-to-object mapping subsystem. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.core.mapping; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceCounts.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceCounts.java index 32a9ed5118..ed9c148a1c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceCounts.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceCounts.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core.mapreduce; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Value object to encapsulate results of a map-reduce count. 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 9f34ec44e4..de00554240 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 @@ -20,8 +20,8 @@ import java.util.Optional; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Collation; -import org.springframework.lang.Nullable; import com.mongodb.client.model.MapReduceAction; @@ -231,13 +231,11 @@ public Optional getFinalizeFunction() { return this.finalizeFunction; } - @Nullable - public Boolean getJavaScriptMode() { + public @Nullable Boolean getJavaScriptMode() { return this.jsMode; } - @Nullable - public String getOutputCollection() { + public @Nullable String getOutputCollection() { return this.outputCollection; } @@ -279,8 +277,7 @@ public Optional getCollation() { * @return the mapped action or {@literal null} if the action maps to inline output. * @since 2.0.10 */ - @Nullable - public MapReduceAction getMapReduceAction() { + public @Nullable MapReduceAction getMapReduceAction() { return mapReduceAction; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceResults.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceResults.java index 865a4e9438..72f4a9e2fd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceResults.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceResults.java @@ -19,7 +19,7 @@ import java.util.List; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** @@ -71,13 +71,11 @@ public MapReduceCounts getCounts() { return mapReduceCounts; } - @Nullable - public String getOutputCollection() { + public @Nullable String getOutputCollection() { return outputCollection; } - @Nullable - public Document getRawResults() { + public @Nullable Document getRawResults() { return rawResults; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceTiming.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceTiming.java index 28de7fe850..d99f6d9237 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceTiming.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceTiming.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core.mapreduce; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * @deprecated since 3.4 in favor of {@link org.springframework.data.mongodb.core.aggregation}. 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 65522d8613..c5f5840e6b 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 @@ -3,6 +3,6 @@ * @deprecated since MongoDB server version 5.0 */ @Deprecated -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.core.mapreduce; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java index fec7fa60ef..f0d0119f77 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java @@ -20,12 +20,12 @@ import org.bson.BsonValue; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.ChangeStreamOptions; import org.springframework.data.mongodb.core.ChangeStreamOptions.ChangeStreamOptionsBuilder; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.messaging.ChangeStreamRequest.ChangeStreamRequestOptions; import org.springframework.data.mongodb.core.query.Collation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.client.model.changestream.ChangeStreamDocument; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamTask.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamTask.java index fc8372613b..cc4d3f0bdb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamTask.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamTask.java @@ -27,6 +27,7 @@ import org.bson.BsonTimestamp; import org.bson.BsonValue; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.ChangeStreamEvent; import org.springframework.data.mongodb.core.ChangeStreamOptions; import org.springframework.data.mongodb.core.MongoTemplate; @@ -39,7 +40,6 @@ import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.messaging.Message.MessageProperties; import org.springframework.data.mongodb.core.messaging.SubscriptionRequest.RequestOptions; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.ErrorHandler; import org.springframework.util.StringUtils; @@ -224,21 +224,18 @@ static class ChangeStreamEventMessage implements Message getRaw() { + public @Nullable ChangeStreamDocument getRaw() { return delegate.getRaw(); } - @Nullable @Override - public T getBody() { + public @Nullable T getBody() { return delegate.getBody(); } - @Nullable @Override - public T getBodyBeforeChange() { + public @Nullable T getBodyBeforeChange() { return delegate.getBodyBeforeChange(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java index 41b5fed4f5..b150589d8a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java @@ -21,12 +21,12 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.messaging.Message.MessageProperties; import org.springframework.data.mongodb.core.messaging.SubscriptionRequest.RequestOptions; import org.springframework.data.util.Lock; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ErrorHandler; @@ -209,8 +209,7 @@ private void emitMessage(Message message) { } } - @Nullable - private T getNext() { + private @Nullable T getNext() { return lock.execute(() -> { if (State.RUNNING.equals(state)) { @@ -239,8 +238,7 @@ private static boolean isValidCursor(@Nullable MongoCursor cursor) { * @return can be {@literal null}. * @throws RuntimeException The potentially translated exception. */ - @Nullable - private V execute(Supplier callback) { + private @Nullable V execute(Supplier callback) { try { return callback.get(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainer.java index 546f3fdd33..1b24e67e07 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainer.java @@ -25,12 +25,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.Nullable; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.messaging.SubscriptionRequest.RequestOptions; import org.springframework.data.util.Lock; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ErrorHandler; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/Message.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/Message.java index 46db068096..125045c5e0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/Message.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/Message.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core.messaging; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -59,8 +59,7 @@ public interface Message { * @return can be {@literal null}. * @since 4.0 */ - @Nullable - default T getBodyBeforeChange() { + default @Nullable T getBodyBeforeChange() { return null; } @@ -87,8 +86,7 @@ class MessageProperties { * * @return can be {@literal null}. */ - @Nullable - public String getDatabaseName() { + public @Nullable String getDatabaseName() { return databaseName; } @@ -97,8 +95,7 @@ public String getDatabaseName() { * * @return can be {@literal null}. */ - @Nullable - public String getCollectionName() { + public @Nullable String getCollectionName() { return collectionName; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SimpleMessage.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SimpleMessage.java index be5308e3cf..730e0d95bb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SimpleMessage.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SimpleMessage.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core.messaging; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SubscriptionRequest.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SubscriptionRequest.java index 287ba293b6..e28c0b1408 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SubscriptionRequest.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SubscriptionRequest.java @@ -17,9 +17,9 @@ import java.time.Duration; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.core.messaging.SubscriptionRequest.RequestOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -61,8 +61,7 @@ interface RequestOptions { * @return the name of the database to subscribe to. Can be {@literal null} in which case the default * {@link MongoDatabaseFactory#getMongoDatabase() database} is used. */ - @Nullable - default String getDatabaseName() { + default @Nullable String getDatabaseName() { return null; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java index c6caef12fb..6f2f7ce39f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java @@ -18,10 +18,10 @@ import java.util.Optional; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.messaging.SubscriptionRequest.RequestOptions; import org.springframework.data.mongodb.core.messaging.TailableCursorRequest.TailableCursorRequestOptions.TailableCursorRequestOptionsBuilder; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/package-info.java index 35be8f2ef8..aa879cc3c3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/package-info.java @@ -2,5 +2,5 @@ * MongoDB specific messaging support for listening to eg. * Change Streams. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.core.messaging; 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 e2f9169d0d..cae1d3df48 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,6 +1,6 @@ /** * MongoDB core support. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked 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 8b1620b320..9926404e5e 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 @@ -18,7 +18,7 @@ import static org.springframework.util.ObjectUtils.*; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java index 12843ce622..6fd9edcf64 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java @@ -15,21 +15,13 @@ */ package org.springframework.data.mongodb.core.query; -import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.BiFunction; import org.bson.Document; - -import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; +import org.jspecify.annotations.Nullable; /** - * {@link Document}-based {@link Update} variant. - * * @author Thomas Risberg * @author John Brisbin * @author Oliver Gierke @@ -41,114 +33,74 @@ public class BasicUpdate extends Update { private final Document updateObject; public BasicUpdate(String updateString) { - this(Document.parse(updateString)); + super(); + this.updateObject = Document.parse(updateString); } public BasicUpdate(Document updateObject) { + super(); this.updateObject = updateObject; } @Override public Update set(String key, @Nullable Object value) { - setOperationValue("$set", key, value); + updateObject.put("$set", Collections.singletonMap(key, value)); return this; } @Override public Update unset(String key) { - setOperationValue("$unset", key, 1); + updateObject.put("$unset", Collections.singletonMap(key, 1)); return this; } @Override public Update inc(String key, Number inc) { - setOperationValue("$inc", key, inc); + updateObject.put("$inc", Collections.singletonMap(key, inc)); return this; } @Override public Update push(String key, @Nullable Object value) { - setOperationValue("$push", key, value); + updateObject.put("$push", Collections.singletonMap(key, value)); return this; } @Override public Update addToSet(String key, @Nullable Object value) { - setOperationValue("$addToSet", key, value); + updateObject.put("$addToSet", Collections.singletonMap(key, value)); return this; } @Override public Update pop(String key, Position pos) { - setOperationValue("$pop", key, (pos == Position.FIRST ? -1 : 1)); + updateObject.put("$pop", Collections.singletonMap(key, (pos == Position.FIRST ? -1 : 1))); return this; } @Override public Update pull(String key, @Nullable Object value) { - setOperationValue("$pull", key, value); + updateObject.put("$pull", Collections.singletonMap(key, value)); return this; } @Override public Update pullAll(String key, Object[] values) { - setOperationValue("$pullAll", key, List.of(values), (o, o2) -> { - - if (o instanceof List prev && o2 instanceof List currentValue) { - List merged = new ArrayList<>(prev.size() + currentValue.size()); - merged.addAll(prev); - merged.addAll(currentValue); - return merged; - } - - return o2; - }); + Document keyValue = new Document(); + keyValue.put(key, Arrays.copyOf(values, values.length)); + updateObject.put("$pullAll", keyValue); return this; } @Override public Update rename(String oldName, String newName) { - setOperationValue("$rename", oldName, newName); + updateObject.put("$rename", Collections.singletonMap(oldName, newName)); return this; } - @Override - public boolean modifies(String key) { - return super.modifies(key) || Update.fromDocument(getUpdateObject()).modifies(key); - } - @Override public Document getUpdateObject() { return updateObject; } - void setOperationValue(String operator, String key, @Nullable Object value) { - setOperationValue(operator, key, value, (o, o2) -> o2); - } - - void setOperationValue(String operator, String key, @Nullable Object value, - BiFunction mergeFunction) { - - if (!updateObject.containsKey(operator)) { - updateObject.put(operator, Collections.singletonMap(key, value)); - } else { - Object o = updateObject.get(operator); - if (o instanceof Map existing) { - Map target = new LinkedHashMap<>(existing); - - if (target.containsKey(key)) { - target.put(key, mergeFunction.apply(target.get(key), value)); - } else { - target.put(key, value); - } - updateObject.put(operator, target); - } else { - throw new IllegalStateException( - "Cannot add ['%s' : { '%s' : ... }]. Operator already exists with value of type [%s] which is not suitable for appending" - .formatted(operator, key, - o != null ? ClassUtils.getShortName(o.getClass()) : "null")); - } - } - } - } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java index de24c0511d..c1ca9791a3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java @@ -19,8 +19,8 @@ import java.util.Optional; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; 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 8d4cb703bb..e0c25d6907 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 @@ -33,6 +33,7 @@ import org.bson.BsonType; import org.bson.Document; import org.bson.types.Binary; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Example; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Point; @@ -45,7 +46,6 @@ import org.springframework.data.mongodb.core.schema.JsonSchemaProperty; import org.springframework.data.mongodb.core.schema.MongoJsonSchema; import org.springframework.data.mongodb.util.RegexFlags; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -884,8 +884,7 @@ private Criteria registerCriteriaChainElement(Criteria criteria) { * @see org.springframework.data.mongodb.core.query.CriteriaDefinition#getKey() */ @Override - @Nullable - public String getKey() { + public @Nullable 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 c00b1d4b82..c75f709ab9 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 @@ -16,7 +16,7 @@ package org.springframework.data.mongodb.core.query; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * @author Oliver Gierke 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 3540a5a836..f8bd8fa897 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 @@ -22,8 +22,8 @@ import java.util.Map.Entry; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.MongoExpression; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/GeoCommand.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/GeoCommand.java index 83417c7200..19ecd94e23 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/GeoCommand.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/GeoCommand.java @@ -17,12 +17,12 @@ import static org.springframework.util.ObjectUtils.*; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Box; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Polygon; import org.springframework.data.geo.Shape; import org.springframework.data.mongodb.core.geo.Sphere; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java index 5757aa94a2..c6bf9992e5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java @@ -23,7 +23,7 @@ import java.util.Map.Entry; import java.util.Set; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -85,8 +85,7 @@ public boolean hasMaxTime() { /** * @return {@literal null} if not set. */ - @Nullable - public Long getMaxTimeMsec() { + public @Nullable Long getMaxTimeMsec() { return getValue(MetaKey.MAX_TIME_MS.key); } @@ -181,8 +180,7 @@ public void setComment(String comment) { * @return {@literal null} if not set. * @since 2.1 */ - @Nullable - public Integer getCursorBatchSize() { + public @Nullable Integer getCursorBatchSize() { return cursorBatchSize; } @@ -285,9 +283,8 @@ void setValue(String key, @Nullable Object value) { this.values.put(key, value); } - @Nullable @SuppressWarnings("unchecked") - private T getValue(String key) { + private @Nullable T getValue(String key) { return (T) this.values.get(key); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MongoRegexCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MongoRegexCreator.java index e26a61c61e..b37c088981 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MongoRegexCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MongoRegexCreator.java @@ -18,7 +18,7 @@ import java.util.regex.Pattern; import org.bson.BsonRegularExpression; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * @author Christoph Strobl @@ -80,8 +80,7 @@ public enum MatchMode { * @param matcherType the type of matching to perform * @return {@literal source} when {@literal source} or {@literal matcherType} is {@literal null}. */ - @Nullable - public String toRegularExpression(@Nullable String source, @Nullable MatchMode matcherType) { + public @Nullable String toRegularExpression(@Nullable String source, @Nullable MatchMode matcherType) { if (matcherType == null || source == null) { return source; 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 f0f3b0a4dc..b9ccec1067 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 @@ -18,6 +18,7 @@ import java.util.Arrays; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Pageable; import org.springframework.data.geo.CustomMetric; import org.springframework.data.geo.Distance; @@ -27,7 +28,6 @@ import org.springframework.data.mongodb.core.ReadConcernAware; import org.springframework.data.mongodb.core.ReadPreferenceAware; import org.springframework.data.mongodb.core.geo.GeoJsonPoint; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -428,8 +428,7 @@ public NearQuery minDistance(Distance distance) { * * @return */ - @Nullable - public Distance getMaxDistance() { + public @Nullable Distance getMaxDistance() { return this.maxDistance; } @@ -439,8 +438,7 @@ public Distance getMaxDistance() { * @return * @since 1.7 */ - @Nullable - public Distance getMinDistance() { + public @Nullable Distance getMinDistance() { return this.minDistance; } @@ -546,8 +544,7 @@ public NearQuery query(Query query) { /** * @return the number of elements to skip. */ - @Nullable - public Long getSkip() { + public @Nullable Long getSkip() { return skip; } @@ -557,8 +554,7 @@ public Long getSkip() { * @return the {@link Collation} if set. {@literal null} otherwise. * @since 2.2 */ - @Nullable - public Collation getCollation() { + public @Nullable Collation getCollation() { return query != null ? query.getCollation().orElse(null) : null; } @@ -620,9 +616,8 @@ public ReadConcern getReadConcern() { * @since 4.1 * @see ReadPreferenceAware */ - @Nullable @Override - public ReadPreference getReadPreference() { + public @Nullable ReadPreference getReadPreference() { if (query != null && query.hasReadPreference()) { return query.getReadPreference(); 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 31c6b9069f..c5d0a1638a 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 @@ -30,6 +30,7 @@ import java.util.Set; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.KeysetScrollPosition; import org.springframework.data.domain.Limit; import org.springframework.data.domain.OffsetScrollPosition; @@ -42,7 +43,6 @@ import org.springframework.data.mongodb.core.ReadPreferenceAware; import org.springframework.data.mongodb.core.query.Meta.CursorOption; import org.springframework.data.mongodb.util.BsonUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.ReadConcern; @@ -349,8 +349,7 @@ public boolean hasKeyset() { return keysetScrollPosition != null; } - @Nullable - public KeysetScrollPosition getKeyset() { + public @Nullable KeysetScrollPosition getKeyset() { return keysetScrollPosition; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java index 11e0f7fb24..b7f877ce49 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java @@ -23,9 +23,8 @@ import java.util.Map; import org.bson.Document; - +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** @@ -110,8 +109,7 @@ private static void toFlatMap(String currentPath, Object source, Map getTypes() { return targetProperty.getTypes(); } - @Nullable - private Type extractPropertyType(Document source) { + private @Nullable Type extractPropertyType(Document source) { if (source.containsKey("type")) { return Type.of(source.get("type", String.class)); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java index a84f361d37..24a40efa5b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java @@ -31,6 +31,7 @@ import org.bson.types.Code; import org.bson.types.Decimal128; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ArrayJsonSchemaObject; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.BooleanJsonSchemaObject; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.DateJsonSchemaObject; @@ -39,7 +40,6 @@ import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ObjectJsonSchemaObject; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.StringJsonSchemaObject; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.TimestampJsonSchemaObject; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaProperty.java index 8529951db2..9a112941be 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaProperty.java @@ -17,10 +17,10 @@ import java.util.Collection; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.NumericJsonSchemaObject; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ObjectJsonSchemaObject; import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.*; -import org.springframework.lang.Nullable; /** * A {@literal property} or {@literal patternProperty} within a {@link JsonSchemaObject} of {@code type : 'object'}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java index f64218cc56..f6e4071eaf 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java @@ -23,8 +23,8 @@ import java.util.Set; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ObjectJsonSchemaObject; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -311,8 +311,7 @@ class MongoJsonSchemaBuilder { private ObjectJsonSchemaObject root; - @Nullable // - private Document encryptionMetadata; + private @Nullable Document encryptionMetadata; MongoJsonSchemaBuilder() { root = new ObjectJsonSchemaObject(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypeUnifyingMergeFunction.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypeUnifyingMergeFunction.java index 95f116619f..315bfd94d7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypeUnifyingMergeFunction.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypeUnifyingMergeFunction.java @@ -22,10 +22,10 @@ import java.util.function.BiFunction; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.schema.MongoJsonSchema.ConflictResolutionFunction; import org.springframework.data.mongodb.core.schema.MongoJsonSchema.ConflictResolutionFunction.Path; import org.springframework.data.mongodb.core.schema.MongoJsonSchema.ConflictResolutionFunction.Resolution; -import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -119,8 +119,7 @@ private static String getTypeKeyToUse(String key, Document source) { return key; } - @Nullable - private static Object getUnifiedExistingType(String key, Document source) { + private static @Nullable Object getUnifiedExistingType(String key, Document source) { return source.get(getTypeKeyToUse(key, source)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypedJsonSchemaObject.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypedJsonSchemaObject.java index abf8b0b8a2..1394a28e24 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypedJsonSchemaObject.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypedJsonSchemaObject.java @@ -27,9 +27,9 @@ import java.util.stream.Collectors; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.domain.Range.Bound; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -210,8 +210,7 @@ private Optional getOrCreateDescription() { * * @return can be {@literal null}. */ - @Nullable - protected String generateDescription() { + protected @Nullable String generateDescription() { return null; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java index 54ca29e0e3..b570855c98 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java @@ -23,7 +23,7 @@ import java.util.stream.Collectors; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -163,8 +163,7 @@ private Optional getOrCreateDescription() { * * @return can be {@literal null}. */ - @Nullable - protected String generateDescription() { + protected @Nullable String generateDescription() { return null; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/package-info.java index 380d92af09..cdc583e038 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/package-info.java @@ -1,6 +1,6 @@ /** * MongoDB-specific JSON schema implementation classes. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked @org.springframework.lang.NonNullFields package org.springframework.data.mongodb.core.schema; 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 index 34eb8ea890..976b238fbd 100644 --- 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 @@ -3,6 +3,6 @@ * * @since 1.7 */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.core.script; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionNode.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionNode.java index b4550ee8de..a5b4a2aabf 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionNode.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionNode.java @@ -18,13 +18,13 @@ import java.util.Collections; import java.util.Iterator; +import org.jspecify.annotations.Nullable; import org.springframework.expression.spel.ExpressionState; import org.springframework.expression.spel.SpelNode; import org.springframework.expression.spel.ast.Literal; import org.springframework.expression.spel.ast.MethodReference; import org.springframework.expression.spel.ast.Operator; import org.springframework.expression.spel.ast.OperatorNot; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -150,8 +150,7 @@ public boolean isLiteral() { * * @return */ - @Nullable - public Object getValue() { + public @Nullable Object getValue() { return node.getValue(state); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformationContextSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformationContextSupport.java index 8869f51e09..f2a1394ab1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformationContextSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformationContextSupport.java @@ -18,7 +18,7 @@ import java.util.List; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** @@ -67,8 +67,7 @@ public T getCurrentNode() { * * @return */ - @Nullable - public ExpressionNode getParentNode() { + public @Nullable ExpressionNode getParentNode() { return parentNode; } @@ -81,8 +80,7 @@ public ExpressionNode getParentNode() { * @see #addToPreviousOrReturn(Object) * @return */ - @Nullable - public Document getPreviousOperationObject() { + public @Nullable Document getPreviousOperationObject() { return previousOperationObject; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/LiteralNode.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/LiteralNode.java index 030ef0d055..b276831860 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/LiteralNode.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/LiteralNode.java @@ -17,6 +17,7 @@ import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.expression.spel.ExpressionState; import org.springframework.expression.spel.ast.BooleanLiteral; import org.springframework.expression.spel.ast.FloatLiteral; @@ -26,7 +27,6 @@ import org.springframework.expression.spel.ast.NullLiteral; import org.springframework.expression.spel.ast.RealLiteral; import org.springframework.expression.spel.ast.StringLiteral; -import org.springframework.lang.Nullable; /** * A node representing a literal in an expression. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java index 5f1b0c4309..db2801e649 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java @@ -21,9 +21,9 @@ import java.util.HashMap; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.expression.spel.ExpressionState; import org.springframework.expression.spel.ast.MethodReference; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -272,8 +272,7 @@ public class MethodReferenceNode extends ExpressionNode { * @return can be {@literal null}. * @since 1.10 */ - @Nullable - public AggregationMethodReference getMethodReference() { + public @Nullable AggregationMethodReference getMethodReference() { String name = getName(); String methodName = name.substring(0, name.indexOf('(')); @@ -288,7 +287,7 @@ public static final class AggregationMethodReference { private final @Nullable String mongoOperator; private final @Nullable ArgumentType argumentType; - private final @Nullable String[] argumentMap; + private final String @Nullable[] argumentMap; /** * Creates new {@link AggregationMethodReference}. @@ -298,7 +297,7 @@ public static final class AggregationMethodReference { * @param argumentMap can be {@literal null}. */ private AggregationMethodReference(@Nullable String mongoOperator, @Nullable ArgumentType argumentType, - @Nullable String[] argumentMap) { + String @Nullable[] argumentMap) { this.mongoOperator = mongoOperator; this.argumentType = argumentType; @@ -310,8 +309,7 @@ private AggregationMethodReference(@Nullable String mongoOperator, @Nullable Arg * * @return can be {@literal null}. */ - @Nullable - public String getMongoOperator() { + public @Nullable String getMongoOperator() { return this.mongoOperator; } @@ -320,8 +318,7 @@ public String getMongoOperator() { * * @return never {@literal null}. */ - @Nullable - public ArgumentType getArgumentType() { + public @Nullable ArgumentType getArgumentType() { return this.argumentType; } 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 fbfa2ae78b..627cb8a04f 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 @@ -3,6 +3,6 @@ * * @since 1.4 */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.core.spel; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/CriteriaValidator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/CriteriaValidator.java index 779ed4ec9f..d739994e89 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/CriteriaValidator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/CriteriaValidator.java @@ -16,10 +16,10 @@ package org.springframework.data.mongodb.core.validation; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.CriteriaDefinition; import org.springframework.data.mongodb.core.query.SerializationUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/DocumentValidator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/DocumentValidator.java index 5e27b99ad6..9adf5fcf79 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/DocumentValidator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/DocumentValidator.java @@ -16,8 +16,8 @@ package org.springframework.data.mongodb.core.validation; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.SerializationUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/JsonSchemaValidator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/JsonSchemaValidator.java index 61ef8c5b4f..b04e65b1db 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/JsonSchemaValidator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/JsonSchemaValidator.java @@ -16,9 +16,9 @@ package org.springframework.data.mongodb.core.validation; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.SerializationUtils; import org.springframework.data.mongodb.core.schema.MongoJsonSchema; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/package-info.java index 002a4ee1fb..83fe5719a3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/package-info.java @@ -1,6 +1,6 @@ /** * MongoDB schema validation specifics. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked @org.springframework.lang.NonNullFields package org.springframework.data.mongodb.core.validation; 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 54010a7c65..e0aa5bb2d5 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 @@ -15,8 +15,8 @@ */ package org.springframework.data.mongodb.gridfs; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.lang.Nullable; /** * GridFs-specific helper class to define {@link Criteria}s. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java index f73c0c943f..1e22a5d3f3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java @@ -16,7 +16,7 @@ package org.springframework.data.mongodb.gridfs; import org.bson.Document; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import com.mongodb.client.gridfs.model.GridFSFile; 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 bf5a1d86e3..4878b431f4 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 @@ -19,11 +19,11 @@ import org.bson.Document; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.gridfs.GridFsUpload.GridFsUploadBuilder; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -181,8 +181,7 @@ default ObjectId store(InputStream content, @Nullable String filename, @Nullable * @param query must not be {@literal null}. * @return can be {@literal null}. */ - @Nullable - com.mongodb.client.gridfs.model.GridFSFile findOne(Query query); + com.mongodb.client.gridfs.model.@Nullable GridFSFile findOne(Query query); /** * Deletes all files matching the given {@link Query}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperationsSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperationsSupport.java index b3d3771f3c..9a5621dcbc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperationsSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperationsSupport.java @@ -18,9 +18,9 @@ import java.util.Optional; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.convert.QueryMapper; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java index 0873432977..e2819222d4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java @@ -21,10 +21,10 @@ import java.io.InputStream; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; import org.springframework.data.mongodb.util.BsonUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.MongoGridFSException; @@ -157,8 +157,7 @@ public Object getFileId() { * @return the underlying {@link GridFSFile}. Can be {@literal null} if absent. * @since 2.2 */ - @Nullable - public GridFSFile getGridFSFile() { + public @Nullable GridFSFile getGridFSFile() { return this.file; } 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 8187c7dbc3..d688932f6d 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 @@ -26,13 +26,13 @@ import org.bson.Document; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.util.BsonUtils; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java index 9f8d9a47d2..a57da38405 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java @@ -20,9 +20,8 @@ import org.bson.Document; import org.bson.types.ObjectId; - +import org.jspecify.annotations.Nullable; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.client.gridfs.model.GridFSFile; @@ -61,8 +60,7 @@ private GridFsUpload(@Nullable ID id, Lazy dataStream, String filen * @see org.springframework.data.mongodb.gridfs.GridFsObject#getFileId() */ @Override - @Nullable - public ID getFileId() { + public @Nullable ID getFileId() { return id; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsOperations.java index 9ee47e0bb9..f8a6bd804f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsOperations.java @@ -20,12 +20,12 @@ import org.bson.Document; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.gridfs.ReactiveGridFsUpload.ReactiveGridFsUploadBuilder; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsResource.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsResource.java index aec7cadef1..3efc6edcc8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsResource.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsResource.java @@ -22,6 +22,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.bson.BsonValue; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.core.io.Resource; import org.springframework.core.io.buffer.DataBuffer; @@ -29,7 +30,6 @@ import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.data.mongodb.util.BsonUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.client.gridfs.model.GridFSFile; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java index 305e55aee4..092f81d1fa 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java @@ -26,6 +26,7 @@ import org.bson.BsonValue; import org.bson.Document; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferFactory; @@ -37,7 +38,6 @@ import org.springframework.data.mongodb.core.query.SerializationUtils; import org.springframework.data.mongodb.util.BsonUtils; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java index 2f16c3b06e..c1fe458219 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java @@ -17,9 +17,9 @@ import org.bson.Document; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.client.gridfs.model.GridFSFile; @@ -58,8 +58,7 @@ private ReactiveGridFsUpload(@Nullable ID id, Publisher dataStream, * @see org.springframework.data.mongodb.gridfs.GridFsObject#getFileId() */ @Override - @Nullable - public ID getFileId() { + public @Nullable ID getFileId() { return id; } 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 2f3b5af150..57726d69cc 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,6 +1,6 @@ /** * Support for MongoDB GridFS feature. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked 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 new file mode 100644 index 0000000000..40073d6022 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/monitor/package-info.java @@ -0,0 +1,6 @@ +/** + * MongoDB specific JMX monitoring support. + */ +@org.jspecify.annotations.NullMarked +package org.springframework.data.mongodb.monitor; + diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoHandlerContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoHandlerContext.java index cc58aac56e..b86e8ec70a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoHandlerContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoHandlerContext.java @@ -25,8 +25,7 @@ import org.bson.BsonDocument; import org.bson.BsonValue; - -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import com.mongodb.ConnectionString; import com.mongodb.RequestContext; @@ -92,8 +91,7 @@ public String getCommandName() { return commandStartedEvent.getCommandName(); } - @Nullable - public ConnectionString getConnectionString() { + public @Nullable ConnectionString getConnectionString() { return connectionString; } @@ -135,8 +133,7 @@ private static String getCollectionName(CommandStartedEvent event) { * * @return trimmed string from {@code bsonValue} or null if the trimmed string was empty or the value wasn't a string */ - @Nullable - private static String getNonEmptyBsonString(@Nullable BsonValue bsonValue) { + private static @Nullable String getNonEmptyBsonString(@Nullable BsonValue bsonValue) { if (bsonValue == null || !bsonValue.isString()) { return null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoObservationCommandListener.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoObservationCommandListener.java index 9360a95de2..914396ab96 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoObservationCommandListener.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoObservationCommandListener.java @@ -23,7 +23,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import com.mongodb.ConnectionString; @@ -197,8 +197,7 @@ private void doInObservation(@Nullable RequestContext requestContext, * @param context * @return */ - @Nullable - private static Observation observationFromContext(RequestContext context) { + private static @Nullable Observation observationFromContext(RequestContext context) { Observation observation = context.getOrDefault(ObservationThreadLocalAccessor.KEY, null); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/package-info.java index d240e12f9e..d6319e5f4f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/package-info.java @@ -1,5 +1,5 @@ /** * Infrastructure to provide driver observability using Micrometer. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.observability; 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 900342bbcb..989655f4a6 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 +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/RepositoryRuntimeHints.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/RepositoryRuntimeHints.java index b1ba6ea3f0..00ff498731 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/RepositoryRuntimeHints.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/RepositoryRuntimeHints.java @@ -19,6 +19,7 @@ import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; @@ -28,7 +29,6 @@ import org.springframework.data.mongodb.repository.support.QuerydslMongoPredicateExecutor; import org.springframework.data.mongodb.repository.support.ReactiveQuerydslMongoPredicateExecutor; import org.springframework.data.querydsl.QuerydslUtils; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/package-info.java index 9016519d9b..750cc38678 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/package-info.java @@ -1,5 +1,5 @@ /** * Ahead-Of-Time processors for MongoDB repositories. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.repository.aot; 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 a2cbf659dd..db7edc05bd 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,6 +1,6 @@ /** * CDI support for MongoDB specific repository implementation. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked 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 d0d9b07081..e276d4d1e0 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,6 +1,6 @@ /** * Support infrastructure for the configuration of MongoDB specific repositories. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked 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 8deddfe939..799597e19c 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,6 +1,6 @@ /** * MongoDB specific repository implementation. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked 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 910665253d..b52df43379 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 @@ -20,7 +20,7 @@ import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; - +import org.jspecify.annotations.Nullable; import org.springframework.data.expression.ValueEvaluationContextProvider; import org.springframework.data.expression.ValueExpression; import org.springframework.data.mapping.model.ValueExpressionEvaluator; @@ -48,7 +48,6 @@ import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -126,8 +125,7 @@ public Object execute(Object[] parameters) { * @param accessor for providing invocation arguments. Never {@literal null}. * @param typeToRead the desired component target type. Can be {@literal null}. */ - @Nullable - protected Object doExecute(MongoQueryMethod method, ResultProcessor processor, ConvertingParameterAccessor accessor, + protected @Nullable Object doExecute(MongoQueryMethod method, ResultProcessor processor, ConvertingParameterAccessor accessor, @Nullable Class typeToRead) { Query query = createQuery(accessor); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java index 76b4b2e088..f5b1e2f7df 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java @@ -24,6 +24,7 @@ import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.core.convert.converter.Converter; @@ -57,7 +58,6 @@ import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.spel.ExpressionDependencies; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AggregationUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AggregationUtils.java index 6eb6a5da89..639c694ef9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AggregationUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AggregationUtils.java @@ -22,7 +22,7 @@ import java.util.function.LongUnaryOperator; import org.bson.Document; - +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort.Order; import org.springframework.data.mapping.model.ValueExpressionEvaluator; @@ -41,7 +41,6 @@ import org.springframework.data.repository.query.ReturnedType; import org.springframework.data.util.ReflectionUtils; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -166,8 +165,7 @@ static AggregationOptions computeOptions(MongoQueryMethod method, ConvertingPara * Prepares the AggregationPipeline including type discovery and calling {@link AggregationCallback} to run the * aggregation. */ - @Nullable - static T doAggregate(AggregationPipeline pipeline, MongoQueryMethod method, ResultProcessor processor, + static @Nullable T doAggregate(AggregationPipeline pipeline, MongoQueryMethod method, ResultProcessor processor, ConvertingParameterAccessor accessor, Function evaluatorFunction, AggregationCallback callback) { @@ -308,8 +306,7 @@ static void appendLimitAndOffsetIfPresent(AggregationPipeline aggregationPipelin * @return can be {@literal null} if source {@link Document#isEmpty() is empty}. * @throws IllegalArgumentException when none of the above rules is met. */ - @Nullable - static T extractSimpleTypeResult(@Nullable Document source, Class targetType, MongoConverter converter) { + static @Nullable T extractSimpleTypeResult(@Nullable Document source, Class targetType, MongoConverter converter) { if (ObjectUtils.isEmpty(source)) { return null; @@ -336,9 +333,8 @@ static T extractSimpleTypeResult(@Nullable Document source, Class targetT String.format("o_O no entry of type %s found in %s.", targetType.getSimpleName(), source.toJson())); } - @Nullable @SuppressWarnings("unchecked") - private static T getPotentiallyConvertedSimpleTypeValue(MongoConverter converter, @Nullable Object value, + private static @Nullable T getPotentiallyConvertedSimpleTypeValue(MongoConverter converter, @Nullable Object value, Class targetType) { if (value == null) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/CollationUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/CollationUtils.java index 2aac6b77a8..df99017896 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/CollationUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/CollationUtils.java @@ -20,12 +20,11 @@ import java.util.regex.Pattern; import org.bson.Document; - +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.model.ValueExpressionEvaluator; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.util.json.ParameterBindingContext; import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec; -import org.springframework.lang.Nullable; import org.springframework.util.NumberUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -55,8 +54,7 @@ private CollationUtils() { * @return can be {@literal null} if neither {@link ConvertingParameterAccessor#getCollation()} nor * {@literal collationExpression} are present. */ - @Nullable - static Collation computeCollation(@Nullable String collationExpression, ConvertingParameterAccessor accessor, + static @Nullable Collation computeCollation(@Nullable String collationExpression, ConvertingParameterAccessor accessor, ValueExpressionEvaluator expressionEvaluator) { if (accessor.getCollation() != null) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java index dbf87f2f2e..0032ca3fb1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java @@ -21,6 +21,7 @@ import java.util.Iterator; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Limit; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Range; @@ -35,7 +36,6 @@ import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -130,8 +130,7 @@ public Limit getLimit() { * @param typeInformation can be {@literal null}. * @return can be {@literal null}. */ - @Nullable - private Object getConvertedValue(Object value, @Nullable TypeInformation typeInformation) { + private @Nullable Object getConvertedValue(Object value, @Nullable TypeInformation typeInformation) { return writer.convertToMongoType(value, typeInformation == null ? null : typeInformation.getActualType()); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoEntityInformation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoEntityInformation.java index 8678e5a74c..c54d689b52 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoEntityInformation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoEntityInformation.java @@ -15,9 +15,9 @@ */ package org.springframework.data.mongodb.repository.query; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.repository.core.EntityInformation; -import org.springframework.lang.Nullable; /** * Mongo specific {@link EntityInformation}. @@ -58,8 +58,7 @@ default boolean isVersioned() { * @return can be {@literal null}. * @since 2.2 */ - @Nullable - default Object getVersion(T entity) { + default @Nullable Object getVersion(T entity) { return null; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameterAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameterAccessor.java index 5db853e810..d9cacdbb14 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameterAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameterAccessor.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.repository.query; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.geo.Distance; import org.springframework.data.geo.Point; @@ -23,7 +24,6 @@ import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.lang.Nullable; /** * Mongo-specific {@link ParameterAccessor} exposing a maximum distance parameter. 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 257d8d1918..1ed39c9851 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 @@ -19,6 +19,7 @@ import java.util.Arrays; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.core.MethodParameter; import org.springframework.data.domain.Range; import org.springframework.data.geo.Distance; @@ -32,7 +33,6 @@ import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersSource; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; /** * Custom extension of {@link Parameters} discovering additional diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java index ac1931e10c..b1c81dbbbe 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.repository.query; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.domain.Range.Bound; import org.springframework.data.geo.Distance; @@ -24,7 +25,6 @@ import org.springframework.data.mongodb.core.query.TextCriteria; import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -95,9 +95,8 @@ public Point getGeoNearLocation() { return (Point) value; } - @Nullable @Override - public TextCriteria getFullText() { + public @Nullable TextCriteria getFullText() { int index = method.getParameters().getFullTextParameterIndex(); return index >= 0 ? potentiallyConvertFullText(getValue(index)) : null; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java index 66a8870623..d616f783ee 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java @@ -26,6 +26,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bson.BsonRegularExpression; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.domain.Range.Bound; import org.springframework.data.domain.Sort; @@ -52,7 +53,6 @@ import org.springframework.data.repository.query.parser.Part.Type; import org.springframework.data.repository.query.parser.PartTree; import org.springframework.data.util.Streamable; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -348,8 +348,7 @@ private Criteria addAppropriateLikeRegexTo(Criteria criteria, Part part, Object * @param part * @return the regex options or {@literal null}. */ - @Nullable - private String toRegexOptions(Part part) { + private @Nullable String toRegexOptions(Part part) { String regexOptions = null; switch (part.shouldIgnoreCase()) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java index dd2b78de59..0e57eaada9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Range; @@ -39,7 +40,6 @@ import org.springframework.data.mongodb.repository.util.SliceUtils; import org.springframework.data.support.PageableExecutionUtils; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; 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 dcfef7de00..8ed3446eec 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 @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.data.geo.GeoPage; import org.springframework.data.geo.GeoResult; @@ -48,7 +49,6 @@ import org.springframework.data.util.ReactiveWrappers; import org.springframework.data.util.ReflectionUtils; 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.ConcurrentReferenceHashMap; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java index 431510f11b..4b7262749a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java @@ -21,13 +21,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bson.Document; - +import org.jspecify.annotations.Nullable; import org.springframework.aop.framework.ProxyFactory; import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mapping.model.ValueExpressionEvaluator; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java index d18c6a989c..dea3695775 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java @@ -18,6 +18,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.DtoInstantiatingConverter; @@ -37,7 +38,6 @@ import org.springframework.data.util.ReactiveWrappers; import org.springframework.data.util.ReflectionUtils; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregation.java index cf6e7231f8..ebc33cef96 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregation.java @@ -21,6 +21,7 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.mongodb.core.ReactiveMongoOperations; @@ -32,7 +33,6 @@ import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.util.ReflectionUtils; -import org.springframework.lang.Nullable; /** * A reactive {@link org.springframework.data.repository.query.RepositoryQuery} to use a plain JSON String to create an diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java index 562ee026fc..cef642dd5e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java @@ -20,7 +20,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bson.Document; - +import org.jspecify.annotations.NonNull; import org.springframework.data.expression.ValueExpressionParser; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.ReactiveMongoOperations; @@ -30,7 +30,6 @@ import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.spel.ExpressionDependencies; -import org.springframework.lang.NonNull; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringAggregationOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringAggregationOperation.java index 724c8f29ef..289b953b27 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringAggregationOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringAggregationOperation.java @@ -20,9 +20,9 @@ import java.util.regex.Pattern; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.AggregationOperation; import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext; -import org.springframework.lang.Nullable; /** * String-based aggregation operation for a repository query method. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedAggregation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedAggregation.java index 5596435eb0..3f6a48e84c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedAggregation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedAggregation.java @@ -20,7 +20,7 @@ import java.util.stream.Stream; import org.bson.Document; - +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.SliceImpl; import org.springframework.data.mongodb.InvalidMongoDbApiUsageException; @@ -32,7 +32,6 @@ import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.util.ReflectionUtils; -import org.springframework.lang.Nullable; /** * {@link AbstractMongoQuery} implementation to run string-based aggregations using @@ -72,8 +71,7 @@ public StringBasedAggregation(MongoQueryMethod method, MongoOperations mongoOper @SuppressWarnings("unchecked") @Override - @Nullable - protected Object doExecute(MongoQueryMethod method, ResultProcessor processor, ConvertingParameterAccessor accessor, + protected @Nullable Object doExecute(MongoQueryMethod method, ResultProcessor processor, ConvertingParameterAccessor accessor, @Nullable Class ignore) { return AggregationUtils.doAggregate(AggregationUtils.computePipeline(this, method, accessor), method, processor, 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 20c77e22aa..5f0cc21049 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,6 +1,6 @@ /** * Query derivation mechanism for MongoDB specific repositories. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.repository.query; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java index f59a995170..5c50c79ea9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java @@ -25,6 +25,7 @@ import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; +import org.jspecify.annotations.Nullable; import org.springframework.aop.TargetSource; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.BeanClassLoaderAware; @@ -32,7 +33,6 @@ import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.support.RepositoryProxyPostProcessor; -import org.springframework.lang.Nullable; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java index 1d876289be..c6d42388ef 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java @@ -16,12 +16,12 @@ package org.springframework.data.mongodb.repository.support; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.repository.query.MongoEntityInformation; import org.springframework.data.repository.core.support.PersistentEntityInformation; -import org.springframework.lang.Nullable; /** * {@link MongoEntityInformation} implementation using a {@link MongoPersistentEntity} instance to lookup the necessary @@ -124,8 +124,7 @@ public Object getVersion(T entity) { return accessor.getProperty(this.entityMetadata.getRequiredVersionProperty()); } - @Nullable - public Collation getCollation() { + public @Nullable Collation getCollation() { return this.entityMetadata.getCollation(); } 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 3c029ee5aa..6deee469e1 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 @@ -22,9 +22,8 @@ import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.tools.Diagnostic; - +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.Document; -import org.springframework.lang.Nullable; import com.querydsl.apt.AbstractQuerydslProcessor; import com.querydsl.apt.Configuration; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoEntityInformationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoEntityInformationSupport.java index d0a3f7a1e4..1a39198757 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoEntityInformationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoEntityInformationSupport.java @@ -15,9 +15,9 @@ */ package org.springframework.data.mongodb.repository.support; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.repository.query.MongoEntityInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** 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 91a3e39cbe..666329c947 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 @@ -21,6 +21,7 @@ import java.lang.reflect.Method; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.BeanFactory; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.mapping.context.MappingContext; @@ -44,7 +45,6 @@ import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ValueExpressionDelegate; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** 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 c98d38c5f5..ec75a5c27b 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 @@ -17,13 +17,13 @@ import java.io.Serializable; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.MongoOperations; 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; /** 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 fe18fda758..b443ae3f2e 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 @@ -21,6 +21,7 @@ import java.lang.reflect.Method; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.BeanFactory; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.ReactiveMongoOperations; @@ -45,7 +46,6 @@ import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ValueExpressionDelegate; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** 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 dfb7c00fe6..341280436f 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 @@ -17,13 +17,13 @@ import java.io.Serializable; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.ReactiveMongoOperations; 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; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveSpringDataMongodbQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveSpringDataMongodbQuery.java index cf5191fd42..2d9c7e29b3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveSpringDataMongodbQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveSpringDataMongodbQuery.java @@ -25,6 +25,7 @@ import java.util.function.Consumer; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.ScrollPosition; @@ -36,7 +37,6 @@ import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.lang.Nullable; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java index 2f4c30ee7a..2c469c777d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java @@ -27,6 +27,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; @@ -47,7 +48,6 @@ import org.springframework.data.support.PageableExecutionUtils; import org.springframework.data.util.StreamUtils; import org.springframework.data.util.Streamable; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.ReadPreference; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleReactiveMongoRepository.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleReactiveMongoRepository.java index 1c1df2c9a1..7e4a3aa665 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleReactiveMongoRepository.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleReactiveMongoRepository.java @@ -30,6 +30,7 @@ import java.util.function.Function; import java.util.function.UnaryOperator; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.dao.IncorrectResultSizeDataAccessException; @@ -49,7 +50,6 @@ import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.data.mongodb.repository.query.MongoEntityInformation; import org.springframework.data.repository.query.FluentQuery; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.mongodb.ReadPreference; 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 0ef6c38744..cf92c07c28 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 @@ -22,21 +22,18 @@ import java.util.stream.Stream; import org.bson.Document; - +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.ScrollPosition; -import org.springframework.data.domain.Slice; import org.springframework.data.domain.Window; import org.springframework.data.mongodb.core.ExecutableFindOperation; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.repository.util.SliceUtils; import org.springframework.data.support.PageableExecutionUtils; -import org.springframework.lang.Nullable; import com.mysema.commons.lang.CloseableIterator; import com.mysema.commons.lang.EmptyCloseableIterator; @@ -185,20 +182,6 @@ public Page fetchPage(Pageable pageable) { } } - /** - * Fetch a {@link Slice}. - * - * @param pageable defines range and sort of requested slice - * @return new instance of {@link Slice} containing matching results within range. - * @since 4.5 - */ - public Slice fetchSlice(Pageable pageable) { - - List content = find.matching(SliceUtils.limitResult(createQuery(), pageable).with(pageable.getSort())).all(); - - return SliceUtils.sliceResult(content, pageable); - } - @Override public T fetchFirst() { try { 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 d9a550a0f7..854fe2aa1a 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 @@ -20,6 +20,7 @@ import java.util.regex.Pattern; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.convert.QueryMapper; @@ -27,7 +28,6 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -146,8 +146,7 @@ protected boolean isId(Path arg) { } @Override - @Nullable - protected Object convert(@Nullable Path path, @Nullable Constant constant) { + protected @Nullable Object convert(@Nullable Path path, @Nullable Constant constant) { if (constant == null) { return null; @@ -191,8 +190,7 @@ protected Object convert(@Nullable Path path, @Nullable Constant constant) return asReference(constant.getConstant(), path); } - @Nullable - private MongoPersistentProperty getPropertyFor(Path path) { + private @Nullable MongoPersistentProperty getPropertyFor(Path path) { Path parent = path.getMetadata().getParent(); 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 1d0b8beeba..42cd5a0b18 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,6 +1,6 @@ /** * Support infrastructure for query derivation of MongoDB specific repositories. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.repository.support; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java index cbbd4a37a9..25fffd5ffe 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java @@ -40,11 +40,11 @@ import org.bson.types.Binary; import org.bson.types.Decimal128; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.mongodb.CodecRegistryProvider; import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.mongodb.core.mapping.FieldName.Type; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -73,8 +73,7 @@ public class BsonUtils { public static final Document EMPTY_DOCUMENT = new EmptyDocument(); @SuppressWarnings("unchecked") - @Nullable - public static T get(Bson bson, String key) { + public static @Nullable T get(Bson bson, String key) { return (T) asMap(bson).get(key); } @@ -450,8 +449,7 @@ public static Document toDocumentOrElse(String source, Function source, FieldName fieldNam * @return can be {@literal null}. * @since 4.1 */ - @Nullable - public static Object resolveValue(Map source, String key) { + public static @Nullable Object resolveValue(Map source, String key) { if (source.containsKey(key)) { return source.get(key); @@ -745,8 +741,7 @@ public static Document mapEntries(Document source, Function evaluationContext) { return evaluate(value, new ValueEvaluationContext() { - @Nullable @Override - public Environment getEnvironment() { + public @Nullable Environment getEnvironment() { return null; } - @Nullable @Override - public EvaluationContext getEvaluationContext() { + public @Nullable EvaluationContext getEvaluationContext() { return evaluationContext.get(); } }); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/EmptyDocument.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/EmptyDocument.java index ffc97402fe..23ea9409cc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/EmptyDocument.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/EmptyDocument.java @@ -66,9 +66,8 @@ public boolean replace(String key, Object oldValue, Object newValue) { throw new UnsupportedOperationException(); } - @Nullable @Override - public Object replace(String key, Object value) { + public @Nullable Object replace(String key, Object value) { throw new UnsupportedOperationException(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java index 8fc4b108ff..fbbba59e8f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java @@ -15,12 +15,9 @@ */ package org.springframework.data.mongodb.util; -import java.lang.reflect.Field; - +import org.jspecify.annotations.Nullable; import org.springframework.data.util.Version; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; import com.mongodb.internal.build.MongoDriverVersion; @@ -94,14 +91,12 @@ private static Version getMongoDbDriverVersion(ClassLoader classLoader) { return version == null ? guessDriverVersionFromClassPath(classLoader) : version; } - @Nullable - private static Version getVersionFromPackage(ClassLoader classLoader) { + private static @Nullable Version getVersionFromPackage(ClassLoader classLoader) { if (ClassUtils.isPresent("com.mongodb.internal.build.MongoDriverVersion", classLoader)) { try { - Field field = ReflectionUtils.findField(MongoDriverVersion.class, "VERSION"); - return field != null ? Version.parse("" + field.get(null)) : null; - } catch (ReflectiveOperationException | IllegalArgumentException exception) { + return Version.parse(MongoDriverVersion.VERSION); + } catch (IllegalArgumentException exception) { // well not much we can do, right? } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoCompatibilityAdapter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoCompatibilityAdapter.java index f85be98c1f..641ccd274f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoCompatibilityAdapter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoCompatibilityAdapter.java @@ -20,8 +20,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; @@ -174,8 +174,7 @@ public interface IndexOptionsAdapter { } public interface ClientSettingsAdapter { - @Nullable - T getStreamFactoryFactory(); + @Nullable T getStreamFactoryFactory(); } public interface ClientSettingsBuilderAdapter { @@ -202,11 +201,9 @@ public interface MongoDatabaseAdapterBuilder { @SuppressWarnings({ "unchecked", "DataFlowIssue" }) public static class MongoDatabaseAdapter { - @Nullable // - private static final Method LIST_COLLECTION_NAMES_METHOD; + private static final @Nullable Method LIST_COLLECTION_NAMES_METHOD; - @Nullable // - private static final Method LIST_COLLECTION_NAMES_METHOD_SESSION; + private static final @Nullable Method LIST_COLLECTION_NAMES_METHOD_SESSION; private static final Class collectionNamesReturnType; @@ -271,11 +268,9 @@ public interface ReactiveMongoDatabaseAdapterBuilder { @SuppressWarnings({ "unchecked", "DataFlowIssue" }) public static class ReactiveMongoDatabaseAdapter { - @Nullable // - private static final Method LIST_COLLECTION_NAMES_METHOD; + private static final @Nullable Method LIST_COLLECTION_NAMES_METHOD; - @Nullable // - private static final Method LIST_COLLECTION_NAMES_METHOD_SESSION; + private static final @Nullable Method LIST_COLLECTION_NAMES_METHOD_SESSION; private static final Class collectionNamesReturnType; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoDbErrorCodes.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoDbErrorCodes.java index 326a5c1e88..9df6d098ac 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoDbErrorCodes.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoDbErrorCodes.java @@ -17,10 +17,10 @@ import java.util.HashMap; -import org.springframework.lang.Nullable; - import com.mongodb.MongoException; +import org.jspecify.annotations.Nullable; + /** * {@link MongoDbErrorCodes} holds MongoDB specific error codes outlined in {@literal mongo/base/error_codes.yml}. * @@ -140,8 +140,7 @@ public final class MongoDbErrorCodes { errorCodes.putAll(clientSessionCodes); } - @Nullable - public static String getErrorDescription(@Nullable Integer errorCode) { + public static @Nullable String getErrorDescription(@Nullable Integer errorCode) { return errorCode == null ? null : errorCodes.get(errorCode); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/RegexFlags.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/RegexFlags.java index 23c96f9e46..8b0f4b83ce 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/RegexFlags.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/RegexFlags.java @@ -17,7 +17,7 @@ import java.util.regex.Pattern; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Utility to translate {@link Pattern#flags() regex flags} to MongoDB regex options and vice versa. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/aggregation/TestAggregationContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/aggregation/TestAggregationContext.java index 344244717e..950f9ec797 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/aggregation/TestAggregationContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/aggregation/TestAggregationContext.java @@ -17,6 +17,7 @@ import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; @@ -27,7 +28,6 @@ import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; -import org.springframework.lang.Nullable; /** * @author Christoph Strobl diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/encryption/EncryptionUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/encryption/EncryptionUtils.java index 9dd3f1d8fb..be9a2e1cff 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/encryption/EncryptionUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/encryption/EncryptionUtils.java @@ -22,10 +22,10 @@ import org.bson.BsonBinary; import org.bson.BsonBinarySubType; import org.bson.types.Binary; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.util.spel.ExpressionUtils; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -48,8 +48,7 @@ public final class EncryptionUtils { * @return can be {@literal null}. * @throws IllegalArgumentException if one of the required arguments is {@literal null}. */ - @Nullable - public static Object resolveKeyId(String value, Supplier evaluationContext) { + public static @Nullable Object resolveKeyId(String value, Supplier evaluationContext) { Assert.notNull(value, "Value must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/EvaluationContextExpressionEvaluator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/EvaluationContextExpressionEvaluator.java index 6c31a9721f..ff0454cff7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/EvaluationContextExpressionEvaluator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/EvaluationContextExpressionEvaluator.java @@ -18,12 +18,12 @@ import java.util.Collections; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.model.ValueExpressionEvaluator; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.lang.Nullable; /** * @author Christoph Strobl @@ -40,9 +40,8 @@ class EvaluationContextExpressionEvaluator implements ValueExpressionEvaluator { this.expressionParser = expressionParser; } - @Nullable @Override - public T evaluate(String expression) { + public @Nullable T evaluate(String expression) { return evaluateExpression(expression, Collections.emptyMap()); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingContext.java index 5678d959ce..55dccad0c9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingContext.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.model.ValueExpressionEvaluator; import org.springframework.data.spel.ExpressionDependencies; import org.springframework.data.util.Lazy; @@ -27,7 +28,6 @@ import org.springframework.expression.ExpressionParser; import org.springframework.expression.ParseException; import org.springframework.expression.ParserContext; -import org.springframework.lang.Nullable; /** * Reusable context for binding parameters to a placeholder or a SpEL expression within a JSON structure.
@@ -128,18 +128,15 @@ public static ParameterBindingContext forExpressions(ValueProvider valueProvider return new ParameterBindingContext(valueProvider, expressionEvaluator); } - @Nullable - public Object bindableValueForIndex(int index) { + public @Nullable Object bindableValueForIndex(int index) { return valueProvider.getBindableValue(index); } - @Nullable - public Object evaluateExpression(String expressionString) { + public @Nullable Object evaluateExpression(String expressionString) { return expressionEvaluator.evaluate(expressionString); } - @Nullable - public Object evaluateExpression(String expressionString, Map variables) { + public @Nullable Object evaluateExpression(String expressionString, Map variables) { if (expressionEvaluator instanceof EvaluationContextExpressionEvaluator expressionEvaluator) { return expressionEvaluator.evaluateExpression(expressionString, variables); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingDocumentCodec.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingDocumentCodec.java index adce99c904..924ed88067 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingDocumentCodec.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingDocumentCodec.java @@ -40,14 +40,13 @@ import org.bson.codecs.*; import org.bson.codecs.configuration.CodecRegistry; import org.bson.json.JsonParseException; - +import org.jspecify.annotations.Nullable; import org.springframework.data.expression.ValueExpressionParser; import org.springframework.data.mapping.model.ValueExpressionEvaluator; import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.spel.EvaluationContextProvider; import org.springframework.data.spel.ExpressionDependencies; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.lang.Nullable; import org.springframework.util.NumberUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -396,9 +395,8 @@ static class DependencyCapturingExpressionEvaluator implements ValueExpressionEv this.expressionParser = expressionParser; } - @Nullable @Override - public T evaluate(String expression) { + public @Nullable T evaluate(String expression) { dependencies.add(expressionParser.parse(expression).getExpressionDependencies()); return (T) PLACEHOLDER; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java index 8dd42e2427..6610326604 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java @@ -39,10 +39,10 @@ import org.bson.types.MaxKey; import org.bson.types.MinKey; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.springframework.data.spel.EvaluationContextProvider; import org.springframework.expression.EvaluationContext; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.NumberUtils; import org.springframework.util.ObjectUtils; @@ -533,13 +533,11 @@ private BsonType bsonTypeForValue(Object value) { return BsonType.UNDEFINED; } - @Nullable - private Object evaluateExpression(String expressionString) { + private @Nullable Object evaluateExpression(String expressionString) { return bindingContext.evaluateExpression(expressionString, Collections.emptyMap()); } - @Nullable - private Object evaluateExpression(String expressionString, Map variables) { + private @Nullable Object evaluateExpression(String expressionString, Map variables) { return bindingContext.evaluateExpression(expressionString, variables); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ValueProvider.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ValueProvider.java index 8f1d23885d..2ce22214fb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ValueProvider.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ValueProvider.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.util.json; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * A value provider to retrieve bindable values by their parameter index. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/package-info.java index 8a86b3522b..60e5e8c609 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/package-info.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/package-info.java @@ -1,5 +1,5 @@ /** * MongoDB driver-specific utility classes for Json conversion. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.util.json; 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 7caec410f5..a697bb7000 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 @@ -2,5 +2,5 @@ * MongoDB driver-specific utility classes for {@link org.bson.conversions.Bson} and {@link com.mongodb.DBObject} * interaction. */ -@org.springframework.lang.NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.mongodb.util; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/spel/ExpressionUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/spel/ExpressionUtils.java index 9fa66b3b2b..796f618906 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/spel/ExpressionUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/spel/ExpressionUtils.java @@ -17,12 +17,12 @@ import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.ParserContext; import org.springframework.expression.common.LiteralExpression; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; /** @@ -42,8 +42,7 @@ public final class ExpressionUtils { * @param potentialExpression can be {@literal null} * @return can be {@literal null}. */ - @Nullable - public static Expression detectExpression(@Nullable String potentialExpression) { + public static @Nullable Expression detectExpression(@Nullable String potentialExpression) { if (!StringUtils.hasText(potentialExpression)) { return null; @@ -53,8 +52,7 @@ public static Expression detectExpression(@Nullable String potentialExpression) return expression instanceof LiteralExpression ? null : expression; } - @Nullable - public static Object evaluate(String value, Supplier evaluationContext) { + public static @Nullable Object evaluate(String value, Supplier evaluationContext) { Expression expression = detectExpression(value); if (expression == null) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/CapturingTransactionOptionsResolver.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/CapturingTransactionOptionsResolver.java index 0448ad936c..c05122873c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/CapturingTransactionOptionsResolver.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/CapturingTransactionOptionsResolver.java @@ -21,7 +21,7 @@ import org.assertj.core.api.Assertions; import org.assertj.core.api.ListAssert; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.CollectionUtils; /** @@ -36,9 +36,8 @@ public CapturingTransactionOptionsResolver(MongoTransactionOptionsResolver deleg this.delegateResolver = delegateResolver; } - @Nullable @Override - public String getLabelPrefix() { + public @Nullable String getLabelPrefix() { return delegateResolver.getLabelPrefix(); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/MongoTransactionOptionsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/MongoTransactionOptionsUnitTests.java index 44692348a0..d89edc6206 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/MongoTransactionOptionsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/MongoTransactionOptionsUnitTests.java @@ -20,8 +20,8 @@ import java.time.Duration; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; -import org.springframework.lang.Nullable; import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; @@ -90,27 +90,23 @@ void testEquals() { assertThat(MongoTransactionOptions.NONE) // .isSameAs(MongoTransactionOptions.NONE) // .isNotEqualTo(new MongoTransactionOptions() { - @Nullable @Override - public Duration getMaxCommitTime() { + public @Nullable Duration getMaxCommitTime() { return null; } - @Nullable @Override - public ReadConcern getReadConcern() { + public @Nullable ReadConcern getReadConcern() { return null; } - @Nullable @Override - public ReadPreference getReadPreference() { + public @Nullable ReadPreference getReadPreference() { return null; } - @Nullable @Override - public WriteConcern getWriteConcern() { + public @Nullable WriteConcern getWriteConcern() { return null; } }); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoExceptionTranslatorUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoExceptionTranslatorUnitTests.java index 9730e61e51..bdc151ec63 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoExceptionTranslatorUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoExceptionTranslatorUnitTests.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.*; import org.bson.BsonDocument; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -31,7 +32,6 @@ import org.springframework.data.mongodb.ClientSessionException; import org.springframework.data.mongodb.MongoTransactionException; import org.springframework.data.mongodb.UncategorizedMongoDbException; -import org.springframework.lang.Nullable; import com.mongodb.MongoCursorNotFoundException; import com.mongodb.MongoException; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java index 51b3b005a5..9a6bbb4f29 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java @@ -29,6 +29,7 @@ import org.bson.Document; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -48,7 +49,6 @@ import org.springframework.data.mongodb.test.util.Client; import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; -import org.springframework.lang.Nullable; import com.mongodb.client.MongoClient; import com.mongodb.client.model.Filters; @@ -1936,9 +1936,8 @@ public String toString() { static class ReferencableConverter implements Converter> { - @Nullable @Override - public DocumentPointer convert(ReferenceAble source) { + public @Nullable DocumentPointer convert(ReferenceAble source) { return source::toReference; } } @@ -1947,9 +1946,8 @@ public DocumentPointer convert(ReferenceAble source) { static class DocumentToSimpleObjectRefWithReadingConverter implements Converter, SimpleObjectRefWithReadingConverter> { - @Nullable @Override - public SimpleObjectRefWithReadingConverter convert(DocumentPointer source) { + public @Nullable SimpleObjectRefWithReadingConverter convert(DocumentPointer source) { Document document = client.getDatabase(DB_NAME).getCollection("simple-object-ref") .find(Filters.eq("_id", source.getPointer().get("ref-key-from-custom-write-converter"))).first(); @@ -1961,9 +1959,8 @@ public SimpleObjectRefWithReadingConverter convert(DocumentPointer sou static class SimpleObjectRefWithReadingConverterToDocumentConverter implements Converter> { - @Nullable @Override - public DocumentPointer convert(SimpleObjectRefWithReadingConverter source) { + public @Nullable DocumentPointer convert(SimpleObjectRefWithReadingConverter source) { return () -> new Document("ref-key-from-custom-write-converter", source.getId()); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateScrollTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateScrollTests.java index 766929c732..772392f037 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateScrollTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateScrollTests.java @@ -26,6 +26,7 @@ import java.util.stream.Stream; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -47,7 +48,6 @@ import org.springframework.data.mongodb.test.util.Client; import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import com.mongodb.client.MongoClient; 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 5d701de5f6..ee01de7ebc 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 @@ -35,6 +35,7 @@ import java.util.stream.Stream; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -90,7 +91,6 @@ import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.MongoTestUtils; import org.springframework.data.mongodb.test.util.MongoVersion; -import org.springframework.lang.Nullable; import org.springframework.test.annotation.DirtiesContext; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; 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 79a0bb1fcb..b5892c2ca0 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 @@ -39,6 +39,7 @@ import org.bson.Document; import org.bson.conversions.Bson; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -99,7 +100,6 @@ import org.springframework.data.mongodb.core.timeseries.Granularity; import org.springframework.data.mongodb.util.BsonUtils; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; -import org.springframework.lang.Nullable; import org.springframework.mock.env.MockEnvironment; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.util.CollectionUtils; @@ -2908,8 +2908,7 @@ public List getValues() { return values; } - @Nullable - public T getValue() { + public @Nullable T getValue() { return CollectionUtils.lastElement(values); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java index 18da8c516d..fd1b70f3c7 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java @@ -25,6 +25,7 @@ import java.util.Set; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -39,7 +40,6 @@ import org.springframework.data.mongodb.core.schema.MongoJsonSchema; import org.springframework.data.mongodb.test.util.Client; import org.springframework.data.mongodb.test.util.MongoClientExtension; -import org.springframework.lang.Nullable; import org.springframework.test.context.junit.jupiter.SpringExtension; import com.mongodb.client.MongoClient; @@ -242,13 +242,11 @@ public SimpleBean(@Nullable String nonNullString, @Nullable Integer rangedIntege this.customFieldName = customFieldName; } - @Nullable - public String getNonNullString() { + public @Nullable String getNonNullString() { return this.nonNullString; } - @Nullable - public Integer getRangedInteger() { + public @Nullable Integer getRangedInteger() { return this.rangedInteger; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/Person.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/Person.java index bc126e05f0..7b07cd9448 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/Person.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/Person.java @@ -16,7 +16,7 @@ package org.springframework.data.mongodb.core; import org.bson.types.ObjectId; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; public class Person { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java index f89b2fa8c1..5ba0d947fe 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java @@ -43,6 +43,7 @@ import org.bson.Document; import org.bson.conversions.Bson; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -93,7 +94,6 @@ import org.springframework.data.mongodb.core.timeseries.Granularity; import org.springframework.data.mongodb.util.BsonUtils; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; -import org.springframework.lang.Nullable; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.util.CollectionUtils; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TransactionOptionsTestService.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TransactionOptionsTestService.java index 8968f53a74..b8cc9cc972 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TransactionOptionsTestService.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TransactionOptionsTestService.java @@ -18,7 +18,7 @@ import java.util.function.Function; import java.util.function.UnaryOperator; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.transaction.annotation.Transactional; /** @@ -48,45 +48,38 @@ public T saveWithinMaxCommitTime(T entity) { return saveFunction.apply(entity); } - @Nullable @Transactional(transactionManager = "txManager", label = { "mongo:readConcern=available" }) - public T availableReadConcernFind(Object id) { + public @Nullable T availableReadConcernFind(Object id) { return findByIdFunction.apply(id); } - @Nullable @Transactional(transactionManager = "txManager", label = { "mongo:readConcern=invalid" }) - public T invalidReadConcernFind(Object id) { + public @Nullable T invalidReadConcernFind(Object id) { return findByIdFunction.apply(id); } - @Nullable @Transactional(transactionManager = "txManager", label = { "mongo:readConcern=${tx.read.concern}" }) - public T environmentReadConcernFind(Object id) { + public @Nullable T environmentReadConcernFind(Object id) { return findByIdFunction.apply(id); } - @Nullable @Transactional(transactionManager = "txManager", label = { "mongo:readConcern=majority" }) - public T majorityReadConcernFind(Object id) { + public @Nullable T majorityReadConcernFind(Object id) { return findByIdFunction.apply(id); } - @Nullable @Transactional(transactionManager = "txManager", label = { "mongo:readPreference=primaryPreferred" }) - public T findFromPrimaryPreferredReplica(Object id) { + public @Nullable T findFromPrimaryPreferredReplica(Object id) { return findByIdFunction.apply(id); } - @Nullable @Transactional(transactionManager = "txManager", label = { "mongo:readPreference=invalid" }) - public T findFromInvalidReplica(Object id) { + public @Nullable T findFromInvalidReplica(Object id) { return findByIdFunction.apply(id); } - @Nullable @Transactional(transactionManager = "txManager", label = { "mongo:readPreference=primary" }) - public T findFromPrimaryReplica(Object id) { + public @Nullable T findFromPrimaryReplica(Object id) { return findByIdFunction.apply(id); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/UpdateOperationsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/UpdateOperationsUnitTests.java index d4c2f37f63..61cd3ecce4 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/UpdateOperationsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/UpdateOperationsUnitTests.java @@ -20,6 +20,8 @@ import java.util.Arrays; import org.bson.Document; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.mongodb.CodecRegistryProvider; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; @@ -29,8 +31,6 @@ import org.springframework.data.mongodb.core.convert.UpdateMapper; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; import com.mongodb.MongoClientSettings; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/User.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/User.java index 25fbbbcb83..e9eae082e3 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/User.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/User.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; public class User { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java index 32c6d43220..3256b889d4 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java @@ -20,13 +20,13 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; -import org.springframework.lang.Nullable; /** * Unit tests for {@link AddFieldsOperation}. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/DensifyOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/DensifyOperationUnitTests.java index 47176fd8ab..d830a44582 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/DensifyOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/DensifyOperationUnitTests.java @@ -19,6 +19,7 @@ import java.util.Date; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.mongodb.core.aggregation.DensifyOperation.DensifyUnits; import org.springframework.data.mongodb.core.aggregation.DensifyOperation.Range; @@ -27,7 +28,6 @@ import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; -import org.springframework.lang.Nullable; /** * Unit tests for {@link DensifyOperation}. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperationUnitTests.java index 9496a51c03..1b9aba1ba0 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperationUnitTests.java @@ -20,6 +20,7 @@ import java.util.Arrays; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.annotation.Id; import org.springframework.data.geo.Distance; @@ -33,7 +34,6 @@ import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.lang.Nullable; /** * Unit tests for {@link GeoNearOperation}. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MergeOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MergeOperationUnitTests.java index 311496ba8d..18980f6a06 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MergeOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MergeOperationUnitTests.java @@ -23,6 +23,7 @@ import java.util.Arrays; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.Sum; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; @@ -30,7 +31,6 @@ import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; -import org.springframework.lang.Nullable; /** * Unit tests for {@link MergeOperation}. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/RedactOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/RedactOperationUnitTests.java index 24566089e7..d29e32a988 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/RedactOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/RedactOperationUnitTests.java @@ -20,6 +20,7 @@ import java.util.Arrays; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver; @@ -27,7 +28,6 @@ import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.lang.Nullable; /** * Unit tests for {@link RedactOperation}. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java index 093d4af7a0..82ad4c223f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java @@ -20,6 +20,7 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; @@ -27,7 +28,6 @@ import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; -import org.springframework.lang.Nullable; /** * Unit tests for {@link SetOperation}. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java index b5f5f596e6..18eb659cd0 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java @@ -20,6 +20,7 @@ import java.util.Date; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; @@ -30,7 +31,6 @@ import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; -import org.springframework.lang.Nullable; /** * Unit tests for {@link SetWindowFieldsOperation}. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/UnionWithOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/UnionWithOperationUnitTests.java index e47fea289e..ef514ca882 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/UnionWithOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/UnionWithOperationUnitTests.java @@ -21,13 +21,13 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; -import org.springframework.lang.Nullable; /** * Unit tests for {@link UnionWithOperation}. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/UnsetOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/UnsetOperationUnitTests.java index 2f081cc9fc..c406b89626 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/UnsetOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/UnsetOperationUnitTests.java @@ -22,6 +22,7 @@ import java.util.Collections; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; @@ -29,7 +30,6 @@ import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; -import org.springframework.lang.Nullable; /** * Unit tests for {@link UnsetOperation}. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java index 787e8d6746..71c395e822 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java @@ -34,6 +34,7 @@ import org.bson.Document; import org.bson.conversions.Bson; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledForJreRange; @@ -55,7 +56,6 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; -import org.springframework.lang.Nullable; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.util.SerializationUtils; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index a343d15c7e..5bd7e06b97 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -40,6 +40,8 @@ import org.bson.types.Code; import org.bson.types.Decimal128; import org.bson.types.ObjectId; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -104,8 +106,6 @@ import org.springframework.data.projection.EntityProjection; import org.springframework.data.projection.EntityProjectionIntrospector; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; import org.springframework.test.util.ReflectionTestUtils; import com.mongodb.BasicDBList; @@ -3167,15 +3167,14 @@ void beanConverter() { registrar.registerConverter(WithValueConverters.class, "viaRegisteredConverter", new PropertyValueConverter() { - @Nullable @Override - public String read(@Nullable org.bson.Document nativeValue, MongoConversionContext context) { + public @Nullable String read(org.bson.@Nullable Document nativeValue, MongoConversionContext context) { return nativeValue.getString("bar"); } - @Nullable + @Override - public org.bson.Document write(@Nullable String domainValue, MongoConversionContext context) { + public org.bson.@Nullable Document write(@Nullable String domainValue, MongoConversionContext context) { return new org.bson.Document("bar", domainValue); } }); @@ -4214,9 +4213,9 @@ public SubTypeOfGenericType convert(org.bson.Document source) { @WritingConverter static class TypeImplementingMapToDocumentConverter implements Converter { - @Nullable + @Override - public org.bson.Document convert(TypeImplementingMap source) { + public org.bson.@Nullable Document convert(TypeImplementingMap source) { return new org.bson.Document("1st", source.val1).append("2nd", source.val2); } } @@ -4224,9 +4223,8 @@ public org.bson.Document convert(TypeImplementingMap source) { @ReadingConverter static class DocumentToTypeImplementingMapConverter implements Converter { - @Nullable @Override - public TypeImplementingMap convert(org.bson.Document source) { + public @Nullable TypeImplementingMap convert(org.bson.Document source) { return new TypeImplementingMap(source.getString("1st"), source.getInteger("2nd")); } } @@ -4412,30 +4410,28 @@ enum Converter2 implements MongoValueConverter { INSTANCE; - @Nullable @Override - public String read(@Nullable org.bson.Document value, MongoConversionContext context) { + public @Nullable String read(org.bson.@Nullable Document value, MongoConversionContext context) { return value.getString("bar"); } - @Nullable + @Override - public org.bson.Document write(@Nullable String value, MongoConversionContext context) { + public org.bson.@Nullable Document write(@Nullable String value, MongoConversionContext context) { return new org.bson.Document("bar", value); } } static class Converter1 implements MongoValueConverter { - @Nullable @Override - public String read(@Nullable org.bson.Document value, MongoConversionContext context) { + public @Nullable String read(org.bson.@Nullable Document value, MongoConversionContext context) { return value.getString("foo"); } - @Nullable + @Override - public org.bson.Document write(@Nullable String value, MongoConversionContext context) { + public org.bson.@Nullable Document write(@Nullable String value, MongoConversionContext context) { return new org.bson.Document("foo", value); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ReversingValueConverter.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ReversingValueConverter.java index eb3b1aba1a..0fe791784d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ReversingValueConverter.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ReversingValueConverter.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core.convert; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * @author Christoph Strobl diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/TextQueryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/TextQueryTests.java index 6ea0f5aa9c..b12b83fe3a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/TextQueryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/TextQueryTests.java @@ -21,6 +21,7 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -35,7 +36,6 @@ import org.springframework.data.mongodb.test.util.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; -import org.springframework.lang.Nullable; /** * @author Christoph Strobl diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java index 3e5f416caf..a7fba9a046 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java @@ -28,6 +28,7 @@ import org.bson.Document; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -48,7 +49,6 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.data.mongodb.repository.support.ReactiveMongoRepositoryFactory; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StopWatch; import org.springframework.util.StringUtils; @@ -99,9 +99,8 @@ public void setUp() throws Exception { converter = new MappingMongoConverter(new DbRefResolver() { - @Nullable @Override - public Object resolveReference(MongoPersistentProperty property, Object source, + public @Nullable Object resolveReference(MongoPersistentProperty property, Object source, ReferenceLookupDelegate referenceLookupDelegate, MongoEntityReader entityReader) { return null; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Address.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Address.java index 534f44c8fb..be5be2d9ba 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Address.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Address.java @@ -14,8 +14,7 @@ * limitations under the License. */ package org.springframework.data.mongodb.repository; - -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.ObjectUtils; import com.querydsl.core.annotations.QueryEmbeddable; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoRepositoryTextSearchIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoRepositoryTextSearchIntegrationTests.java index c41abf4aa1..e0c2caee31 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoRepositoryTextSearchIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoRepositoryTextSearchIntegrationTests.java @@ -20,6 +20,7 @@ import java.util.Arrays; import java.util.List; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -38,7 +39,6 @@ import org.springframework.data.mongodb.test.util.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MyId.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MyId.java index 3dace8928b..4e589d5892 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MyId.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MyId.java @@ -17,7 +17,7 @@ import java.io.Serializable; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Person.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Person.java index 664b5279c8..eeca60bc3e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Person.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Person.java @@ -21,6 +21,7 @@ import java.util.Set; import java.util.UUID; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; import org.springframework.data.mongodb.core.index.GeoSpatialIndexType; import org.springframework.data.mongodb.core.index.GeoSpatialIndexed; @@ -30,7 +31,6 @@ import org.springframework.data.mongodb.core.mapping.DocumentReference; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.Unwrapped; -import org.springframework.lang.Nullable; /** * Sample domain class. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java index c66b554078..93a293ecff 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java @@ -23,6 +23,7 @@ import java.util.regex.Pattern; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Limit; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -43,7 +44,6 @@ import org.springframework.data.mongodb.repository.Person.Sex; import org.springframework.data.querydsl.QuerydslPredicateExecutor; import org.springframework.data.repository.query.Param; -import org.springframework.lang.Nullable; /** * Sample repository managing {@link Person} entities. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryTransactionalTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryTransactionalTests.java index 0af684b9c1..b2b350dc4d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryTransactionalTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryTransactionalTests.java @@ -27,6 +27,7 @@ import org.bson.Document; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -46,7 +47,6 @@ import org.springframework.data.mongodb.test.util.EnableIfReplicaSetAvailable; import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.data.mongodb.test.util.ReplSetClient; -import org.springframework.lang.Nullable; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.transaction.AfterTransaction; @@ -205,9 +205,8 @@ private AfterTransactionAssertion assertAfterTransaction(Person person) { AfterTransactionAssertion assertion = new AfterTransactionAssertion<>(new Persistable() { - @Nullable @Override - public Object getId() { + public @Nullable Object getId() { return person.id; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/SimpleReactiveMongoRepositoryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/SimpleReactiveMongoRepositoryTests.java index 9198e002c0..751fc51ded 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/SimpleReactiveMongoRepositoryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/SimpleReactiveMongoRepositoryTests.java @@ -26,6 +26,7 @@ import java.util.Objects; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; @@ -48,7 +49,6 @@ import org.springframework.data.mongodb.repository.support.SimpleReactiveMongoRepository; import org.springframework.data.mongodb.test.util.EnableIfReplicaSetAvailable; import org.springframework.data.repository.query.FluentQuery; -import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.TransactionDefinition; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexId.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexId.java index 606cca8647..c3bb9cb724 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexId.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexId.java @@ -15,9 +15,9 @@ */ package org.springframework.data.mongodb.repository; +import org.jspecify.annotations.Nullable; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/VersionedPerson.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/VersionedPerson.java index 294e4ea501..4f1adc714e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/VersionedPerson.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/VersionedPerson.java @@ -17,9 +17,9 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.springframework.data.annotation.Version; import org.springframework.data.mongodb.core.mapping.Document; -import org.springframework.lang.Nullable; /** * @author Christoph Strobl @@ -48,8 +48,7 @@ public String getFirstname() { return this.firstname; } - @Nullable - public String getLastname() { + public @Nullable String getLastname() { return this.lastname; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregationUnitTests.java index b4bc48cadf..b55ee77732 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedAggregationUnitTests.java @@ -27,6 +27,7 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -57,7 +58,6 @@ import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.repository.reactive.ReactiveCrudRepository; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import com.mongodb.ReadPreference; @@ -239,14 +239,12 @@ private Class inputTypeOf(AggregationInvocation invocation) { return invocation.aggregation.getInputType(); } - @Nullable - private Collation collationOf(AggregationInvocation invocation) { + private @Nullable Collation collationOf(AggregationInvocation invocation) { return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().getCollation().orElse(null) : null; } - @Nullable - private Object hintOf(AggregationInvocation invocation) { + private @Nullable Object hintOf(AggregationInvocation invocation) { return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().getHintObject().orElse(null) : null; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedAggregationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedAggregationUnitTests.java index 463bb2a22a..827168007e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedAggregationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedAggregationUnitTests.java @@ -27,6 +27,7 @@ import java.util.stream.Stream; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -64,7 +65,6 @@ import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; import org.springframework.data.repository.query.ValueExpressionDelegate; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import com.mongodb.MongoClientSettings; @@ -323,14 +323,12 @@ private Class inputTypeOf(AggregationInvocation invocation) { return invocation.aggregation.getInputType(); } - @Nullable - private Collation collationOf(AggregationInvocation invocation) { + private @Nullable Collation collationOf(AggregationInvocation invocation) { return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().getCollation().orElse(null) : null; } - @Nullable - private Object hintOf(AggregationInvocation invocation) { + private @Nullable Object hintOf(AggregationInvocation invocation) { return invocation.aggregation.getOptions() != null ? invocation.aggregation.getOptions().getHintObject().orElse(null) : null; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StubParameterAccessor.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StubParameterAccessor.java index 1927378e80..30ed064e00 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StubParameterAccessor.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StubParameterAccessor.java @@ -18,6 +18,7 @@ import java.util.Arrays; import java.util.Iterator; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Range; import org.springframework.data.domain.Range.Bound; @@ -30,7 +31,6 @@ import org.springframework.data.mongodb.core.query.TextCriteria; import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.lang.Nullable; /** * Simple {@link ParameterAccessor} that returns the given parameters unfiltered. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MappingContextConfigurer.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MappingContextConfigurer.java index 15a0538600..eda1e501a0 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MappingContextConfigurer.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MappingContextConfigurer.java @@ -20,7 +20,7 @@ import java.util.HashSet; import java.util.Set; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Utility to configure {@link org.springframework.data.mongodb.core.mapping.MongoMappingContext} properties. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestTemplateConfiguration.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestTemplateConfiguration.java index 09149c02ef..8300690ccd 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestTemplateConfiguration.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestTemplateConfiguration.java @@ -20,6 +20,7 @@ import java.util.function.Consumer; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.beans.factory.ObjectFactory; import org.springframework.context.ApplicationContext; @@ -39,7 +40,6 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback; import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent; -import org.springframework.lang.Nullable; /** * @author Christoph Strobl From 5e2e445d9fafc162f4f9f102b0b3a93bede2d731 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 12 Mar 2025 15:57:50 +0100 Subject: [PATCH 13/17] start fixing it --- .../data/mongodb/MongoTransactionOptions.java | 7 ++- .../SessionAwareMethodInterceptor.java | 1 + .../SimpleMongoTransactionOptions.java | 8 ++-- .../config/MongoConfigurationSupport.java | 6 ++- .../data/mongodb/core/MongoOperations.java | 3 +- .../data/mongodb/core/MongoTemplate.java | 8 ++-- .../core/convert/LazyLoadingProxyFactory.java | 3 +- .../core/convert/MappingMongoConverter.java | 45 +++++++++++-------- .../core/convert/MongoCustomConversions.java | 2 +- .../mongodb/core/convert/QueryMapper.java | 18 +++++--- .../mapping/BasicMongoPersistentEntity.java | 19 +++++--- .../data/mongodb/core/mapping/MongoField.java | 5 ++- .../core/mapping/MongoPersistentEntity.java | 3 +- .../data/mongodb/core/query/Criteria.java | 2 +- .../data/mongodb/util/BsonUtils.java | 9 +++- .../core/query/TypedUpdateExtensions.kt | 2 +- 16 files changed, 86 insertions(+), 55 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java index e8ad1c713b..7bb1ac980c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java @@ -92,9 +92,8 @@ default MongoTransactionOptions mergeWith(@Nullable MongoTransactionOptions fall : fallbackOptions.getReadConcern(); } - @Nullable @Override - public ReadPreference getReadPreference() { + public @Nullable ReadPreference getReadPreference() { return MongoTransactionOptions.this.hasReadPreference() ? MongoTransactionOptions.this.getReadPreference() : fallbackOptions.getReadPreference(); } @@ -121,8 +120,8 @@ default T map(Function mappingFunction) { * @return MongoDB driver native {@link TransactionOptions}. * @see MongoTransactionOptions#map(Function) */ - @Nullable - default TransactionOptions toDriverOptions() { + @SuppressWarnings("NullAway") + default @Nullable TransactionOptions toDriverOptions() { return map(it -> { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java index 76d718b1e4..beff621bcb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java @@ -101,6 +101,7 @@ public SessionAwareMethodInterceptor(ClientSession session, T target, Class< if (requiresDecoration(methodInvocation.getMethod())) { Object target = methodInvocation.proceed(); + Assert.notNull(target, "invocation target was null"); if (target instanceof Proxy) { return target; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java index 0dfe5d9e5a..321125458f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java @@ -41,10 +41,10 @@ class SimpleMongoTransactionOptions implements MongoTransactionOptions { static final Set KNOWN_KEYS = Arrays.stream(OptionKey.values()).map(OptionKey::getKey) .collect(Collectors.toSet()); - private final Duration maxCommitTime; - private final ReadConcern readConcern; - private final ReadPreference readPreference; - private final WriteConcern writeConcern; + private final @Nullable Duration maxCommitTime; + private final @Nullable ReadConcern readConcern; + private final @Nullable ReadPreference readPreference; + private final @Nullable WriteConcern writeConcern; static SimpleMongoTransactionOptions of(Map options) { return new SimpleMongoTransactionOptions(options); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java index 0594f6176c..1d1903ee10 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java @@ -35,6 +35,7 @@ import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -172,8 +173,11 @@ protected Set> scanForEntities(String basePackage) throws ClassNotFound for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) { + String beanClassName = candidate.getBeanClassName(); + Assert.notNull(beanClassName, "BeanClassName cannot be null"); + initialEntitySet - .add(ClassUtils.forName(candidate.getBeanClassName(), MongoConfigurationSupport.class.getClassLoader())); + .add(ClassUtils.forName(beanClassName, MongoConfigurationSupport.class.getClassLoader())); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java index 6d604bef37..475a659025 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java @@ -195,7 +195,8 @@ default SessionScoped withSession(Supplier sessionProvider) { private @Nullable ClientSession session; @Override - public T execute(SessionCallback action, Consumer onComplete) { + @SuppressWarnings("NullAway") + public @Nullable T execute(SessionCallback action, Consumer onComplete) { lock.executeWithoutResult(() -> { 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 0be01a0465..bb187095d7 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 @@ -3309,9 +3309,9 @@ private class ProjectingReadCallback implements DocumentCallback { @SuppressWarnings("unchecked") public T doWith(Document document) { - if (document == null) { - return null; - } +// if (document == null) { +// return null; +// } maybeEmitEvent(new AfterLoadEvent<>(document, projection.getMappedType().getType(), collectionName)); @@ -3554,8 +3554,6 @@ public void close() { throw potentiallyConvertRuntimeException(ex, exceptionTranslator); } finally { cursor = null; - exceptionTranslator = null; - objectReadCallback = null; } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java index bb5f582468..739d57f6ed 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java @@ -191,6 +191,7 @@ public static class LazyLoadingInterceptor * @return a {@link LazyLoadingInterceptor} that just continues with the invocation. * @since 4.0 */ + @SuppressWarnings("NullAway") public static LazyLoadingInterceptor none() { return new LazyLoadingInterceptor(null, null, null, null) { @@ -223,7 +224,7 @@ public LazyLoadingInterceptor(MongoPersistentProperty property, DbRefResolverCal } @Override - public @Nullable Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable { + public @Nullable Object intercept(Object o, Method method, Object @Nullable[] 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/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index e729ab8df3..84e8964705 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 @@ -53,6 +53,7 @@ import org.springframework.core.env.StandardEnvironment; import org.springframework.data.annotation.Reference; import org.springframework.data.convert.CustomConversions; +import org.springframework.data.convert.PropertyValueConversions; import org.springframework.data.convert.PropertyValueConverter; import org.springframework.data.convert.TypeMapper; import org.springframework.data.convert.ValueConversionContext; @@ -156,7 +157,7 @@ public class MappingMongoConverter extends AbstractMongoConverter protected @Nullable ApplicationContext applicationContext; protected @Nullable Environment environment; - protected MongoTypeMapper typeMapper; + protected @Nullable MongoTypeMapper typeMapper; protected @Nullable String mapKeyDotReplacement = null; protected @Nullable CodecRegistryProvider codecRegistryProvider; @@ -306,7 +307,9 @@ public void setApplicationContext(ApplicationContext applicationContext) throws this.environment = applicationContext.getEnvironment(); this.spELContext = new SpELContext(this.spELContext, applicationContext); this.projectionFactory.setBeanFactory(applicationContext); - this.projectionFactory.setBeanClassLoader(applicationContext.getClassLoader()); + if(applicationContext.getClassLoader() != null) { + this.projectionFactory.setBeanClassLoader(applicationContext.getClassLoader()); + } if (entityCallbacks == null) { setEntityCallbacks(EntityCallbacks.create(applicationContext)); @@ -432,12 +435,12 @@ static class MapPersistentPropertyAccessor implements PersistentPropertyAccessor Map map = new LinkedHashMap<>(); @Override - public void setProperty(PersistentProperty persistentProperty, Object o) { + public void setProperty(PersistentProperty persistentProperty, @Nullable Object o) { map.put(persistentProperty.getName(), o); } @Override - public Object getProperty(PersistentProperty persistentProperty) { + public @Nullable Object getProperty(PersistentProperty persistentProperty) { return map.get(persistentProperty.getName()); } @@ -544,7 +547,7 @@ public EvaluatingDocumentAccessor(Bson document) { } @Override - public T evaluate(String expression) { + public @Nullable T evaluate(String expression) { return expressionEvaluatorFactory.create(getDocument()).evaluate(expression); } } @@ -742,8 +745,7 @@ && peek(collection) instanceof Document) { } } - @Nullable - private Object readUnwrapped(ConversionContext context, DocumentAccessor documentAccessor, + private @Nullable Object readUnwrapped(ConversionContext context, DocumentAccessor documentAccessor, MongoPersistentProperty prop, MongoPersistentEntity unwrappedEntity) { if (prop.findAnnotation(Unwrapped.class).onEmpty().equals(OnEmpty.USE_EMPTY)) { @@ -765,7 +767,7 @@ public DBRef toDBRef(Object object, @Nullable MongoPersistentProperty referringP if (referringProperty != null) { annotation = referringProperty.getDBRef(); - Assert.isTrue(annotation != null, "The referenced property has to be mapped with @DBRef"); + Assert.notNull(annotation, "The referenced property has to be mapped with @DBRef"); } // DATAMONGO-913 @@ -1339,8 +1341,13 @@ private void writeSimpleInternal(@Nullable Object value, Bson bson, MongoPersist return (T) persistentPropertyAccessor.getProperty(property); } }, property, this, spELContext); - PropertyValueConverter> valueConverter = conversions - .getPropertyValueConversions().getValueConverter(property); + + PropertyValueConversions propertyValueConversions = conversions.getPropertyValueConversions(); + if(propertyValueConversions == null) { + return value; + } + + PropertyValueConverter> valueConverter = propertyValueConversions.getValueConverter(property); return value != null ? valueConverter.write(value, context) : valueConverter.writeNull(context); } @@ -2341,15 +2348,15 @@ protected static class DefaultConversionContext implements ConversionContext { final ObjectPath path; final ContainerValueConverter documentConverter; final ContainerValueConverter> collectionConverter; - final ContainerValueConverter mapConverter; - final ContainerValueConverter dbRefConverter; - final ValueConverter elementConverter; + final ContainerValueConverter<@Nullable Bson> mapConverter; + final ContainerValueConverter<@Nullable DBRef> dbRefConverter; + final ValueConverter<@Nullable Object> elementConverter; DefaultConversionContext(MongoConverter sourceConverter, org.springframework.data.convert.CustomConversions customConversions, ObjectPath path, - ContainerValueConverter documentConverter, ContainerValueConverter> collectionConverter, - ContainerValueConverter mapConverter, ContainerValueConverter dbRefConverter, - ValueConverter elementConverter) { + ContainerValueConverter<@Nullable Bson> documentConverter, ContainerValueConverter> collectionConverter, + ContainerValueConverter<@Nullable Bson> mapConverter, ContainerValueConverter<@Nullable DBRef> dbRefConverter, + ValueConverter<@Nullable Object> elementConverter) { this.sourceConverter = sourceConverter; this.conversions = customConversions; @@ -2453,9 +2460,9 @@ interface ValueConverter { * * @param */ - interface ContainerValueConverter { + interface ContainerValueConverter<@Nullable T> { - Object convert(ConversionContext context, T source, TypeInformation typeHint); + @Nullable Object convert(ConversionContext context, @Nullable T source, TypeInformation typeHint); } @@ -2470,7 +2477,7 @@ class ProjectingConversionContext extends DefaultConversionContext { ProjectingConversionContext(MongoConverter sourceConverter, CustomConversions customConversions, ObjectPath path, ContainerValueConverter> collectionConverter, ContainerValueConverter mapConverter, - ContainerValueConverter dbRefConverter, ValueConverter elementConverter, + ContainerValueConverter<@Nullable DBRef> dbRefConverter, ValueConverter elementConverter, EntityProjection projection) { super(sourceConverter, customConversions, path, (context, source, typeHint) -> doReadOrProject(context, source, typeHint, projection), 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 964ecb6b65..fa57f2cab4 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 @@ -137,7 +137,7 @@ public Set getConvertibleTypes() { return new HashSet<>(Arrays.asList(localeToString, booleanToString)); } - public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + public @Nullable 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/QueryMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java index 27583a2e50..6c739a8563 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 @@ -66,6 +66,7 @@ import org.springframework.data.mongodb.util.BsonUtils; import org.springframework.data.mongodb.util.DotPath; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -274,6 +275,7 @@ public Document addMetaAttributes(Document source, @Nullable MongoPersistentEnti return mapMetaAttributes(source, entity, MetaMapping.FORCE); } + @SuppressWarnings("NullAway") private Document mapMetaAttributes(Document source, @Nullable MongoPersistentEntity entity, MetaMapping metaMapping) { @@ -346,7 +348,7 @@ private Document getMappedTextScoreField(MongoPersistentProperty property) { * @param rawValue * @return */ - protected Entry getMappedObjectForField(Field field, Object rawValue) { + protected Entry getMappedObjectForField(Field field, @Nullable Object rawValue) { String key = field.getMappedKey(); Object value; @@ -410,7 +412,9 @@ protected Document getMappedKeyword(Keyword keyword, @Nullable MongoPersistentEn } if (keyword.isSample()) { - return exampleMapper.getMappedExample(keyword.getValue(), entity); + + Example example = keyword.getValue(); + return exampleMapper.getMappedExample(example, entity != null ? entity : mappingContext.getRequiredPersistentEntity(example.getProbeType())); } if (keyword.isJsonSchema()) { @@ -451,8 +455,8 @@ protected Document getMappedKeyword(Field property, Keyword keyword) { * @param sourceValue the source object to be mapped * @return */ - @SuppressWarnings("unchecked") - protected @Nullable Object getMappedValue(Field documentField, Object sourceValue) { + @SuppressWarnings("NullAway") + protected @Nullable Object getMappedValue(Field documentField, @Nullable Object sourceValue) { Object value = applyFieldTargetTypeHintToValue(documentField, sourceValue); @@ -489,6 +493,7 @@ private boolean isIdField(Field documentField) { && documentField.getProperty().getOwner().isIdProperty(documentField.getProperty()); } + @SuppressWarnings("NullAway") private Class getIdTypeForField(Field documentField) { return isIdField(documentField) ? documentField.getProperty().getFieldType() : ObjectId.class; } @@ -527,7 +532,7 @@ protected boolean isAssociationConversionNecessary(Field documentField, @Nullabl } MongoPersistentEntity entity = documentField.getPropertyEntity(); - return entity.hasIdProperty() + return entity != null && entity.hasIdProperty() && (type.equals(DBRef.class) || entity.getRequiredIdProperty().getActualType().isAssignableFrom(type)); } @@ -660,7 +665,7 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers return createReferenceFor(source, property); } - private @Nullable Object convertValue(Field documentField, Object sourceValue, Object value, + private @Nullable Object convertValue(Field documentField, @Nullable Object sourceValue, @Nullable Object value, PropertyValueConverter> valueConverter) { MongoPersistentProperty property = documentField.getProperty(); @@ -828,6 +833,7 @@ private Object createReferenceFor(Object source, MongoPersistentProperty propert * @param candidate * @return */ + @Contract("null -> false") protected boolean isNestedKeyword(@Nullable Object candidate) { if (!(candidate instanceof Document)) { 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 6e888c7c9f..e524a2602c 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 @@ -36,6 +36,7 @@ import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.model.BasicPersistentEntity; import org.springframework.data.mongodb.MongoCollectionUtils; +import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.util.encryption.EncryptionUtils; import org.springframework.data.spel.ExpressionDependencies; import org.springframework.data.util.Lazy; @@ -150,7 +151,7 @@ public boolean hasTextScoreProperty() { } @Override - public org.springframework.data.mongodb.core.query.Collation getCollation() { + public @Nullable Collation getCollation() { Object collationValue = collationExpression != null ? collationExpression.evaluate(getValueEvaluationContext(null)) @@ -193,17 +194,17 @@ public EvaluationContext getEvaluationContext(Object rootObject) { } @Override - public EvaluationContext getEvaluationContext(Object rootObject, ExpressionDependencies dependencies) { + public EvaluationContext getEvaluationContext(@Nullable Object rootObject, ExpressionDependencies dependencies) { return super.getEvaluationContext(rootObject, dependencies); } @Override - public ValueEvaluationContext getValueEvaluationContext(Object rootObject) { + public ValueEvaluationContext getValueEvaluationContext(@Nullable Object rootObject) { return super.getValueEvaluationContext(rootObject); } @Override - public ValueEvaluationContext getValueEvaluationContext(Object rootObject, ExpressionDependencies dependencies) { + public ValueEvaluationContext getValueEvaluationContext(@Nullable Object rootObject, ExpressionDependencies dependencies) { return super.getValueEvaluationContext(rootObject, dependencies); } @@ -242,7 +243,11 @@ public int compare(@Nullable MongoPersistentProperty o1, @Nullable MongoPersiste return -1; } - return o1.getFieldOrder() - o2.getFieldOrder(); + if(o1 != null && o2 != null) { + return o1.getFieldOrder() - o2.getFieldOrder(); + } + + return o1.getFieldOrder(); } } @@ -256,7 +261,7 @@ public int compare(@Nullable MongoPersistentProperty o1, @Nullable MongoPersiste * @return can be {@literal null}. */ @Override - protected MongoPersistentProperty returnPropertyIfBetterIdPropertyCandidateOrNull(MongoPersistentProperty property) { + protected @Nullable MongoPersistentProperty returnPropertyIfBetterIdPropertyCandidateOrNull(MongoPersistentProperty property) { Assert.notNull(property, "MongoPersistentProperty must not be null"); @@ -267,7 +272,7 @@ protected MongoPersistentProperty returnPropertyIfBetterIdPropertyCandidateOrNul MongoPersistentProperty currentIdProperty = getIdProperty(); boolean currentIdPropertyIsSet = currentIdProperty != null; - @SuppressWarnings("null") + @SuppressWarnings("NullAway") boolean currentIdPropertyIsExplicit = currentIdPropertyIsSet && currentIdProperty.isExplicitIdProperty(); boolean newIdPropertyIsExplicit = property.isExplicitIdProperty(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoField.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoField.java index 6f0e1ae4c3..80d7c120f7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoField.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoField.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.core.mapping; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.FieldName.Type; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -139,7 +140,7 @@ public String toString() { */ public static class MongoFieldBuilder { - private String name; + private @Nullable String name; private Type nameType = Type.PATH; private FieldType type = FieldType.IMPLICIT; private int order = Integer.MAX_VALUE; @@ -205,6 +206,8 @@ public MongoFieldBuilder order(int order) { * @return a new {@link MongoField}. */ public MongoField build() { + + Assert.notNull(name, "Name of Field must not be null"); return new MongoField(new FieldName(name, nameType), type, order); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java index d6ac5a0882..f1d67e4ae8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java @@ -20,6 +20,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.model.MutablePersistentEntity; +import org.springframework.data.mongodb.core.query.Collation; /** * MongoDB specific {@link PersistentEntity} abstraction. @@ -68,7 +69,7 @@ public interface MongoPersistentEntity extends MutablePersistentEntityMongoDB Query operator: $in */ - public Criteria in(Object... values) { + public Criteria in(@Nullable Object ... values) { if (values.length > 1 && values[1] instanceof Collection) { throw new InvalidMongoDbApiUsageException( "You can only pass in one argument of type " + values[1].getClass().getName()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java index 25fffd5ffe..f26c1ada25 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java @@ -45,6 +45,7 @@ import org.springframework.data.mongodb.CodecRegistryProvider; import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.mongodb.core.mapping.FieldName.Type; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -73,7 +74,8 @@ public class BsonUtils { public static final Document EMPTY_DOCUMENT = new EmptyDocument(); @SuppressWarnings("unchecked") - public static @Nullable T get(Bson bson, String key) { + @Contract("null, _ -> null") + public static @Nullable T get(@Nullable Bson bson, String key) { return (T) asMap(bson).get(key); } @@ -84,7 +86,7 @@ public class BsonUtils { * @param bson * @return */ - public static Map asMap(Bson bson) { + public static Map asMap(@Nullable Bson bson) { return asMap(bson, MongoClientSettings.getDefaultCodecRegistry()); } @@ -469,6 +471,7 @@ public static Document toDocumentOrElse(String source, Function false") public static boolean isJsonDocument(@Nullable String value) { if (!StringUtils.hasText(value)) { @@ -486,6 +489,7 @@ public static boolean isJsonDocument(@Nullable String value) { * @return {@literal true} if the given value looks like a json array. * @since 3.0 */ + @Contract("null -> false") public static boolean isJsonArray(@Nullable String value) { return StringUtils.hasText(value) && (value.startsWith("[") && value.endsWith("]")); } @@ -741,6 +745,7 @@ public static Document mapEntries(Document source, Function null") private static @Nullable String toJson(@Nullable Object value) { if (value == null) { diff --git a/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/query/TypedUpdateExtensions.kt b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/query/TypedUpdateExtensions.kt index d132482f65..d7784a7768 100644 --- a/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/query/TypedUpdateExtensions.kt +++ b/spring-data-mongodb/src/main/kotlin/org/springframework/data/mongodb/core/query/TypedUpdateExtensions.kt @@ -142,7 +142,7 @@ fun Update.pull(key: KProperty, value: Any) = * @since 4.4 * @see Update.pullAll */ -fun Update.pullAll(key: KProperty>, values: Array) = +fun Update.pullAll(key: KProperty>, values: Array) = pullAll(key.toDotPath(), values) /** From 41a3fe1215fa9131820ea0e2c09d9a9f3463b32e Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 14 Mar 2025 12:03:15 +0100 Subject: [PATCH 14/17] tmp save - doh - srly --- .../data/mongodb/MongoTransactionManager.java | 2 + .../mongodb/ReactiveMongoDatabaseUtils.java | 2 +- .../config/MappingMongoConverterParser.java | 2 + .../MongoAuditingBeanDefinitionParser.java | 2 + .../mongodb/config/MongoDbFactoryParser.java | 2 + .../mongodb/config/MongoParsingUtils.java | 2 + .../mongodb/config/MongoTemplateParser.java | 2 + .../data/mongodb/core/ChangeStreamEvent.java | 3 +- .../data/mongodb/core/CollectionOptions.java | 2 +- .../data/mongodb/core/CountQuery.java | 6 + .../mongodb/core/DefaultIndexOperations.java | 4 + .../core/DefaultIndexOperationsProvider.java | 3 +- .../core/DefaultReactiveBulkOperations.java | 5 +- .../core/DefaultReactiveIndexOperations.java | 2 + .../mongodb/core/DefaultScriptOperations.java | 34 ++---- .../core/DefaultWriteConcernResolver.java | 3 +- .../core/EntityLifecycleEventDelegate.java | 1 + ...ExecutableAggregationOperationSupport.java | 15 ++- .../core/ExecutableFindOperationSupport.java | 8 +- .../ExecutableInsertOperationSupport.java | 2 +- .../ExecutableMapReduceOperationSupport.java | 1 + .../ExecutableRemoveOperationSupport.java | 2 +- .../ExecutableUpdateOperationSupport.java | 11 +- .../core/MappingMongoJsonSchemaCreator.java | 9 +- .../mongodb/core/MongoClientFactoryBean.java | 6 +- .../MongoEncryptionSettingsFactoryBean.java | 12 +- .../core/MongoExceptionTranslator.java | 1 + .../mongodb/core/MongoJsonSchemaCreator.java | 4 +- .../data/mongodb/core/MongoOperations.java | 33 ++---- .../core/MongoServerApiFactoryBean.java | 7 +- .../data/mongodb/core/MongoTemplate.java | 2 +- .../ReactiveAggregationOperationSupport.java | 12 +- .../core/ReactiveFindOperationSupport.java | 4 +- .../core/ReactiveInsertOperationSupport.java | 5 +- .../ReactiveMapReduceOperationSupport.java | 5 +- .../core/ReactiveMongoClientFactoryBean.java | 6 +- .../mongodb/core/ReactiveMongoTemplate.java | 49 ++++---- .../core/ReactiveRemoveOperationSupport.java | 5 +- .../core/ReactiveUpdateOperationSupport.java | 23 ++-- .../AbstractAggregationExpression.java | 3 +- .../aggregation/AccumulatorOperators.java | 23 ++-- .../core/aggregation/AddFieldsOperation.java | 2 +- .../AggregationSpELExpression.java | 4 +- .../core/aggregation/ArithmeticOperators.java | 49 +++++++- .../core/aggregation/ArrayOperators.java | 25 ++++- .../core/aggregation/BooleanOperators.java | 8 +- .../core/aggregation/BucketAutoOperation.java | 5 +- .../core/aggregation/BucketOperation.java | 5 +- .../aggregation/BucketOperationSupport.java | 18 ++- .../core/aggregation/ComparisonOperators.java | 12 +- .../aggregation/ConditionalOperators.java | 11 +- .../core/aggregation/ConvertOperators.java | 2 + .../core/aggregation/DateOperators.java | 1 + .../core/aggregation/DensifyOperation.java | 7 +- .../DocumentEnhancingOperation.java | 9 +- .../core/aggregation/EvaluationOperators.java | 7 +- .../data/mongodb/core/aggregation/Fields.java | 2 +- .../aggregation/GraphLookupOperation.java | 7 +- .../core/aggregation/GroupOperation.java | 5 +- .../core/aggregation/LookupOperation.java | 1 + .../core/aggregation/MatchOperation.java | 6 +- .../core/aggregation/MergeOperation.java | 4 +- ...ExpressionAggregationOperationContext.java | 3 +- .../core/aggregation/ObjectOperators.java | 2 +- .../core/aggregation/ProjectionOperation.java | 2 +- .../core/aggregation/RedactOperation.java | 11 +- .../aggregation/ReplaceRootOperation.java | 1 + .../core/aggregation/ScriptOperators.java | 26 +++-- .../core/aggregation/SetOperation.java | 2 +- .../core/aggregation/SetOperators.java | 12 +- .../aggregation/SetWindowFieldsOperation.java | 8 +- .../aggregation/SortByCountOperation.java | 1 + .../SpelExpressionTransformer.java | 31 ++--- .../core/aggregation/StringOperators.java | 24 +++- .../core/aggregation/UnwindOperation.java | 4 + .../core/aggregation/VariableOperators.java | 1 + .../core/convert/DbRefResolverCallback.java | 3 +- .../core/convert/DefaultDbRefResolver.java | 7 +- .../convert/DefaultDbRefResolverCallback.java | 3 +- .../core/convert/DefaultMongoTypeMapper.java | 2 +- .../convert/DefaultReferenceResolver.java | 6 +- .../core/convert/DocumentPointerFactory.java | 19 +++- .../core/convert/DocumentReferenceSource.java | 6 +- .../mongodb/core/convert/GeoConverters.java | 106 ++++++++++++------ .../core/convert/LazyLoadingProxyFactory.java | 20 ++-- .../core/convert/MappingMongoConverter.java | 4 +- .../core/convert/MongoConversionContext.java | 4 +- .../core/convert/MongoExampleMapper.java | 9 +- .../mongodb/core/convert/QueryMapper.java | 17 ++- .../core/convert/ReferenceLookupDelegate.java | 15 +-- .../mongodb/core/convert/UpdateMapper.java | 19 ++-- .../encryption/EncryptingConverter.java | 9 +- .../encryption/ExplicitEncryptionContext.java | 8 +- .../encryption/MongoEncryptionConverter.java | 3 +- .../core/encryption/EncryptionContext.java | 4 +- .../data/mongodb/core/geo/GeoJsonModule.java | 2 +- .../mongodb/core/index/GeospatialIndex.java | 2 +- .../data/mongodb/core/index/IndexInfo.java | 12 +- .../MongoPersistentEntityIndexResolver.java | 12 +- .../mapping/BasicMongoPersistentEntity.java | 9 +- .../mapping/BasicMongoPersistentProperty.java | 3 + .../CachingMongoPersistentProperty.java | 4 +- .../UnwrappedMongoPersistentProperty.java | 5 +- .../core/mapreduce/MapReduceResults.java | 3 +- .../core/messaging/ChangeStreamRequest.java | 4 +- .../core/messaging/CursorReadingTask.java | 4 +- .../core/messaging/SubscriptionRequest.java | 2 +- .../core/messaging/TailableCursorRequest.java | 2 +- .../data/mongodb/core/query/Collation.java | 6 +- .../data/mongodb/core/query/Criteria.java | 2 +- .../data/mongodb/core/query/Meta.java | 4 +- .../data/mongodb/core/query/Query.java | 6 +- .../core/query/SerializationUtils.java | 2 + .../core/schema/UntypedJsonSchemaObject.java | 8 +- ...xpressionTransformationContextSupport.java | 9 +- .../core/spel/ExpressionTransformer.java | 4 +- .../data/mongodb/gridfs/GridFsUpload.java | 9 +- .../MongoParametersParameterAccessor.java | 2 +- .../support/MongoRepositoryFactory.java | 4 +- .../ReactiveMongoRepositoryFactory.java | 4 +- .../data/mongodb/util/BsonUtils.java | 11 +- .../mongodb/util/json/DateTimeFormatter.java | 3 + .../data/mongodb/util/json/JsonBuffer.java | 2 + .../data/mongodb/util/json/JsonScanner.java | 2 + .../data/mongodb/util/json/JsonToken.java | 2 + .../json/ParameterBindingDocumentCodec.java | 2 + .../util/json/ParameterBindingJsonReader.java | 2 + ...iveMapReduceOperationSupportUnitTests.java | 10 +- 128 files changed, 713 insertions(+), 352 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java index f19acc6ff6..0c449635d9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java @@ -80,7 +80,9 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager * @see #setTransactionSynchronization(int) */ public MongoTransactionManager() { + this.transactionOptionsResolver = MongoTransactionOptionsResolver.defaultResolver(); + this.options = MongoTransactionOptions.NONE; } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java index 0b63cde870..7c291288f2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java @@ -113,7 +113,7 @@ public static Mono getDatabase(ReactiveMongoDatabaseFactory facto * @param factory the {@link ReactiveMongoDatabaseFactory} to get the {@link MongoDatabase} from. * @return the {@link MongoDatabase} that is potentially associated with a transactional {@link ClientSession}. */ - public static Mono getDatabase(String dbName, ReactiveMongoDatabaseFactory factory) { + public static Mono getDatabase(@Nullable String dbName, ReactiveMongoDatabaseFactory factory) { return doGetMongoDatabase(dbName, factory, SessionSynchronization.ON_ACTUAL_TRANSACTION); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java index b9ab066181..f3a7dc0437 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Set; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.factory.config.BeanDefinition; @@ -76,6 +77,7 @@ * @author Zied Yaich * @author Tomasz Forys */ +@NullUnmarked public class MappingMongoConverterParser implements BeanDefinitionParser { private static final String BASE_PACKAGE = "base-package"; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java index 786827eb55..a304199776 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java @@ -18,6 +18,7 @@ import static org.springframework.data.config.ParsingUtils.*; import static org.springframework.data.mongodb.config.BeanNames.*; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; @@ -42,6 +43,7 @@ * @author Oliver Gierke * @author Mark Paluch */ +@NullUnmarked public class MongoAuditingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { private static boolean PROJECT_REACTOR_AVAILABLE = ClassUtils.isPresent("reactor.core.publisher.Mono", diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java index 2a6939fbdc..2d3649c53a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java @@ -20,6 +20,7 @@ import java.util.Set; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.config.BeanDefinition; @@ -47,6 +48,7 @@ * @author Viktor Khoroshko * @author Mark Paluch */ +@NullUnmarked public class MongoDbFactoryParser extends AbstractBeanDefinitionParser { private static final Set MONGO_URI_ALLOWED_ADDITIONAL_ATTRIBUTES = Set.of("id", "write-concern"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java index 95b56b58f3..00e993fdc8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java @@ -19,6 +19,7 @@ import java.util.Map; +import org.jspecify.annotations.NullUnmarked; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.CustomEditorConfigurer; import org.springframework.beans.factory.support.BeanDefinitionBuilder; @@ -40,6 +41,7 @@ * @author Christoph Strobl * @author Mark Paluch */ +@NullUnmarked abstract class MongoParsingUtils { private MongoParsingUtils() {} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java index 1e1b11356f..5053e540fe 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java @@ -18,6 +18,7 @@ import static org.springframework.data.config.ParsingUtils.*; import static org.springframework.data.mongodb.config.MongoParsingUtils.*; +import org.jspecify.annotations.NullUnmarked; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.parsing.BeanComponentDefinition; @@ -37,6 +38,7 @@ * @author Martin Baumgartner * @author Oliver Gierke */ +@NullUnmarked class MongoTemplateParser extends AbstractBeanDefinitionParser { @Override diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java index 42f436c21d..7fa31cefe6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java @@ -89,7 +89,7 @@ public ChangeStreamEvent(@Nullable ChangeStreamDocument raw, Class */ public @Nullable Instant getTimestamp() { - return getBsonTimestamp() != null ? converter.getConversionService().convert(raw.getClusterTime(), Instant.class) + return getBsonTimestamp() != null && raw != null ? converter.getConversionService().convert(raw.getClusterTime(), Instant.class) : null; } @@ -183,6 +183,7 @@ private T getConvertedFullDocument(Document fullDocument) { return (T) doGetConverted(fullDocument, CONVERTED_FULL_DOCUMENT_UPDATER); } + @SuppressWarnings("NullAway") private Object doGetConverted(Document fullDocument, AtomicReferenceFieldUpdater updater) { Object result = updater.get(this); 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 5d6b87cf45..4e6fd68be0 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 @@ -461,7 +461,7 @@ public static class ValidationOptions { private final @Nullable ValidationLevel validationLevel; private final @Nullable ValidationAction validationAction; - public ValidationOptions(Validator validator, ValidationLevel validationLevel, ValidationAction validationAction) { + public ValidationOptions(@Nullable Validator validator, @Nullable ValidationLevel validationLevel, @Nullable ValidationAction validationAction) { this.validator = validator; this.validationLevel = validationLevel; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java index 3f3025cf90..85ac36f828 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java @@ -26,6 +26,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; import org.springframework.data.mongodb.core.query.MetricConversion; +import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** @@ -160,6 +161,8 @@ private static Document createGeoWithin(String key, Document source, @Nullable O boolean spheric = source.containsKey("$nearSphere"); Object $near = spheric ? source.get("$nearSphere") : source.get("$near"); + Assert.notNull($near, "Invalid near query - must contain $nearSphere or $near"); + Number maxDistance = getMaxDistance(source, $near, spheric); List $centerMax = Arrays.asList(toCenterCoordinates($near), maxDistance); @@ -251,6 +254,9 @@ private static Object toCenterCoordinates(Object value) { if (document.containsKey("$geometry")) { Document geoJsonPoint = document.get("$geometry", Document.class); + if(!geoJsonPoint.containsKey("coordinates")) { + throw new IllegalStateException("Invalid geometry without coordinates."); + } return geoJsonPoint.get("coordinates"); } } 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 3293a233c8..24d22bd80a 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 @@ -115,6 +115,7 @@ public DefaultIndexOperations(MongoOperations mongoOperations, String collection } @Override + @SuppressWarnings("NullAway") public String ensureIndex(IndexDefinition indexDefinition) { return execute(collection -> { @@ -159,6 +160,7 @@ public void dropIndex(String name) { } @Override + @SuppressWarnings("NullAway") public void alterIndex(String name, org.springframework.data.mongodb.core.index.IndexOptions options) { Document indexOptions = new Document("name", name); @@ -179,6 +181,7 @@ public void dropAllIndexes() { } @Override + @SuppressWarnings("NullAway") public List getIndexInfo() { return execute(new CollectionCallback>() { @@ -226,6 +229,7 @@ private IndexOptions addPartialFilterIfPresent(IndexOptions ops, Document source mapper.getMappedSort((Document) sourceOptions.get(PARTIAL_FILTER_EXPRESSION_KEY), entity)); } + @SuppressWarnings("NullAway") private static IndexOptions addDefaultCollationIfRequired(IndexOptions ops, @Nullable MongoPersistentEntity entity) { 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 e2471dbb14..a34c1fb945 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 @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.core; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.index.IndexOperations; @@ -43,7 +44,7 @@ class DefaultIndexOperationsProvider implements IndexOperationsProvider { } @Override - public IndexOperations indexOps(String collectionName, Class type) { + public IndexOperations indexOps(String collectionName, @Nullable Class type) { return new DefaultIndexOperations(mongoDbFactory, collectionName, mapper, type); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java index 22daa71799..2458d29ec3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java @@ -359,7 +359,7 @@ public boolean skipEventPublishing() { return eventPublisher == null; } - @SuppressWarnings("rawtypes") + @SuppressWarnings({"rawtypes","NullAway"}) public Mono callback(Class callbackType, T entity, String collectionName) { if (skipEntityCallbacks()) { @@ -369,7 +369,7 @@ public Mono callback(Class callbackType, T enti return entityCallbacks.callback(callbackType, entity, collectionName); } - @SuppressWarnings("rawtypes") + @SuppressWarnings({"rawtypes","NullAway"}) public Mono callback(Class callbackType, T entity, Document document, String collectionName) { @@ -380,6 +380,7 @@ public Mono callback(Class callbackType, T enti return entityCallbacks.callback(callbackType, entity, document, collectionName); } + @SuppressWarnings("NullAway") public void publishEvent(ApplicationEvent event) { if (skipEventPublishing()) { 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 1fdcb574ec..53ca30af53 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 @@ -89,6 +89,7 @@ private DefaultReactiveIndexOperations(ReactiveMongoOperations mongoOperations, } @Override + @SuppressWarnings("NullAway") public Mono ensureIndex(IndexDefinition indexDefinition) { return mongoOperations.execute(collectionName, collection -> { @@ -163,6 +164,7 @@ private IndexOptions addPartialFilterIfPresent(IndexOptions ops, Document source queryMapper.getMappedObject((Document) sourceOptions.get(PARTIAL_FILTER_EXPRESSION_KEY), entity)); } + @SuppressWarnings("NullAway") private static IndexOptions addDefaultCollationIfRequired(IndexOptions ops, @Nullable MongoPersistentEntity entity) { 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 b236b4df28..745e10726b 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 @@ -28,6 +28,7 @@ import org.bson.Document; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.mongodb.core.script.ExecutableMongoScript; @@ -85,38 +86,27 @@ public NamedMongoScript register(NamedMongoScript script) { } @Override - public Object execute(ExecutableMongoScript script, Object... args) { + public @Nullable Object execute(ExecutableMongoScript script, Object... args) { Assert.notNull(script, "Script must not be null"); - return mongoOperations.execute(new DbCallback() { + return mongoOperations.execute(db -> { - @Override - public Object doInDB(MongoDatabase db) throws MongoException, DataAccessException { - - Document command = new Document("$eval", script.getCode()); - BasicDBList commandArgs = new BasicDBList(); - commandArgs.addAll(Arrays.asList(convertScriptArgs(false, args))); - command.append("args", commandArgs); - return db.runCommand(command).get("retval"); - } - }); + Document command = new Document("$eval", script.getCode()); + BasicDBList commandArgs = new BasicDBList(); + commandArgs.addAll(Arrays.asList(convertScriptArgs(false, args))); + command.append("args", commandArgs); + return db.runCommand(command).get("retval"); + }); } @Override - public Object call(String scriptName, Object... args) { + public @Nullable Object call(String scriptName, Object... args) { Assert.hasText(scriptName, "ScriptName must not be null or empty"); - return mongoOperations.execute(new DbCallback() { - - @Override - public Object doInDB(MongoDatabase db) throws MongoException, DataAccessException { - - return db.runCommand(new Document("eval", String.format("%s(%s)", scriptName, convertAndJoinScriptArgs(args)))) - .get("retval"); - } - }); + return mongoOperations.execute(db -> db.runCommand(new Document("eval", String.format("%s(%s)", scriptName, convertAndJoinScriptArgs(args)))) + .get("retval")); } @Override diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultWriteConcernResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultWriteConcernResolver.java index 8b4de14e05..a1830cd940 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultWriteConcernResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultWriteConcernResolver.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core; import com.mongodb.WriteConcern; +import org.jspecify.annotations.Nullable; /** * Default {@link WriteConcernResolver} resolving the {@link WriteConcern} from the given {@link MongoAction}. @@ -26,7 +27,7 @@ enum DefaultWriteConcernResolver implements WriteConcernResolver { INSTANCE; - public WriteConcern resolve(MongoAction action) { + public @Nullable WriteConcern resolve(MongoAction action) { return action.getDefaultWriteConcern(); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityLifecycleEventDelegate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityLifecycleEventDelegate.java index d577ec9cd0..ad3c2b8564 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityLifecycleEventDelegate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityLifecycleEventDelegate.java @@ -47,6 +47,7 @@ public void setEventsEnabled(boolean eventsEnabled) { * * @param event the application event. */ + @SuppressWarnings("NullAway") public void publishEvent(Object event) { if (canPublishEvent()) { 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 ca5aa7a513..33bfcf7fa3 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 @@ -17,6 +17,7 @@ import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.AggregationResults; import org.springframework.data.mongodb.core.aggregation.TypedAggregation; @@ -55,11 +56,11 @@ static class ExecutableAggregationSupport private final MongoTemplate template; private final Class domainType; - private final Aggregation aggregation; - private final String collection; + private final @Nullable Aggregation aggregation; + private final @Nullable String collection; - public ExecutableAggregationSupport(MongoTemplate template, Class domainType, Aggregation aggregation, - String collection) { + public ExecutableAggregationSupport(MongoTemplate template, Class domainType, @Nullable Aggregation aggregation, + @Nullable String collection) { this.template = template; this.domainType = domainType; this.aggregation = aggregation; @@ -84,15 +85,19 @@ public TerminatingAggregation by(Aggregation aggregation) { @Override public AggregationResults all() { + + Assert.notNull(aggregation, "Aggregation must be set first"); return template.aggregate(aggregation, getCollectionName(aggregation), domainType); } @Override public Stream stream() { + + Assert.notNull(aggregation, "Aggregation must be set first"); return template.aggregateStream(aggregation, getCollectionName(aggregation), domainType); } - private String getCollectionName(Aggregation aggregation) { + private String getCollectionName(@Nullable Aggregation aggregation) { if (StringUtils.hasText(collection)) { return collection; 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 2bba87ed2d..75a1955aad 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 @@ -107,7 +107,7 @@ public TerminatingFind matching(Query query) { } @Override - public T oneValue() { + public @Nullable T oneValue() { List result = doFind(new DelegatingQueryCursorPreparer(getCursorPreparer(query, null)).limit(2)); @@ -123,7 +123,7 @@ public T oneValue() { } @Override - public T firstValue() { + public @Nullable T firstValue() { List result = doFind(new DelegatingQueryCursorPreparer(getCursorPreparer(query, null)).limit(1)); @@ -228,8 +228,8 @@ CursorPreparer limit(int limit) { } @Override - public ReadPreference getReadPreference() { - return delegate.getReadPreference(); + public @Nullable ReadPreference getReadPreference() { + return delegate != null ? delegate.getReadPreference() : null; } } 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 f786ac0700..a8e6397ae8 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 @@ -59,7 +59,7 @@ static class ExecutableInsertSupport implements ExecutableInsert { @Nullable private final String collection; @Nullable private final BulkMode bulkMode; - ExecutableInsertSupport(MongoTemplate template, Class domainType, String collection, BulkMode bulkMode) { + ExecutableInsertSupport(MongoTemplate template, Class domainType, @Nullable String collection, @Nullable BulkMode bulkMode) { this.template = template; this.domainType = domainType; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java index 4f0ff6a283..a1f5ab4ef2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java @@ -89,6 +89,7 @@ static class ExecutableMapReduceSupport * @see in org.springframework.data.mongodb.core.ExecutableMapReduceOperation.TerminatingMapReduce#all() */ @Override + @SuppressWarnings("NullAway") public List all() { return template.mapReduce(query, domainType, getCollectionName(), mapFunction, reduceFunction, options, returnType); 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 3d52c33fc1..37a975264d 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 @@ -60,7 +60,7 @@ static class ExecutableRemoveSupport implements ExecutableRemove, RemoveWi private final Query query; @Nullable private final String collection; - public ExecutableRemoveSupport(MongoTemplate template, Class domainType, Query query, String collection) { + public ExecutableRemoveSupport(MongoTemplate template, Class domainType, Query query, @Nullable String collection) { this.template = template; this.domainType = domainType; this.query = query; 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 133581ada6..c1cc8d57ce 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 @@ -52,6 +52,7 @@ public ExecutableUpdate update(Class domainType) { * @author Christoph Strobl * @since 2.0 */ + @SuppressWarnings("rawtypes") static class ExecutableUpdateSupport implements ExecutableUpdate, UpdateWithCollection, UpdateWithQuery, TerminatingUpdate, FindAndReplaceWithOptions, TerminatingFindAndReplace, FindAndReplaceWithProjection { @@ -66,9 +67,9 @@ static class ExecutableUpdateSupport @Nullable private final Object replacement; private final Class targetType; - ExecutableUpdateSupport(MongoTemplate template, Class domainType, Query query, UpdateDefinition update, - String collection, FindAndModifyOptions findAndModifyOptions, FindAndReplaceOptions findAndReplaceOptions, - Object replacement, Class targetType) { + ExecutableUpdateSupport(MongoTemplate template, Class domainType, Query query, @Nullable UpdateDefinition update, + @Nullable String collection, @Nullable FindAndModifyOptions findAndModifyOptions, @Nullable FindAndReplaceOptions findAndReplaceOptions, + @Nullable Object replacement, Class targetType) { this.template = template; this.domainType = domainType; @@ -171,6 +172,7 @@ public UpdateResult upsert() { } @Override + @SuppressWarnings("NullAway") public @Nullable T findAndModifyValue() { return template.findAndModify(query, update, @@ -179,6 +181,7 @@ public UpdateResult upsert() { } @Override + @SuppressWarnings({"unchecked", "NullAway"}) public @Nullable T findAndReplaceValue() { return (T) template.findAndReplace(query, replacement, @@ -187,6 +190,7 @@ public UpdateResult upsert() { } @Override + @SuppressWarnings({"unchecked", "NullAway"}) public UpdateResult replaceFirst() { if (replacement != null) { @@ -198,6 +202,7 @@ public UpdateResult replaceFirst() { findAndReplaceOptions != null ? findAndReplaceOptions : ReplaceOptions.none(), getCollectionName()); } + @SuppressWarnings("NullAway") private UpdateResult doUpdate(boolean multi, boolean upsert) { return template.doUpdate(getCollectionName(), query, update, domainType, upsert, multi); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java index 839f49c7da..d6239794e9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java @@ -24,6 +24,7 @@ import java.util.stream.Collectors; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.convert.MongoConverter; @@ -176,6 +177,7 @@ private List computePropertiesForEntity(List path) { String stringPath = path.stream().map(MongoPersistentProperty::getName).collect(Collectors.joining(".")); @@ -337,7 +339,9 @@ private TypedJsonSchemaObject createSchemaObject(Object type, Collection poss return schemaObject; } - private String computePropertyFieldName(PersistentProperty property) { + private String computePropertyFieldName(@Nullable PersistentProperty property) { + + Assert.notNull(property, "Property must not be null"); return property instanceof MongoPersistentProperty mongoPersistentProperty ? mongoPersistentProperty.getFieldName() : property.getName(); @@ -409,7 +413,8 @@ public MongoPersistentProperty getProperty() { } @Override - public MongoPersistentEntity resolveEntity(MongoPersistentProperty property) { + @SuppressWarnings("unchecked") + public @Nullable MongoPersistentEntity resolveEntity(MongoPersistentProperty property) { return (MongoPersistentEntity) mappingContext.getPersistentEntity(property); } } 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 5a1f5088a3..9210dd85ec 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 @@ -315,13 +315,13 @@ private void applySettings(Consumer settingsBuilder, @Nullable T value) { settingsBuilder.accept(value); } - private T computeSettingsValue(Function function, S defaultValueHolder, S settingsValueHolder, + private @Nullable T computeSettingsValue(Function function, S defaultValueHolder, S settingsValueHolder, @Nullable T connectionStringValue) { return computeSettingsValue(function.apply(defaultValueHolder), function.apply(settingsValueHolder), connectionStringValue); } - private T computeSettingsValue(T defaultValue, T fromSettings, T fromConnectionString) { + private @Nullable T computeSettingsValue(@Nullable T defaultValue, T fromSettings, @Nullable T fromConnectionString) { boolean fromSettingsIsDefault = ObjectUtils.nullSafeEquals(defaultValue, fromSettings); boolean fromConnectionStringIsDefault = ObjectUtils.nullSafeEquals(defaultValue, fromConnectionString); @@ -336,7 +336,7 @@ private MongoClient createMongoClient(MongoClientSettings settings) throws Unkno return MongoClients.create(settings, SpringDataMongoDB.driverInformation()); } - private String getOrDefault(Object value, String defaultValue) { + private String getOrDefault(@Nullable Object value, String defaultValue) { if(value == null) { return defaultValue; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java index cd850ac304..4019cb8b38 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java @@ -34,11 +34,11 @@ public class MongoEncryptionSettingsFactoryBean implements FactoryBean { private boolean bypassAutoEncryption; - private String keyVaultNamespace; - private Map extraOptions; - private MongoClientSettings keyVaultClientSettings; - private Map> kmsProviders; - private Map schemaMap; + private @Nullable String keyVaultNamespace; + private @Nullable Map extraOptions; + private @Nullable MongoClientSettings keyVaultClientSettings; + private @Nullable Map> kmsProviders; + private @Nullable Map schemaMap; /** * @param bypassAutoEncryption @@ -91,6 +91,8 @@ public void setSchemaMap(Map schemaMap) { @Override public AutoEncryptionSettings getObject() { + + return AutoEncryptionSettings.builder() // .bypassAutoEncryption(bypassAutoEncryption) // .keyVaultNamespace(keyVaultNamespace) // diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java index a07d0085ff..2bde873c2f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java @@ -73,6 +73,7 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator } @Nullable + @SuppressWarnings("NullAway") DataAccessException doTranslateException(RuntimeException ex) { // Check for well-known MongoException subclasses. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoJsonSchemaCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoJsonSchemaCreator.java index 66b1cf209e..84c395bf2f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoJsonSchemaCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoJsonSchemaCreator.java @@ -139,8 +139,7 @@ interface JsonSchemaPropertyContext { * @return {@literal null} if the property is not an entity. It is nevertheless recommend to check * {@link PersistentProperty#isEntity()} first. */ - @Nullable - MongoPersistentEntity resolveEntity(MongoPersistentProperty property); + @Nullable MongoPersistentEntity resolveEntity(MongoPersistentProperty property); } @@ -162,6 +161,7 @@ public boolean test(JsonSchemaPropertyContext context) { return extracted(context.getProperty(), context); } + @SuppressWarnings("NullAway") private boolean extracted(MongoPersistentProperty property, JsonSchemaPropertyContext context) { if (property.isAnnotationPresent(Encrypted.class)) { return true; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java index 475a659025..6eb29fe0bf 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java @@ -733,8 +733,7 @@ MapReduceResults mapReduce(Query query, String inputCollectionName, Strin * @param entityClass the parametrized type of the returned list. * @return the converted object. */ - @Nullable - T findOne(Query query, Class entityClass); + @Nullable T findOne(Query query, Class entityClass); /** * Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified @@ -750,8 +749,7 @@ MapReduceResults mapReduce(Query query, String inputCollectionName, Strin * @param collectionName name of the collection to retrieve the objects from. * @return the converted object. */ - @Nullable - T findOne(Query query, Class entityClass, String collectionName); + @Nullable T findOne(Query query, Class entityClass, String collectionName); /** * Determine result of given {@link Query} contains at least one element.
@@ -871,8 +869,7 @@ MapReduceResults mapReduce(Query query, String inputCollectionName, Strin * @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); + @Nullable T findById(Object id, Class entityClass); /** * Returns the document with the given id from the given collection mapped onto the given target class. @@ -882,8 +879,7 @@ MapReduceResults mapReduce(Query query, String inputCollectionName, Strin * @param collectionName the collection to query for the document. * @return he converted object or {@literal null} if document does not exist. */ - @Nullable - T findById(Object id, Class entityClass, String collectionName); + @Nullable T findById(Object id, Class entityClass, String collectionName); /** * Finds the distinct values for a specified {@literal field} across a single {@link MongoCollection} or view and @@ -960,8 +956,7 @@ default List findDistinct(Query query, String field, String collection, C * @see Update * @see AggregationUpdate */ - @Nullable - T findAndModify(Query query, UpdateDefinition update, Class entityClass); + @Nullable T findAndModify(Query query, UpdateDefinition update, Class entityClass); /** * Triggers findAndModify @@ -980,8 +975,7 @@ default List findDistinct(Query query, String field, String collection, C * @see Update * @see AggregationUpdate */ - @Nullable - T findAndModify(Query query, UpdateDefinition update, Class entityClass, String collectionName); + @Nullable T findAndModify(Query query, UpdateDefinition update, Class entityClass, String collectionName); /** * Triggers findAndModify @@ -1003,8 +997,7 @@ default List findDistinct(Query query, String field, String collection, C * @see Update * @see AggregationUpdate */ - @Nullable - T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class entityClass); + @Nullable T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class entityClass); /** * Triggers findAndModify @@ -1027,8 +1020,7 @@ default List findDistinct(Query query, String field, String collection, C * @see Update * @see AggregationUpdate */ - @Nullable - T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class entityClass, + @Nullable T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class entityClass, String collectionName); /** @@ -1188,8 +1180,7 @@ T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions o * as it is after the update. * @since 2.1 */ - @Nullable - T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class entityType, + @Nullable T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class entityType, String collectionName, Class resultType); /** @@ -1205,8 +1196,7 @@ T findAndReplace(Query query, S replacement, FindAndReplaceOptions option * @param entityClass the parametrized type of the returned list. * @return the converted object */ - @Nullable - T findAndRemove(Query query, Class entityClass); + @Nullable T findAndRemove(Query query, Class entityClass); /** * Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified @@ -1223,8 +1213,7 @@ T findAndReplace(Query query, S replacement, FindAndReplaceOptions option * @param collectionName name of the collection to retrieve the objects from. * @return the converted object. */ - @Nullable - T findAndRemove(Query query, Class entityClass, String collectionName); + @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. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBean.java index 9223ad9ece..574c0c8931 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBean.java @@ -31,7 +31,7 @@ */ public class MongoServerApiFactoryBean implements FactoryBean { - private String version; + private @Nullable String version; private @Nullable Boolean deprecationErrors; private @Nullable Boolean strict; @@ -80,6 +80,11 @@ public Class getObjectType() { } private ServerApiVersion version() { + + if(version == null) { + return ServerApiVersion.V1; + } + try { // lookup by name eg. 'V1' return ObjectUtils.caseInsensitiveValueOf(ServerApiVersion.values(), version); 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 bb187095d7..a173df155e 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 @@ -338,7 +338,7 @@ public boolean hasReadPreference() { } @Override - public ReadPreference getReadPreference() { + public @Nullable ReadPreference getReadPreference() { return this.readPreference; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveAggregationOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveAggregationOperationSupport.java index 954fd61716..978aa9634f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveAggregationOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveAggregationOperationSupport.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.core; +import org.jspecify.annotations.Nullable; import reactor.core.publisher.Flux; import org.springframework.data.mongodb.core.aggregation.Aggregation; @@ -59,11 +60,11 @@ static class ReactiveAggregationSupport private final ReactiveMongoTemplate template; private final Class domainType; - private final Aggregation aggregation; - private final String collection; + private final @Nullable Aggregation aggregation; + private final @Nullable String collection; - ReactiveAggregationSupport(ReactiveMongoTemplate template, Class domainType, Aggregation aggregation, - String collection) { + ReactiveAggregationSupport(ReactiveMongoTemplate template, Class domainType, @Nullable Aggregation aggregation, + @Nullable String collection) { this.template = template; this.domainType = domainType; @@ -89,6 +90,9 @@ public TerminatingAggregationOperation by(Aggregation aggregation) { @Override public Flux all() { + + Assert.notNull(aggregation, "Aggregation must be set first"); + return template.aggregate(aggregation, getCollectionName(aggregation), domainType); } 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 918267e073..9445dbdadb 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 @@ -67,10 +67,10 @@ static class ReactiveFindSupport private final ReactiveMongoTemplate template; private final Class domainType; private final Class returnType; - private final String collection; + private final @Nullable String collection; private final Query query; - ReactiveFindSupport(ReactiveMongoTemplate template, Class domainType, Class returnType, String collection, + ReactiveFindSupport(ReactiveMongoTemplate template, Class domainType, Class returnType, @Nullable String collection, Query query) { this.template = template; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveInsertOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveInsertOperationSupport.java index 06d3c6eae7..9d424c2446 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveInsertOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveInsertOperationSupport.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.core; +import org.jspecify.annotations.Nullable; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -50,9 +51,9 @@ static class ReactiveInsertSupport implements ReactiveInsert { private final ReactiveMongoTemplate template; private final Class domainType; - private final String collection; + private final @Nullable String collection; - ReactiveInsertSupport(ReactiveMongoTemplate template, Class domainType, String collection) { + ReactiveInsertSupport(ReactiveMongoTemplate template, Class domainType, @Nullable String collection) { this.template = template; this.domainType = domainType; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupport.java index 34edba0e80..4e3379bad0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupport.java @@ -89,8 +89,11 @@ static class ReactiveMapReduceSupport @Override public Flux all() { + Assert.notNull(mapFunction, "MapFunction must be set first"); + Assert.notNull(reduceFunction, "ReduceFunction must be set first"); + return template.mapReduce(query, domainType, getCollectionName(), returnType, mapFunction, reduceFunction, - options); + options != null ? options : MapReduceOptions.options()); } /* 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 e35cf66a19..04fd312847 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 @@ -89,7 +89,7 @@ public void setExceptionTranslator(@Nullable PersistenceExceptionTranslator exce } @Override - public DataAccessException translateExceptionIfPossible(RuntimeException ex) { + public @Nullable DataAccessException translateExceptionIfPossible(RuntimeException ex) { return exceptionTranslator.translateExceptionIfPossible(ex); } @@ -124,7 +124,9 @@ protected MongoClient createInstance() throws Exception { @Override protected void destroyInstance(@Nullable MongoClient instance) throws Exception { - instance.close(); + if(instance != null) { + instance.close(); + } } } 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 68402651ab..ea4b15a856 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 @@ -17,6 +17,7 @@ import static org.springframework.data.mongodb.core.query.SerializationUtils.*; +import org.springframework.lang.Contract; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -345,7 +346,7 @@ public void setWriteConcern(@Nullable WriteConcern writeConcern) { * @param writeConcernResolver can be {@literal null}. */ public void setWriteConcernResolver(@Nullable WriteConcernResolver writeConcernResolver) { - this.writeConcernResolver = writeConcernResolver; + this.writeConcernResolver = writeConcernResolver != null ? writeConcernResolver : DefaultWriteConcernResolver.INSTANCE; } /** @@ -1146,6 +1147,7 @@ public Mono findAndModify(Query query, UpdateDefinition update, FindAndMo } @Override + @SuppressWarnings("NullAway") public Mono findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class entityType, String collectionName, Class resultType) { @@ -1351,6 +1353,7 @@ public Mono insert(T objectToSave, String collectionName) { return doInsert(collectionName, objectToSave, this.mongoConverter); } + @SuppressWarnings("NullAway") protected Mono doInsert(String collectionName, T objectToSave, MongoWriter writer) { return Mono.just(PersistableEntityModel.of(objectToSave, collectionName)) // @@ -1401,6 +1404,7 @@ public Flux insertAll(Mono> objectsToSa return Flux.from(objectsToSave).flatMapSequential(this::insertAll); } + @SuppressWarnings("NullAway") protected Flux doInsertAll(Collection listToSave, MongoWriter writer) { Map> elementsByCollection = new HashMap<>(); @@ -1417,6 +1421,7 @@ protected Flux doInsertAll(Collection listToSave, MongoWrite .concatMap(collectionName -> doInsertBatch(collectionName, elementsByCollection.get(collectionName), writer)); } + @SuppressWarnings("NullAway") protected Flux doInsertBatch(String collectionName, Collection batchToSave, MongoWriter writer) { @@ -1532,6 +1537,7 @@ private Mono doSaveVersioned(AdaptibleEntity source, String collection }); } + @SuppressWarnings("NullAway") protected Mono doSave(String collectionName, T objectToSave, MongoWriter writer) { assertUpdateableIdIfNotSet(objectToSave); @@ -1625,6 +1631,7 @@ private MongoCollection prepareCollection(MongoCollection co return collectionToUse; } + @SuppressWarnings("NullAway") protected Mono saveDocument(String collectionName, Document document, Class entityClass) { if (LOGGER.isDebugEnabled()) { @@ -1728,7 +1735,8 @@ public Mono updateMulti(Query query, UpdateDefinition update, Clas return doUpdate(collectionName, query, update, entityClass, false, true); } - protected Mono doUpdate(String collectionName, Query query, @Nullable UpdateDefinition update, + @SuppressWarnings("NullAway") + protected Mono doUpdate(String collectionName, Query query, UpdateDefinition update, @Nullable Class entityClass, boolean upsert, boolean multi) { MongoPersistentEntity entity = entityClass == null ? null : getPersistentEntity(entityClass); @@ -2008,18 +2016,18 @@ public Flux tail(Query query, Class entityClass) { @Override public Flux tail(@Nullable Query query, Class entityClass, String collectionName) { - ReactiveCollectionPreparerDelegate collectionPreparer = ReactiveCollectionPreparerDelegate.of(query); if (query == null) { LOGGER.debug(String.format("Tail for class: %s in collection: %s", entityClass, collectionName)); return executeFindMultiInternal( - collection -> new FindCallback(collectionPreparer, null).doInCollection(collection) + collection -> new FindCallback(CollectionPreparer.identity(), null).doInCollection(collection) .cursorType(CursorType.TailableAwait), FindPublisherPreparer.NO_OP_PREPARER, new ReadDocumentCallback<>(mongoConverter, entityClass, collectionName), collectionName); } + ReactiveCollectionPreparerDelegate collectionPreparer = ReactiveCollectionPreparerDelegate.of(query); return doFind(collectionName, collectionPreparer, query.getQueryObject(), query.getFieldsObject(), entityClass, new TailingQueryFindPublisherPreparer(query, entityClass)); } @@ -2382,7 +2390,7 @@ protected Flux doFind(String collectionName, serializeToJsonSafely(mappedQuery), mappedFields, entityClass, collectionName)); } - return executeFindMultiInternal(new FindCallback(collectionPreparer, mappedQuery, mappedFields), preparer, + return executeFindMultiInternal(new FindCallback(collectionPreparer, mappedQuery, mappedFields), preparer != null ? preparer : FindPublisherPreparer.NO_OP_PREPARER, objectCallback, collectionName); } @@ -2448,7 +2456,7 @@ protected CreateCollectionOptions convertToCreateCollectionOptions(@Nullable Col * @return the List of converted objects. */ protected Mono doFindAndRemove(String collectionName, - CollectionPreparer> collectionPreparer, Document query, Document fields, Document sort, + CollectionPreparer> collectionPreparer, Document query, Document fields, @Nullable Document sort, @Nullable Collation collation, Class entityClass) { if (LOGGER.isDebugEnabled()) { @@ -2464,7 +2472,8 @@ protected Mono doFindAndRemove(String collectionName, } protected Mono doFindAndModify(String collectionName, - CollectionPreparer> collectionPreparer, Document query, Document fields, Document sort, + CollectionPreparer> collectionPreparer, Document query, Document fields, + @Nullable Document sort, Class entityClass, UpdateDefinition update, FindAndModifyOptions options) { MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); @@ -2724,7 +2733,7 @@ private Mono executeFindOneInternal(ReactiveCollectionCallback * @return */ private Flux executeFindMultiInternal(ReactiveCollectionQueryCallback collectionCallback, - @Nullable FindPublisherPreparer preparer, DocumentCallback objectCallback, String collectionName) { + FindPublisherPreparer preparer, DocumentCallback objectCallback, String collectionName) { return createFlux(collectionName, collection -> { return Flux.from(preparer.initiateFind(collection, collectionCallback::doInCollection)) @@ -2783,7 +2792,8 @@ private MappingMongoConverter getDefaultMongoConverter() { return converter; } - private @Nullable Document getMappedSortObject(Query query, Class type) { + @Contract("null, _ -> null") + private @Nullable Document getMappedSortObject(@Nullable Query query, Class type) { if (query == null) { return null; @@ -2792,7 +2802,8 @@ private MappingMongoConverter getDefaultMongoConverter() { return getMappedSortObject(query.getSortObject(), type); } - private @Nullable Document getMappedSortObject(Document sortObject, Class type) { + @Contract("null, _ -> null") + private @Nullable Document getMappedSortObject(@Nullable Document sortObject, Class type) { if (ObjectUtils.isEmpty(sortObject)) { return null; @@ -2858,7 +2869,7 @@ private static class FindCallback implements ReactiveCollectionQueryCallback> collectionPreparer, Document query, Document fields) { + FindCallback(CollectionPreparer> collectionPreparer, @Nullable Document query, @Nullable Document fields) { this.collectionPreparer = collectionPreparer; this.query = query; this.fields = fields; @@ -2894,11 +2905,11 @@ private static class FindAndRemoveCallback implements ReactiveCollectionCallback private final CollectionPreparer> collectionPreparer; private final Document query; private final Document fields; - private final Document sort; + private final @Nullable Document sort; private final Optional collation; FindAndRemoveCallback(CollectionPreparer> collectionPreparer, Document query, - Document fields, Document sort, @Nullable Collation collation) { + Document fields, @Nullable Document sort, @Nullable Collation collation) { this.collectionPreparer = collectionPreparer; this.query = query; this.fields = fields; @@ -2924,14 +2935,14 @@ private static class FindAndModifyCallback implements ReactiveCollectionCallback private final CollectionPreparer> collectionPreparer; private final Document query; - private final Document fields; - private final Document sort; + private final @Nullable Document fields; + private final @Nullable Document sort; private final Object update; private final List arrayFilters; private final FindAndModifyOptions options; FindAndModifyCallback(CollectionPreparer> collectionPreparer, Document query, - Document fields, Document sort, Object update, List arrayFilters, FindAndModifyOptions options) { + @Nullable Document fields, @Nullable Document sort, Object update, List arrayFilters, FindAndModifyOptions options) { this.collectionPreparer = collectionPreparer; this.query = query; @@ -2969,7 +2980,7 @@ public Publisher doInCollection(MongoCollection collection) } private static FindOneAndUpdateOptions convertToFindOneAndUpdateOptions(FindAndModifyOptions options, - Document fields, Document sort, List arrayFilters) { + @Nullable Document fields, @Nullable Document sort, List arrayFilters) { FindOneAndUpdateOptions result = new FindOneAndUpdateOptions(); @@ -3009,7 +3020,7 @@ private static class FindAndReplaceCallback implements ReactiveCollectionCallbac private final FindAndReplaceOptions options; FindAndReplaceCallback(CollectionPreparer> collectionPreparer, Document query, - Document fields, Document sort, Document update, com.mongodb.client.model.Collation collation, + Document fields, Document sort, Document update, com.mongodb.client.model.@Nullable Collation collation, FindAndReplaceOptions options) { this.collectionPreparer = collectionPreparer; this.query = query; @@ -3045,7 +3056,7 @@ private FindOneAndReplaceOptions convertToFindOneAndReplaceOptions(FindAndReplac } } - private static FindOneAndDeleteOptions convertToFindOneAndDeleteOptions(Document fields, Document sort) { + private static FindOneAndDeleteOptions convertToFindOneAndDeleteOptions(@Nullable Document fields, @Nullable Document sort) { FindOneAndDeleteOptions result = new FindOneAndDeleteOptions(); result = result.projection(fields).sort(sort); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveRemoveOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveRemoveOperationSupport.java index 97c9cb0d0e..5c935ec628 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveRemoveOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveRemoveOperationSupport.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.core; +import org.jspecify.annotations.Nullable; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -54,9 +55,9 @@ static class ReactiveRemoveSupport implements ReactiveRemove, RemoveWithCo private final ReactiveMongoTemplate template; private final Class domainType; private final Query query; - private final String collection; + private final @Nullable String collection; - ReactiveRemoveSupport(ReactiveMongoTemplate template, Class domainType, Query query, String collection) { + ReactiveRemoveSupport(ReactiveMongoTemplate template, Class domainType, Query query, @Nullable String collection) { this.template = template; this.domainType = domainType; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupport.java index 60df4fcc30..75bfeef314 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupport.java @@ -57,16 +57,16 @@ static class ReactiveUpdateSupport private final ReactiveMongoTemplate template; private final Class domainType; private final Query query; - private final org.springframework.data.mongodb.core.query.UpdateDefinition update; - @Nullable private final String collection; - @Nullable private final FindAndModifyOptions findAndModifyOptions; - @Nullable private final FindAndReplaceOptions findAndReplaceOptions; - @Nullable private final Object replacement; + private final org.springframework.data.mongodb.core.query.@Nullable UpdateDefinition update; + private final @Nullable String collection; + private final @Nullable FindAndModifyOptions findAndModifyOptions; + private final @Nullable FindAndReplaceOptions findAndReplaceOptions; + private final @Nullable Object replacement; private final Class targetType; - ReactiveUpdateSupport(ReactiveMongoTemplate template, Class domainType, Query query, UpdateDefinition update, - String collection, FindAndModifyOptions findAndModifyOptions, FindAndReplaceOptions findAndReplaceOptions, - Object replacement, Class targetType) { + ReactiveUpdateSupport(ReactiveMongoTemplate template, Class domainType, Query query, @Nullable UpdateDefinition update, + @Nullable String collection, @Nullable FindAndModifyOptions findAndModifyOptions, @Nullable FindAndReplaceOptions findAndReplaceOptions, + @Nullable Object replacement, Class targetType) { this.template = template; this.domainType = domainType; @@ -108,6 +108,7 @@ public Mono upsert() { } @Override + @SuppressWarnings("NullAway") public Mono findAndModify() { String collectionName = getCollectionName(); @@ -118,7 +119,11 @@ public Mono findAndModify() { } @Override + @SuppressWarnings({"unchecked","rawtypes"}) public Mono findAndReplace() { + + Assert.notNull(replacement, "Replacement must be set first"); + return template.findAndReplace(query, replacement, findAndReplaceOptions != null ? findAndReplaceOptions : FindAndReplaceOptions.none(), (Class) domainType, getCollectionName(), targetType); @@ -186,6 +191,7 @@ public FindAndReplaceWithOptions as(Class resultType) { } @Override + @SuppressWarnings("NullAway") public Mono replaceFirst() { if (replacement != null) { @@ -197,6 +203,7 @@ public Mono replaceFirst() { findAndReplaceOptions != null ? findAndReplaceOptions : ReplaceOptions.none(), getCollectionName()); } + @SuppressWarnings("NullAway") private Mono doUpdate(boolean multi, boolean upsert) { return template.doUpdate(getCollectionName(), query, update, domainType, upsert, multi); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AbstractAggregationExpression.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AbstractAggregationExpression.java index d4cdece411..710b570ed7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AbstractAggregationExpression.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AbstractAggregationExpression.java @@ -26,6 +26,7 @@ import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; @@ -282,7 +283,7 @@ protected T get(int index) { * @since 2.1 */ @SuppressWarnings("unchecked") - protected T get(Object key) { + protected @Nullable T get(Object key) { Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AccumulatorOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AccumulatorOperators.java index cf6485c230..9f8db95523 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AccumulatorOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AccumulatorOperators.java @@ -22,6 +22,7 @@ import java.util.Map; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** @@ -60,8 +61,8 @@ public static AccumulatorOperatorFactory valueOf(AggregationExpression expressio */ public static class AccumulatorOperatorFactory { - private final String fieldReference; - private final AggregationExpression expression; + private final @Nullable String fieldReference; + private final @Nullable AggregationExpression expression; /** * Creates new {@link AccumulatorOperatorFactory} for given {@literal fieldReference}. @@ -93,6 +94,7 @@ public AccumulatorOperatorFactory(AggregationExpression expression) { * * @return new instance of {@link Sum}. */ + @SuppressWarnings("NullAway") public Sum sum() { return usesFieldRef() ? Sum.sumOf(fieldReference) : Sum.sumOf(expression); } @@ -103,6 +105,7 @@ public Sum sum() { * * @return new instance of {@link Avg}. */ + @SuppressWarnings("NullAway") public Avg avg() { return usesFieldRef() ? Avg.avgOf(fieldReference) : Avg.avgOf(expression); } @@ -113,6 +116,7 @@ public Avg avg() { * * @return new instance of {@link Max}. */ + @SuppressWarnings("NullAway") public Max max() { return usesFieldRef() ? Max.maxOf(fieldReference) : Max.maxOf(expression); } @@ -134,6 +138,7 @@ public Max max(int numberOfResults) { * * @return new instance of {@link Min}. */ + @SuppressWarnings("NullAway") public Min min() { return usesFieldRef() ? Min.minOf(fieldReference) : Min.minOf(expression); } @@ -155,6 +160,7 @@ public Min min(int numberOfResults) { * * @return new instance of {@link StdDevPop}. */ + @SuppressWarnings("NullAway") public StdDevPop stdDevPop() { return usesFieldRef() ? StdDevPop.stdDevPopOf(fieldReference) : StdDevPop.stdDevPopOf(expression); } @@ -165,6 +171,7 @@ public StdDevPop stdDevPop() { * * @return new instance of {@link StdDevSamp}. */ + @SuppressWarnings("NullAway") public StdDevSamp stdDevSamp() { return usesFieldRef() ? StdDevSamp.stdDevSampOf(fieldReference) : StdDevSamp.stdDevSampOf(expression); } @@ -193,6 +200,7 @@ public CovariancePop covariancePop(AggregationExpression expression) { return covariancePop().and(expression); } + @SuppressWarnings("NullAway") private CovariancePop covariancePop() { return usesFieldRef() ? CovariancePop.covariancePopOf(fieldReference) : CovariancePop.covariancePopOf(expression); } @@ -221,6 +229,7 @@ public CovarianceSamp covarianceSamp(AggregationExpression expression) { return covarianceSamp().and(expression); } + @SuppressWarnings("NullAway") private CovarianceSamp covarianceSamp() { return usesFieldRef() ? CovarianceSamp.covarianceSampOf(fieldReference) : CovarianceSamp.covarianceSampOf(expression); @@ -233,6 +242,7 @@ private CovarianceSamp covarianceSamp() { * @return new instance of {@link ExpMovingAvg}. * @since 3.3 */ + @SuppressWarnings("NullAway") public ExpMovingAvgBuilder expMovingAvg() { ExpMovingAvg expMovingAvg = usesFieldRef() ? ExpMovingAvg.expMovingAvgOf(fieldReference) @@ -259,6 +269,7 @@ public ExpMovingAvg alpha(double exponentialDecayValue) { * @param percentages must not be {@literal null}. * @since 4.2 */ + @SuppressWarnings("NullAway") public Percentile percentile(Double... percentages) { Percentile percentile = usesFieldRef() ? Percentile.percentileOf(fieldReference) : Percentile.percentileOf(expression); @@ -271,6 +282,7 @@ public Percentile percentile(Double... percentages) { * @return new instance of {@link Median}. * @since 4.2 */ + @SuppressWarnings("NullAway") public Median median() { return usesFieldRef() ? Median.medianOf(fieldReference) : Median.medianOf(expression); } @@ -386,7 +398,6 @@ public Sum and(Number value) { } @Override - @SuppressWarnings("unchecked") public Document toDocument(Object value, AggregationOperationContext context) { if (value instanceof List list && list.size() == 1) { @@ -464,7 +475,6 @@ public Avg and(AggregationExpression expression) { } @Override - @SuppressWarnings("unchecked") public Document toDocument(Object value, AggregationOperationContext context) { if (value instanceof List list && list.size() == 1) { @@ -553,6 +563,7 @@ public Max limit(int numberOfResults) { } @Override + @SuppressWarnings("NullAway") public Document toDocument(AggregationOperationContext context) { if (get("n") == null) { return toDocument(get("input"), context); @@ -650,6 +661,7 @@ public Min limit(int numberOfResults) { } @Override + @SuppressWarnings("NullAway") public Document toDocument(AggregationOperationContext context) { if (get("n") == null) { @@ -659,7 +671,6 @@ public Document toDocument(AggregationOperationContext context) { } @Override - @SuppressWarnings("unchecked") public Document toDocument(Object value, AggregationOperationContext context) { if (value instanceof List list && list.size() == 1) { @@ -737,7 +748,6 @@ public StdDevPop and(AggregationExpression expression) { } @Override - @SuppressWarnings("unchecked") public Document toDocument(Object value, AggregationOperationContext context) { if (value instanceof List list && list.size() == 1) { @@ -815,7 +825,6 @@ public StdDevSamp and(AggregationExpression expression) { } @Override - @SuppressWarnings("unchecked") public Document toDocument(Object value, AggregationOperationContext context) { if (value instanceof List list && list.size() == 1) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java index debc7c61f3..a49971f8f7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java @@ -139,7 +139,7 @@ public ValueAppender addField(String field) { return new ValueAppender() { @Override - public AddFieldsOperationBuilder withValue(Object value) { + public AddFieldsOperationBuilder withValue(@Nullable Object value) { valueMap.put(field, value); return AddFieldsOperationBuilder.this; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationSpELExpression.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationSpELExpression.java index 1626d672bc..c5b53ef0c6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationSpELExpression.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationSpELExpression.java @@ -66,6 +66,8 @@ public static AggregationSpELExpression expressionOf(String expressionString, Ob @Override public Document toDocument(AggregationOperationContext context) { - return (Document) TRANSFORMER.transform(rawExpression, context, parameters); + + Document doc = (Document) TRANSFORMER.transform(rawExpression, context, parameters); + return doc != null ? doc : new Document(); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java index 2554c328b6..b8350680c4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java @@ -84,8 +84,8 @@ public static Rand rand() { */ public static class ArithmeticOperatorFactory { - private final String fieldReference; - private final AggregationExpression expression; + private final @Nullable String fieldReference; + private final @Nullable AggregationExpression expression; /** * Creates new {@link ArithmeticOperatorFactory} for given {@literal fieldReference}. @@ -116,6 +116,7 @@ public ArithmeticOperatorFactory(AggregationExpression expression) { * * @return new instance of {@link Abs}. */ + @SuppressWarnings("NullAway") public Abs abs() { return usesFieldRef() ? Abs.absoluteValueOf(fieldReference) : Abs.absoluteValueOf(expression); } @@ -158,6 +159,7 @@ public Add add(Number value) { return createAdd().add(value); } + @SuppressWarnings("NullAway") private Add createAdd() { return usesFieldRef() ? Add.valueOf(fieldReference) : Add.valueOf(expression); } @@ -168,6 +170,7 @@ private Add createAdd() { * * @return new instance of {@link Ceil}. */ + @SuppressWarnings("NullAway") public Ceil ceil() { return usesFieldRef() ? Ceil.ceilValueOf(fieldReference) : Ceil.ceilValueOf(expression); } @@ -205,6 +208,7 @@ public Derivative derivative(WindowUnit unit) { * @return new instance of {@link Derivative}. * @since 3.3 */ + @SuppressWarnings("NullAway") public Derivative derivative(@Nullable String unit) { Derivative derivative = usesFieldRef() ? Derivative.derivativeOf(fieldReference) @@ -250,6 +254,7 @@ public Divide divideBy(Number value) { return createDivide().divideBy(value); } + @SuppressWarnings("NullAway") private Divide createDivide() { return usesFieldRef() ? Divide.valueOf(fieldReference) : Divide.valueOf(expression); } @@ -259,6 +264,7 @@ private Divide createDivide() { * * @return new instance of {@link Exp}. */ + @SuppressWarnings("NullAway") public Exp exp() { return usesFieldRef() ? Exp.expValueOf(fieldReference) : Exp.expValueOf(expression); } @@ -269,6 +275,7 @@ public Exp exp() { * * @return new instance of {@link Floor}. */ + @SuppressWarnings("NullAway") public Floor floor() { return usesFieldRef() ? Floor.floorValueOf(fieldReference) : Floor.floorValueOf(expression); } @@ -279,6 +286,7 @@ public Floor floor() { * @return new instance of {@link Integral}. * @since 3.3 */ + @SuppressWarnings("NullAway") public Integral integral() { return usesFieldRef() ? Integral.integralOf(fieldReference) : Integral.integralOf(expression); } @@ -318,6 +326,7 @@ public Integral integral(String unit) { * * @return new instance of {@link Ln}. */ + @SuppressWarnings("NullAway") public Ln ln() { return usesFieldRef() ? Ln.lnValueOf(fieldReference) : Ln.lnValueOf(expression); } @@ -345,7 +354,7 @@ public Log log(String fieldReference) { public Log log(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); - return createLog().log(fieldReference); + return createLog().log(expression); } /** @@ -361,6 +370,7 @@ public Log log(Number base) { return createLog().log(base); } + @SuppressWarnings("NullAway") private Log createLog() { return usesFieldRef() ? Log.valueOf(fieldReference) : Log.valueOf(expression); } @@ -370,6 +380,7 @@ private Log createLog() { * * @return new instance of {@link Log10}. */ + @SuppressWarnings("NullAway") public Log10 log10() { return usesFieldRef() ? Log10.log10ValueOf(fieldReference) : Log10.log10ValueOf(expression); } @@ -413,6 +424,7 @@ public Mod mod(Number value) { return createMod().mod(value); } + @SuppressWarnings("NullAway") private Mod createMod() { return usesFieldRef() ? Mod.valueOf(fieldReference) : Mod.valueOf(expression); } @@ -453,6 +465,7 @@ public Multiply multiplyBy(Number value) { return createMultiply().multiplyBy(value); } + @SuppressWarnings("NullAway") private Multiply createMultiply() { return usesFieldRef() ? Multiply.valueOf(fieldReference) : Multiply.valueOf(expression); } @@ -493,6 +506,7 @@ public Pow pow(Number value) { return createPow().pow(value); } + @SuppressWarnings("NullAway") private Pow createPow() { return usesFieldRef() ? Pow.valueOf(fieldReference) : Pow.valueOf(expression); } @@ -502,6 +516,7 @@ private Pow createPow() { * * @return new instance of {@link Sqrt}. */ + @SuppressWarnings("NullAway") public Sqrt sqrt() { return usesFieldRef() ? Sqrt.sqrtOf(fieldReference) : Sqrt.sqrtOf(expression); } @@ -542,6 +557,7 @@ public Subtract subtract(Number value) { return createSubtract().subtract(value); } + @SuppressWarnings("NullAway") private Subtract createSubtract() { return usesFieldRef() ? Subtract.valueOf(fieldReference) : Subtract.valueOf(expression); } @@ -551,6 +567,7 @@ private Subtract createSubtract() { * * @return new instance of {@link Trunc}. */ + @SuppressWarnings("NullAway") public Trunc trunc() { return usesFieldRef() ? Trunc.truncValueOf(fieldReference) : Trunc.truncValueOf(expression); } @@ -560,6 +577,7 @@ public Trunc trunc() { * * @return new instance of {@link Sum}. */ + @SuppressWarnings("NullAway") public Sum sum() { return usesFieldRef() ? AccumulatorOperators.Sum.sumOf(fieldReference) : AccumulatorOperators.Sum.sumOf(expression); @@ -570,6 +588,7 @@ public Sum sum() { * * @return new instance of {@link Avg}. */ + @SuppressWarnings("NullAway") public Avg avg() { return usesFieldRef() ? AccumulatorOperators.Avg.avgOf(fieldReference) : AccumulatorOperators.Avg.avgOf(expression); @@ -580,6 +599,7 @@ public Avg avg() { * * @return new instance of {@link Max}. */ + @SuppressWarnings("NullAway") public Max max() { return usesFieldRef() ? AccumulatorOperators.Max.maxOf(fieldReference) : AccumulatorOperators.Max.maxOf(expression); @@ -590,6 +610,7 @@ public Max max() { * * @return new instance of {@link Min}. */ + @SuppressWarnings("NullAway") public Min min() { return usesFieldRef() ? AccumulatorOperators.Min.minOf(fieldReference) : AccumulatorOperators.Min.minOf(expression); @@ -600,6 +621,7 @@ public Min min() { * * @return new instance of {@link StdDevPop}. */ + @SuppressWarnings("NullAway") public StdDevPop stdDevPop() { return usesFieldRef() ? AccumulatorOperators.StdDevPop.stdDevPopOf(fieldReference) : AccumulatorOperators.StdDevPop.stdDevPopOf(expression); @@ -610,6 +632,7 @@ public StdDevPop stdDevPop() { * * @return new instance of {@link StdDevSamp}. */ + @SuppressWarnings("NullAway") public StdDevSamp stdDevSamp() { return usesFieldRef() ? AccumulatorOperators.StdDevSamp.stdDevSampOf(fieldReference) : AccumulatorOperators.StdDevSamp.stdDevSampOf(expression); @@ -639,6 +662,7 @@ public CovariancePop covariancePop(AggregationExpression expression) { return covariancePop().and(expression); } + @SuppressWarnings("NullAway") private CovariancePop covariancePop() { return usesFieldRef() ? CovariancePop.covariancePopOf(fieldReference) : CovariancePop.covariancePopOf(expression); } @@ -667,6 +691,7 @@ public CovarianceSamp covarianceSamp(AggregationExpression expression) { return covarianceSamp().and(expression); } + @SuppressWarnings("NullAway") private CovarianceSamp covarianceSamp() { return usesFieldRef() ? CovarianceSamp.covarianceSampOf(fieldReference) : CovarianceSamp.covarianceSampOf(expression); @@ -679,6 +704,7 @@ private CovarianceSamp covarianceSamp() { * @return new instance of {@link Round}. * @since 3.0 */ + @SuppressWarnings("NullAway") public Round round() { return usesFieldRef() ? Round.roundValueOf(fieldReference) : Round.roundValueOf(expression); } @@ -712,6 +738,7 @@ public Sin sin() { * @return new instance of {@link Sin}. * @since 3.3 */ + @SuppressWarnings("NullAway") public Sin sin(AngularUnit unit) { return usesFieldRef() ? Sin.sinOf(fieldReference, unit) : Sin.sinOf(expression, unit); } @@ -734,6 +761,7 @@ public Sinh sinh() { * @return new instance of {@link Sinh}. * @since 3.3 */ + @SuppressWarnings("NullAway") public Sinh sinh(AngularUnit unit) { return usesFieldRef() ? Sinh.sinhOf(fieldReference, unit) : Sinh.sinhOf(expression, unit); } @@ -744,6 +772,7 @@ public Sinh sinh(AngularUnit unit) { * @return new instance of {@link ASin}. * @since 3.3 */ + @SuppressWarnings("NullAway") public ASin asin() { return usesFieldRef() ? ASin.asinOf(fieldReference) : ASin.asinOf(expression); } @@ -754,6 +783,7 @@ public ASin asin() { * @return new instance of {@link ASinh}. * @since 3.3 */ + @SuppressWarnings("NullAway") public ASinh asinh() { return usesFieldRef() ? ASinh.asinhOf(fieldReference) : ASinh.asinhOf(expression); } @@ -777,6 +807,7 @@ public Cos cos() { * @return new instance of {@link Cos}. * @since 3.3 */ + @SuppressWarnings("NullAway") public Cos cos(AngularUnit unit) { return usesFieldRef() ? Cos.cosOf(fieldReference, unit) : Cos.cosOf(expression, unit); } @@ -799,6 +830,7 @@ public Cosh cosh() { * @return new instance of {@link Cosh}. * @since 3.3 */ + @SuppressWarnings("NullAway") public Cosh cosh(AngularUnit unit) { return usesFieldRef() ? Cosh.coshOf(fieldReference, unit) : Cosh.coshOf(expression, unit); } @@ -809,6 +841,7 @@ public Cosh cosh(AngularUnit unit) { * @return new instance of {@link ACos}. * @since 3.4 */ + @SuppressWarnings("NullAway") public ACos acos() { return usesFieldRef() ? ACos.acosOf(fieldReference) : ACos.acosOf(expression); } @@ -819,6 +852,7 @@ public ACos acos() { * @return new instance of {@link ACosh}. * @since 3.4 */ + @SuppressWarnings("NullAway") public ACosh acosh() { return usesFieldRef() ? ACosh.acoshOf(fieldReference) : ACosh.acoshOf(expression); } @@ -840,6 +874,7 @@ public Tan tan() { * @return new instance of {@link ATan}. * @since 3.3 */ + @SuppressWarnings("NullAway") public ATan atan() { return usesFieldRef() ? ATan.atanOf(fieldReference) : ATan.atanOf(expression); } @@ -852,6 +887,7 @@ public ATan atan() { * @return new instance of {@link ATan2}. * @since 3.3 */ + @SuppressWarnings("NullAway") public ATan2 atan2(Number value) { Assert.notNull(value, "Value must not be null"); @@ -886,8 +922,8 @@ public ATan2 atan2(AggregationExpression expression) { return createATan2().atan2of(expression); } + @SuppressWarnings("NullAway") private ATan2 createATan2() { - return usesFieldRef() ? ATan2.valueOf(fieldReference) : ATan2.valueOf(expression); } @@ -897,6 +933,7 @@ private ATan2 createATan2() { * @return new instance of {@link ATanh}. * @since 3.3 */ + @SuppressWarnings("NullAway") public ATanh atanh() { return usesFieldRef() ? ATanh.atanhOf(fieldReference) : ATanh.atanhOf(expression); } @@ -909,6 +946,7 @@ public ATanh atanh() { * @return new instance of {@link Tan}. * @since 3.3 */ + @SuppressWarnings("NullAway") public Tan tan(AngularUnit unit) { return usesFieldRef() ? Tan.tanOf(fieldReference, unit) : Tan.tanOf(expression, unit); } @@ -931,6 +969,7 @@ public Tanh tanh() { * @return new instance of {@link Tanh}. * @since 3.3 */ + @SuppressWarnings("NullAway") public Tanh tanh(AngularUnit unit) { return usesFieldRef() ? Tanh.tanhOf(fieldReference, unit) : Tanh.tanhOf(expression, unit); } @@ -943,6 +982,7 @@ public Tanh tanh(AngularUnit unit) { * @param percentages must not be {@literal null}. * @since 4.2 */ + @SuppressWarnings("NullAway") public Percentile percentile(Double... percentages) { Percentile percentile = usesFieldRef() ? AccumulatorOperators.Percentile.percentileOf(fieldReference) : AccumulatorOperators.Percentile.percentileOf(expression); @@ -956,6 +996,7 @@ public Percentile percentile(Double... percentages) { * @return new instance of {@link Median}. * @since 4.2 */ + @SuppressWarnings("NullAway") public Median median() { return usesFieldRef() ? AccumulatorOperators.Median.medianOf(fieldReference) : AccumulatorOperators.Median.medianOf(expression); 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 e13626c933..fecd42d7e5 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 @@ -158,6 +158,7 @@ public ArrayElemAt elementAt(String fieldReference) { return createArrayElemAt().elementAt(fieldReference); } + @SuppressWarnings("NullAway") private ArrayElemAt createArrayElemAt() { if (usesFieldRef()) { @@ -193,6 +194,7 @@ public ConcatArrays concat(AggregationExpression expression) { return createConcatArrays().concat(expression); } + @SuppressWarnings("NullAway") private ConcatArrays createConcatArrays() { if (usesFieldRef()) { @@ -208,6 +210,7 @@ private ConcatArrays createConcatArrays() { * * @return new instance of {@link AsBuilder} to create a {@link Filter}. */ + @SuppressWarnings("NullAway") public AsBuilder filter() { if (usesFieldRef()) { @@ -227,6 +230,7 @@ public AsBuilder filter() { * * @return new instance of {@link IsArray}. */ + @SuppressWarnings("NullAway") public IsArray isArray() { Assert.state(values == null, "Does it make sense to call isArray on an array; Maybe just skip it"); @@ -239,6 +243,7 @@ public IsArray isArray() { * * @return new instance of {@link Size}. */ + @SuppressWarnings("NullAway") public Size length() { if (usesFieldRef()) { @@ -253,6 +258,7 @@ public Size length() { * * @return new instance of {@link Slice}. */ + @SuppressWarnings("NullAway") public Slice slice() { if (usesFieldRef()) { @@ -269,6 +275,7 @@ public Slice slice() { * @param value must not be {@literal null}. * @return new instance of {@link IndexOfArray}. */ + @SuppressWarnings("NullAway") public IndexOfArray indexOf(Object value) { if (usesFieldRef()) { @@ -284,6 +291,7 @@ public IndexOfArray indexOf(Object value) { * * @return new instance of {@link ReverseArray}. */ + @SuppressWarnings("NullAway") public ReverseArray reverse() { if (usesFieldRef()) { @@ -301,6 +309,7 @@ public ReverseArray reverse() { * @param expression must not be {@literal null}. * @return new instance of {@link ReduceInitialValueBuilder} to create {@link Reduce}. */ + @SuppressWarnings("NullAway") public ArrayOperatorFactory.ReduceInitialValueBuilder reduce(AggregationExpression expression) { return initialValue -> (usesFieldRef() ? Reduce.arrayOf(fieldReference) @@ -314,6 +323,7 @@ public ArrayOperatorFactory.ReduceInitialValueBuilder reduce(AggregationExpressi * @param expressions must not be {@literal null}. * @return new instance of {@link ReduceInitialValueBuilder} to create {@link Reduce}. */ + @SuppressWarnings("NullAway") public ArrayOperatorFactory.ReduceInitialValueBuilder reduce(PropertyExpression... expressions) { return initialValue -> (usesFieldRef() ? Reduce.arrayOf(fieldReference) : Reduce.arrayOf(expression)) @@ -327,6 +337,7 @@ public ArrayOperatorFactory.ReduceInitialValueBuilder reduce(PropertyExpression. * @return new instance of {@link SortArray}. * @since 4.0 */ + @SuppressWarnings("NullAway") public SortArray sort(Sort sort) { if (usesFieldRef()) { @@ -344,6 +355,7 @@ public SortArray sort(Sort sort) { * @param arrays must not be {@literal null}. * @return new instance of {@link Zip}. */ + @SuppressWarnings("NullAway") public Zip zipWith(Object... arrays) { if (usesFieldRef()) { @@ -360,6 +372,7 @@ public Zip zipWith(Object... arrays) { * @param value must not be {@literal null}. * @return new instance of {@link In}. */ + @SuppressWarnings("NullAway") public In containsValue(Object value) { if (usesFieldRef()) { @@ -376,6 +389,7 @@ public In containsValue(Object value) { * @return new instance of {@link ArrayToObject}. * @since 2.1 */ + @SuppressWarnings("NullAway") public ArrayToObject toObject() { if (usesFieldRef()) { @@ -392,6 +406,7 @@ public ArrayToObject toObject() { * @return new instance of {@link First}. * @since 3.4 */ + @SuppressWarnings("NullAway") public First first() { if (usesFieldRef()) { @@ -408,6 +423,7 @@ public First first() { * @return new instance of {@link Last}. * @since 3.4 */ + @SuppressWarnings("NullAway") public Last last() { if (usesFieldRef()) { @@ -681,9 +697,12 @@ public static AsBuilder filter(List values) { @Override public Document toDocument(final AggregationOperationContext context) { + + Assert.notNull(as, "As must be set first"); return toFilter(ExposedFields.from(as), context); } + @SuppressWarnings("NullAway") private Document toFilter(ExposedFields exposedFields, AggregationOperationContext context) { Document filterExpression = new Document(); @@ -692,12 +711,13 @@ private Document toFilter(ExposedFields exposedFields, AggregationOperationConte filterExpression.putAll(context.getMappedObject(new Document("input", getMappedInput(context)))); filterExpression.put("as", as.getTarget()); + filterExpression.putAll(context.getMappedObject(new Document("cond", getMappedCondition(operationContext)))); return new Document("$filter", filterExpression); } - private Object getMappedInput(AggregationOperationContext context) { + private @Nullable Object getMappedInput(AggregationOperationContext context) { if (input instanceof Field field) { return context.getReference(field).toString(); @@ -710,7 +730,7 @@ private Object getMappedInput(AggregationOperationContext context) { return input; } - private Object getMappedCondition(AggregationOperationContext context) { + private @Nullable Object getMappedCondition(AggregationOperationContext context) { if (!(condition instanceof AggregationExpression aggregationExpression)) { return condition; @@ -1365,6 +1385,7 @@ public Document toDocument(AggregationOperationContext context) { return new Document("$reduce", document); } + @SuppressWarnings("NullAway") private Object getMappedValue(Object value, AggregationOperationContext context) { if (value instanceof Document) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BooleanOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BooleanOperators.java index 69689908c9..ee4b4ff5ba 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BooleanOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BooleanOperators.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** @@ -77,8 +78,8 @@ public static Not not(AggregationExpression expression) { */ public static class BooleanOperatorFactory { - private final String fieldReference; - private final AggregationExpression expression; + private final @Nullable String fieldReference; + private final @Nullable AggregationExpression expression; /** * Creates new {@link BooleanOperatorFactory} for given {@literal fieldReference}. @@ -130,6 +131,7 @@ public And and(String fieldReference) { return createAnd().andField(fieldReference); } + @SuppressWarnings("NullAway") private And createAnd() { return usesFieldRef() ? And.and(Fields.field(fieldReference)) : And.and(expression); } @@ -160,6 +162,7 @@ public Or or(String fieldReference) { return createOr().orField(fieldReference); } + @SuppressWarnings("NullAway") private Or createOr() { return usesFieldRef() ? Or.or(Fields.field(fieldReference)) : Or.or(expression); } @@ -169,6 +172,7 @@ private Or createOr() { * * @return new instance of {@link Not}. */ + @SuppressWarnings("NullAway") public Not not() { return usesFieldRef() ? Not.not(fieldReference) : Not.not(expression); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketAutoOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketAutoOperation.java index 36492e2a81..16eca4ec22 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketAutoOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketAutoOperation.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.BucketAutoOperation.BucketAutoOperationOutputBuilder; import org.springframework.data.mongodb.core.aggregation.BucketOperationSupport.OutputBuilder; import org.springframework.util.Assert; @@ -38,7 +39,7 @@ public class BucketAutoOperation extends BucketOperationSupport boundaries; - private final Object defaultBucket; + private final @Nullable Object defaultBucket; /** * Creates a new {@link BucketOperation} given a {@link Field group-by field}. @@ -76,7 +77,7 @@ private BucketOperation(BucketOperation bucketOperation, Outputs outputs) { this.defaultBucket = bucketOperation.defaultBucket; } - private BucketOperation(BucketOperation bucketOperation, List boundaries, Object defaultBucket) { + private BucketOperation(BucketOperation bucketOperation, List boundaries, @Nullable Object defaultBucket) { super(bucketOperation); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketOperationSupport.java index e19ad59a3f..3d5ded05c2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketOperationSupport.java @@ -22,6 +22,7 @@ import java.util.List; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.BucketOperationSupport.OutputBuilder; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.data.mongodb.core.aggregation.ProjectionOperation.ProjectionOperationBuilder; @@ -40,8 +41,8 @@ public abstract class BucketOperationSupport, B extends OutputBuilder> implements FieldsExposingAggregationOperation { - private final Field groupByField; - private final AggregationExpression groupByExpression; + private final @Nullable Field groupByField; + private final @Nullable AggregationExpression groupByExpression; private final Outputs outputs; /** @@ -142,12 +143,17 @@ public Document toDocument(AggregationOperationContext context) { } @Override + public Document toDocument(AggregationOperationContext context) { Document document = new Document(); - document.put("groupBy", groupByExpression == null ? context.getReference(groupByField).toString() - : groupByExpression.toDocument(context)); + if(groupByExpression != null) { + document.put("groupBy", groupByExpression.toDocument(context)); + } else if (groupByField != null) { + document.put("groupBy", context.getReference(groupByField).toString()); + + } if (!outputs.isEmpty()) { document.put("output", outputs.toDocument(context)); @@ -625,7 +631,9 @@ public SpelExpressionOutput(String expression, Object[] parameters) { @Override public Document toDocument(AggregationOperationContext context) { - return (Document) TRANSFORMER.transform(expression, context, params); + + Object o = TRANSFORMER.transform(expression, context, params); + return o instanceof Document document ? document : new Document(); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ComparisonOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ComparisonOperators.java index f27b7f16cb..9acfac14bb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ComparisonOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ComparisonOperators.java @@ -18,6 +18,7 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** @@ -50,8 +51,8 @@ public static ComparisonOperatorFactory valueOf(AggregationExpression expression public static class ComparisonOperatorFactory { - private final String fieldReference; - private final AggregationExpression expression; + private final @Nullable String fieldReference; + private final @Nullable AggregationExpression expression; /** * Creates new {@link ComparisonOperatorFactory} for given {@literal fieldReference}. @@ -107,6 +108,7 @@ public Cmp compareToValue(Object value) { return createCmp().compareToValue(value); } + @SuppressWarnings("NullAway") private Cmp createCmp() { return usesFieldRef() ? Cmp.valueOf(fieldReference) : Cmp.valueOf(expression); } @@ -144,6 +146,7 @@ public Eq equalToValue(Object value) { return createEq().equalToValue(value); } + @SuppressWarnings("NullAway") private Eq createEq() { return usesFieldRef() ? Eq.valueOf(fieldReference) : Eq.valueOf(expression); } @@ -181,6 +184,7 @@ public Gt greaterThanValue(Object value) { return createGt().greaterThanValue(value); } + @SuppressWarnings("NullAway") private Gt createGt() { return usesFieldRef() ? Gt.valueOf(fieldReference) : Gt.valueOf(expression); } @@ -218,6 +222,7 @@ public Gte greaterThanEqualToValue(Object value) { return createGte().greaterThanEqualToValue(value); } + @SuppressWarnings("NullAway") private Gte createGte() { return usesFieldRef() ? Gte.valueOf(fieldReference) : Gte.valueOf(expression); } @@ -255,6 +260,7 @@ public Lt lessThanValue(Object value) { return createLt().lessThanValue(value); } + @SuppressWarnings("NullAway") private Lt createLt() { return usesFieldRef() ? Lt.valueOf(fieldReference) : Lt.valueOf(expression); } @@ -292,6 +298,7 @@ public Lte lessThanEqualToValue(Object value) { return createLte().lessThanEqualToValue(value); } + @SuppressWarnings("NullAway") private Lte createLte() { return usesFieldRef() ? Lte.valueOf(fieldReference) : Lte.valueOf(expression); } @@ -329,6 +336,7 @@ public Ne notEqualToValue(Object value) { return createNe().notEqualToValue(value); } + @SuppressWarnings("NullAway") private Ne createNe() { return usesFieldRef() ? Ne.valueOf(fieldReference) : Ne.valueOf(expression); } 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 699cacacf7..5a7a02f47e 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 @@ -211,6 +211,7 @@ public OtherwiseBuilder thenValueOf(String fieldReference) { return createThenBuilder().thenValueOf(fieldReference); } + @SuppressWarnings("NullAway") private ThenBuilder createThenBuilder() { if (usesFieldRef()) { @@ -303,6 +304,7 @@ private Object mapCondition(Object condition, AggregationOperationContext contex } } + @SuppressWarnings("NullAway") private Object resolve(Object value, AggregationOperationContext context) { if (value instanceof Field field) { @@ -389,7 +391,7 @@ public interface ThenBuilder extends OrBuilder { */ static final class IfNullOperatorBuilder implements IfNullBuilder, ThenBuilder { - private @Nullable List conditions; + private List conditions; private IfNullOperatorBuilder() { conditions = new ArrayList<>(); @@ -623,6 +625,7 @@ public Document toDocument(AggregationOperationContext context) { return new Document("$cond", condObject); } + @SuppressWarnings("NullAway") private Object resolveValue(AggregationOperationContext context, Object value) { if (value instanceof Document || value instanceof Field) { @@ -946,6 +949,8 @@ public OtherwiseBuilder thenValueOf(AggregationExpression expression) { public Cond otherwise(Object otherwiseValue) { Assert.notNull(otherwiseValue, "Value must not be null"); + Assert.notNull(condition, "Condition value needs to be set first"); + Assert.notNull(thenValue, "Then value needs to be set first"); return new Cond(condition, thenValue, otherwiseValue); } @@ -953,6 +958,8 @@ public Cond otherwise(Object otherwiseValue) { public Cond otherwiseValueOf(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); + Assert.notNull(condition, "Condition value needs to be set first"); + Assert.notNull(thenValue, "Then value needs to be set first"); return new Cond(condition, thenValue, Fields.field(fieldReference)); } @@ -960,6 +967,8 @@ public Cond otherwiseValueOf(String fieldReference) { public Cond otherwiseValueOf(AggregationExpression expression) { Assert.notNull(expression, "AggregationExpression must not be null"); + Assert.notNull(condition, "Condition value needs to be set first"); + Assert.notNull(thenValue, "Then value needs to be set first"); return new Cond(condition, thenValue, expression); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConvertOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConvertOperators.java index a8af4f27dc..35a6ad061c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConvertOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ConvertOperators.java @@ -242,10 +242,12 @@ public DegreesToRadians convertDegreesToRadians() { return DegreesToRadians.degreesToRadians(valueObject()); } + @SuppressWarnings("NullAway") private Convert createConvert() { return usesFieldRef() ? Convert.convertValueOf(fieldReference) : Convert.convertValueOf(expression); } + @SuppressWarnings("NullAway") private Object valueObject() { return usesFieldRef() ? Fields.field(fieldReference) : expression; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java index 7b1379ed49..6ee59a9bca 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java @@ -848,6 +848,7 @@ public TsSecond tsSecond() { return TsSecond.tsSecond(dateReference()); } + @SuppressWarnings("NullAway") private Object dateReference() { if (usesFieldRef()) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java index 93688d0618..45afd31775 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java @@ -60,6 +60,9 @@ public static DensifyOperationBuilder builder() { @Override public Document toDocument(AggregationOperationContext context) { + Assert.notNull(field, "Field must be set first"); + Assert.notNull(range, "Range must be set first"); + Document densify = new Document(); densify.put("field", context.getReference(field).getRaw()); if (!ObjectUtils.isEmpty(partitionBy)) { @@ -149,9 +152,9 @@ default Document toDocument() { public static abstract class DensifyRange implements Range { private @Nullable DensifyUnit unit; - private Number step; + private @Nullable Number step; - public DensifyRange(DensifyUnit unit) { + public DensifyRange(@Nullable DensifyUnit unit) { this.unit = unit; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentEnhancingOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentEnhancingOperation.java index 7f260c3785..431215e852 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentEnhancingOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentEnhancingOperation.java @@ -22,6 +22,7 @@ import java.util.stream.Collectors; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation; import org.springframework.util.Assert; @@ -105,7 +106,11 @@ private static Document toSetEntry(Entry entry, AggregationOpera return new Document(field, value); } - private static Object computeValue(Object value, AggregationOperationContext context) { + private static @Nullable Object computeValue(@Nullable Object value, AggregationOperationContext context) { + + if(value == null) { + return value; + } if (value instanceof Field field) { return context.getReference(field).toString(); @@ -154,7 +159,7 @@ static class ExpressionProjection { this.params = parameters.clone(); } - Object toExpression(AggregationOperationContext context) { + @Nullable Object toExpression(AggregationOperationContext context) { return TRANSFORMER.transform(expression, context, params); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java index 56f20dde17..dfdc2d620c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.CriteriaDefinition; import org.springframework.util.Assert; @@ -50,8 +51,8 @@ public static EvaluationOperatorFactory valueOf(AggregationExpression expression public static class EvaluationOperatorFactory { - private final String fieldReference; - private final AggregationExpression expression; + private final @Nullable String fieldReference; + private final @Nullable AggregationExpression expression; /** * Creates new {@link EvaluationOperatorFactory} for given {@literal fieldReference}. @@ -82,6 +83,7 @@ public EvaluationOperatorFactory(AggregationExpression expression) { * * @return new instance of {@link Expr}. */ + @SuppressWarnings("NullAway") public Expr expr() { return usesFieldRef() ? Expr.valueOf(fieldReference) : Expr.valueOf(expression); } @@ -91,6 +93,7 @@ public Expr expr() { * * @return new instance of {@link Expr}. */ + @SuppressWarnings("NullAway") public LastObservationCarriedForward locf() { return usesFieldRef() ? LastObservationCarriedForward.locfValueOf(fieldReference) : LastObservationCarriedForward.locfValueOf(expression); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java index f554a5b78a..b23e923412 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java @@ -205,7 +205,7 @@ static class AggregationField implements Field { private final String raw; private final String name; - private final String target; + private final @Nullable String target; /** * Creates an aggregation field with the given {@code name}. 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 ea6cfe6080..3346bf2eb1 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 @@ -217,7 +217,7 @@ static final class GraphLookupOperationFromBuilder implements FromBuilder, StartWithBuilder, ConnectFromBuilder, ConnectToBuilder { private @Nullable String from; - private @Nullable List startWith; + private @Nullable List startWith; private @Nullable String connectFrom; @Override @@ -310,6 +310,9 @@ public GraphLookupOperationBuilder connectTo(String fieldName) { Assert.hasText(fieldName, "ConnectTo must not be null or empty"); + Assert.notNull(from, "From must not be null"); + Assert.notNull(startWith, "startWith must ne set first"); + Assert.notNull(connectFrom, "ConnectFrom must be set first"); return new GraphLookupOperationBuilder(from, startWith, connectFrom, fieldName); } } @@ -327,7 +330,7 @@ public static final class GraphLookupOperationBuilder { private @Nullable Field depthField; private @Nullable CriteriaDefinition restrictSearchWithMatch; - private GraphLookupOperationBuilder(String from, List startWith, String connectFrom, + private GraphLookupOperationBuilder(String from, List startWith, String connectFrom, String connectTo) { this.from = from; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GroupOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GroupOperation.java index ef3c76f733..b6d36f1baf 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GroupOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GroupOperation.java @@ -497,6 +497,7 @@ public Operation withAlias(String key) { } public ExposedField asField() { + Assert.notNull(key, "Key must be set first"); return new ExposedField(key, true); } @@ -506,10 +507,12 @@ public Document toDocument(AggregationOperationContext context) { if(op == null && value instanceof Document) { return new Document(key, value); } + + Assert.notNull(op, "Operation keyword must be set"); return new Document(key, new Document(op.toString(), value)); } - public Object getValue(AggregationOperationContext context) { + public @Nullable Object getValue(AggregationOperationContext context) { if (reference == null) { 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 282ffbd9e0..436fd0c412 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 @@ -324,6 +324,7 @@ public AsBuilder pipeline(AggregationPipeline pipeline) { public LookupOperation as(String name) { Assert.hasText(name, "'As' must not be null or empty"); + Assert.notNull(from, "From must be set first"); as = new ExposedField(Fields.field(name), true); return new LookupOperation(from, localField, foreignField, let, pipeline, as); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java index da1dbfc027..5f736b55a0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java @@ -17,6 +17,7 @@ import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.CriteriaDefinition; import org.springframework.util.Assert; @@ -37,8 +38,8 @@ */ public class MatchOperation implements AggregationOperation { - private final CriteriaDefinition criteriaDefinition; - private final AggregationExpression expression; + private final @Nullable CriteriaDefinition criteriaDefinition; + private final @Nullable AggregationExpression expression; /** * Creates a new {@link MatchOperation} for the given {@link CriteriaDefinition}. @@ -68,6 +69,7 @@ public MatchOperation(AggregationExpression expression) { } @Override + @SuppressWarnings("NullAway") public Document toDocument(AggregationOperationContext context) { return new Document(getOperator(), diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java index 19ce76c6fa..df785b1d32 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java @@ -415,7 +415,7 @@ public Document toDocument(AggregationOperationContext context) { */ public static class MergeOperationBuilder { - private String collection; + private @Nullable String collection; private @Nullable String database; private UniqueMergeId id = UniqueMergeId.id(); private @Nullable Let let; @@ -581,6 +581,8 @@ public MergeOperationBuilder whenDocumentsDontMatch(WhenDocumentsDontMatch whenN * @return new instance of {@link MergeOperation}. */ public MergeOperation build() { + + Assert.notNull(collection, "Collection must not be null"); return new MergeOperation(new MergeOperationTarget(database, collection), id, let, whenMatched, whenNotMatched); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/NestedDelegatingExpressionAggregationOperationContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/NestedDelegatingExpressionAggregationOperationContext.java index c553a7be02..a5124320f6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/NestedDelegatingExpressionAggregationOperationContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/NestedDelegatingExpressionAggregationOperationContext.java @@ -20,6 +20,7 @@ import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExpressionFieldReference; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; import org.springframework.util.Assert; @@ -57,7 +58,7 @@ public Document getMappedObject(Document document) { } @Override - public Document getMappedObject(Document document, Class type) { + public Document getMappedObject(Document document, @Nullable Class type) { return delegate.getMappedObject(document, type); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ObjectOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ObjectOperators.java index 25189241b7..4e5049c120 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ObjectOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ObjectOperators.java @@ -277,7 +277,7 @@ public Document toDocument(Object value, AggregationOperationContext context) { return super.toDocument(potentiallyExtractSingleValue(value), context); } - @SuppressWarnings("unchecked") + @SuppressWarnings("NullAway") private Object potentiallyExtractSingleValue(Object value) { if (value instanceof Collection collection && collection.size() == 1) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java index a3517be20d..b6b370bff6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java @@ -402,7 +402,7 @@ public Document toDocument(AggregationOperationContext context) { return new Document(getExposedField().getName(), toMongoExpression(context, expression, params)); } - protected static Object toMongoExpression(AggregationOperationContext context, String expression, + protected static @Nullable Object toMongoExpression(AggregationOperationContext context, String expression, Object[] params) { return TRANSFORMER.transform(expression, context, params); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/RedactOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/RedactOperation.java index a370016356..13e68d40e7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/RedactOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/RedactOperation.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond.ThenBuilder; import org.springframework.data.mongodb.core.query.CriteriaDefinition; import org.springframework.util.Assert; @@ -94,9 +95,9 @@ public static RedactOperationBuilder builder() { */ public static class RedactOperationBuilder { - private Object when; - private Object then; - private Object otherwise; + private @Nullable Object when; + private @Nullable Object then; + private @Nullable Object otherwise; private RedactOperationBuilder() { @@ -221,6 +222,10 @@ public RedactOperationBuilder otherwise(Object otherwise) { * @return new instance of {@link RedactOperation}. */ public RedactOperation build() { + + Assert.notNull(then, "Then must be set first"); + Assert.notNull(otherwise, "Otherwise must be set first"); + return new RedactOperation(when().then(then).otherwise(otherwise)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java index 130182a001..4d3145e7f3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java @@ -457,6 +457,7 @@ public DocumentContributor(Object value) { } @Override + @SuppressWarnings("NullAway") public Document toDocument(AggregationOperationContext context) { Document document = new Document("$set", value); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java index 9d1f1deeef..b5c0ad8119 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java @@ -150,10 +150,12 @@ List getArgs() { return get(Fields.ARGS.toString()); } + @Nullable String getBody() { return get(Fields.BODY.toString()); } + @Nullable String getLang() { return get(Fields.LANG.toString()); } @@ -253,7 +255,11 @@ public interface AccumulatorInitBuilder { * @return this. */ default AccumulatorAccumulateBuilder init(Function function) { - return init(function.getBody()).initArgs(function.getArgs()); + + Assert.notNull(function.getBody(), "Function body must not be null"); + + List args = function.getArgs(); + return init(function.getBody()).initArgs(args != null ? args : List.of()); } /** @@ -320,7 +326,11 @@ public interface AccumulatorAccumulateBuilder { * @return this. */ default AccumulatorMergeBuilder accumulate(Function function) { - return accumulate(function.getBody()).accumulateArgs(function.getArgs()); + + Assert.notNull(function.getBody(), "Function body must not be null"); + + List args = function.getArgs(); + return accumulate(function.getBody()).accumulateArgs(args != null ? args : List.of()); } /** @@ -414,12 +424,12 @@ static class AccumulatorBuilder implements AccumulatorInitBuilder, AccumulatorInitArgsBuilder, AccumulatorAccumulateBuilder, AccumulatorAccumulateArgsBuilder, AccumulatorMergeBuilder, AccumulatorFinalizeBuilder { - private List initArgs; - private String initFunction; - private List accumulateArgs; - private String accumulateFunction; - private String mergeFunction; - private String finalizeFunction; + private @Nullable List initArgs; + private @Nullable String initFunction; + private @Nullable List accumulateArgs; + private @Nullable String accumulateFunction; + private @Nullable String mergeFunction; + private @Nullable String finalizeFunction; private String lang = "js"; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java index 0a67cee5fd..50c21e25e4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java @@ -131,7 +131,7 @@ public ValueAppender set(String field) { return new ValueAppender() { @Override - public SetOperation toValue(Object value) { + public SetOperation toValue(@Nullable Object value) { valueMap.put(field, value); return FieldAppender.this.build(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperators.java index 094ef7365b..3b44b4d8b0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperators.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.Sum; import org.springframework.util.Assert; @@ -55,8 +56,8 @@ public static SetOperatorFactory arrayAsSet(AggregationExpression expression) { */ public static class SetOperatorFactory { - private final String fieldReference; - private final AggregationExpression expression; + private final @Nullable String fieldReference; + private final @Nullable AggregationExpression expression; /** * Creates new {@link SetOperatorFactory} for given {@literal fieldReference}. @@ -104,6 +105,7 @@ public SetEquals isEqualTo(AggregationExpression... expressions) { return createSetEquals().isEqualTo(expressions); } + @SuppressWarnings("NullAway") private SetEquals createSetEquals() { return usesFieldRef() ? SetEquals.arrayAsSet(fieldReference) : SetEquals.arrayAsSet(expression); } @@ -130,6 +132,7 @@ public SetIntersection intersects(AggregationExpression... expressions) { return createSetIntersection().intersects(expressions); } + @SuppressWarnings("NullAway") private SetIntersection createSetIntersection() { return usesFieldRef() ? SetIntersection.arrayAsSet(fieldReference) : SetIntersection.arrayAsSet(expression); } @@ -156,6 +159,7 @@ public SetUnion union(AggregationExpression... expressions) { return createSetUnion().union(expressions); } + @SuppressWarnings("NullAway") private SetUnion createSetUnion() { return usesFieldRef() ? SetUnion.arrayAsSet(fieldReference) : SetUnion.arrayAsSet(expression); } @@ -182,6 +186,7 @@ public SetDifference differenceTo(AggregationExpression expression) { return createSetDifference().differenceTo(expression); } + @SuppressWarnings("NullAway") private SetDifference createSetDifference() { return usesFieldRef() ? SetDifference.arrayAsSet(fieldReference) : SetDifference.arrayAsSet(expression); } @@ -208,6 +213,7 @@ public SetIsSubset isSubsetOf(AggregationExpression expression) { return createSetIsSubset().isSubsetOf(expression); } + @SuppressWarnings("NullAway") private SetIsSubset createSetIsSubset() { return usesFieldRef() ? SetIsSubset.arrayAsSet(fieldReference) : SetIsSubset.arrayAsSet(expression); } @@ -218,6 +224,7 @@ private SetIsSubset createSetIsSubset() { * * @return new instance of {@link AnyElementTrue}. */ + @SuppressWarnings("NullAway") public AnyElementTrue anyElementTrue() { return usesFieldRef() ? AnyElementTrue.arrayAsSet(fieldReference) : AnyElementTrue.arrayAsSet(expression); } @@ -228,6 +235,7 @@ public AnyElementTrue anyElementTrue() { * * @return new instance of {@link AllElementsTrue}. */ + @SuppressWarnings("NullAway") public AllElementsTrue allElementsTrue() { return usesFieldRef() ? AllElementsTrue.arrayAsSet(fieldReference) : AllElementsTrue.arrayAsSet(expression); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java index 55d3ae4cbe..c353d0525a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java @@ -688,9 +688,9 @@ public enum WindowUnits implements WindowUnit { */ public static class SetWindowFieldsOperationBuilder { - private Object partitionBy; - private SortOperation sortOperation; - private WindowOutput output; + private @Nullable Object partitionBy; + private @Nullable SortOperation sortOperation; + private @Nullable WindowOutput output; /** * Specify the field to group by. @@ -850,6 +850,8 @@ public SetWindowFieldsOperationBuilder partitionBy(Object value) { * @return new instance of {@link SetWindowFieldsOperation}. */ public SetWindowFieldsOperation build() { + + Assert.notNull(output, "Output must be set first"); return new SetWindowFieldsOperation(partitionBy, sortOperation, output); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SortByCountOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SortByCountOperation.java index 84160885eb..e6a9a23d31 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SortByCountOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SortByCountOperation.java @@ -67,6 +67,7 @@ public SortByCountOperation(AggregationExpression groupByExpression) { } @Override + @SuppressWarnings("NullAway") public Document toDocument(AggregationOperationContext context) { return new Document(getOperator(), groupByExpression == null ? context.getReference(groupByField).toString() diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformer.java index c8c1b9c553..ade4f5328e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformer.java @@ -83,7 +83,7 @@ class SpelExpressionTransformer implements AggregationExpressionTransformer { * @param params must not be {@literal null} * @return */ - public Object transform(String expression, AggregationOperationContext context, Object... params) { + public @Nullable Object transform(String expression, AggregationOperationContext context, Object... params) { Assert.notNull(expression, "Expression must not be null"); Assert.notNull(context, "AggregationOperationContext must not be null"); @@ -96,7 +96,7 @@ public Object transform(String expression, AggregationOperationContext context, return transform(new AggregationExpressionTransformationContext<>(node, null, null, context)); } - public Object transform(AggregationExpressionTransformationContext context) { + public @Nullable Object transform(AggregationExpressionTransformationContext context) { return lookupConversionFor(context.getCurrentNode()).convert(context); } @@ -137,7 +137,7 @@ private static abstract class ExpressionNodeConversion * * @param transformer must not be {@literal null}. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "NullAway"}) public ExpressionNodeConversion(AggregationExpressionTransformer transformer) { Assert.notNull(transformer, "Transformer must not be null"); @@ -165,7 +165,7 @@ protected boolean supports(ExpressionNode node) { * @param context must not be {@literal null}. * @return */ - protected Object transform(ExpressionNode node, AggregationExpressionTransformationContext context) { + protected @Nullable Object transform(ExpressionNode node, AggregationExpressionTransformationContext context) { Assert.notNull(node, "ExpressionNode must not be null"); Assert.notNull(context, "AggregationExpressionTransformationContext must not be null"); @@ -183,7 +183,7 @@ protected Object transform(ExpressionNode node, AggregationExpressionTransformat * @param context must not be {@literal null}. * @return */ - protected Object transform(ExpressionNode node, @Nullable ExpressionNode parent, @Nullable Document operation, + protected @Nullable Object transform(ExpressionNode node, @Nullable ExpressionNode parent, @Nullable Document operation, AggregationExpressionTransformationContext context) { Assert.notNull(node, "ExpressionNode must not be null"); @@ -194,7 +194,7 @@ protected Object transform(ExpressionNode node, @Nullable ExpressionNode parent, } @Override - public Object transform(AggregationExpressionTransformationContext context) { + public @Nullable Object transform(AggregationExpressionTransformationContext context) { return transformer.transform(context); } @@ -204,7 +204,7 @@ public Object transform(AggregationExpressionTransformationContext context); + protected abstract @Nullable Object convert(AggregationExpressionTransformationContext context); } /** @@ -247,6 +247,7 @@ protected Object convert(AggregationExpressionTransformationContext context, OperatorNode currentNode) { @@ -301,7 +302,7 @@ private static class IndexerNodeConversion extends ExpressionNodeConversion context) { + protected @Nullable Object convert(AggregationExpressionTransformationContext context) { return context.addToPreviousOrReturn(context.getCurrentNode().getValue()); } @@ -354,7 +355,7 @@ private static class PropertyOrFieldReferenceNodeConversion extends ExpressionNo } @Override - protected Object convert(AggregationExpressionTransformationContext context) { + protected @Nullable Object convert(AggregationExpressionTransformationContext context) { String fieldReference = context.getFieldReference().toString(); return context.addToPreviousOrReturn(fieldReference); @@ -380,14 +381,14 @@ private static class LiteralNodeConversion extends ExpressionNodeConversion context) { + protected @Nullable Object convert(AggregationExpressionTransformationContext context) { LiteralNode node = context.getCurrentNode(); Object value = node.getValue(); if (context.hasPreviousOperation()) { - if (node.isUnaryMinus(context.getParentNode())) { + if (node.isUnaryMinus(context.getParentNode()) && value != null) { // unary minus operator return NumberUtils.convertNumberToTargetClass(((Number) value).doubleValue() * -1, (Class) value.getClass()); // retain type, e.g. int to -int @@ -418,7 +419,7 @@ private static class MethodReferenceNodeConversion extends ExpressionNodeConvers } @Override - protected Object convert(AggregationExpressionTransformationContext context) { + protected @Nullable Object convert(AggregationExpressionTransformationContext context) { MethodReferenceNode node = context.getCurrentNode(); AggregationMethodReference methodReference = node.getMethodReference(); @@ -468,7 +469,7 @@ private static class CompoundExpressionNodeConversion extends ExpressionNodeConv } @Override - protected Object convert(AggregationExpressionTransformationContext context) { + protected @Nullable Object convert(AggregationExpressionTransformationContext context) { ExpressionNode currentNode = context.getCurrentNode(); @@ -502,7 +503,7 @@ static class NotOperatorNodeConversion extends ExpressionNodeConversion context) { + protected @Nullable Object convert(AggregationExpressionTransformationContext context) { NotOperatorNode node = context.getCurrentNode(); List args = new ArrayList<>(); @@ -536,7 +537,7 @@ static class ValueRetrievingNodeConversion extends ExpressionNodeConversion context) { + protected @Nullable Object convert(AggregationExpressionTransformationContext context) { Object value = context.getCurrentNode().getValue(); return ObjectUtils.isArray(value) ? Arrays.asList(ObjectUtils.toObjectArray(value)) : value; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java index 9788497601..40f88b1339 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.regex.Pattern; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.mongodb.util.RegexFlags; import org.springframework.util.Assert; @@ -60,8 +61,8 @@ public static StringOperatorFactory valueOf(AggregationExpression fieldReference */ public static class StringOperatorFactory { - private final String fieldReference; - private final AggregationExpression expression; + private final @Nullable String fieldReference; + private final @Nullable AggregationExpression expression; /** * Creates new {@link StringOperatorFactory} for given {@literal fieldReference}. @@ -126,6 +127,7 @@ public Concat concat(String value) { return createConcat().concat(value); } + @SuppressWarnings("NullAway") private Concat createConcat() { return usesFieldRef() ? Concat.valueOf(fieldReference) : Concat.valueOf(expression); } @@ -153,6 +155,7 @@ public Substr substring(int start, int nrOfChars) { return createSubstr().substring(start, nrOfChars); } + @SuppressWarnings("NullAway") private Substr createSubstr() { return usesFieldRef() ? Substr.valueOf(fieldReference) : Substr.valueOf(expression); } @@ -162,6 +165,7 @@ private Substr createSubstr() { * * @return new instance of {@link ToLower}. */ + @SuppressWarnings("NullAway") public ToLower toLower() { return usesFieldRef() ? ToLower.lowerValueOf(fieldReference) : ToLower.lowerValueOf(expression); } @@ -171,6 +175,7 @@ public ToLower toLower() { * * @return new instance of {@link ToUpper}. */ + @SuppressWarnings("NullAway") public ToUpper toUpper() { return usesFieldRef() ? ToUpper.upperValueOf(fieldReference) : ToUpper.upperValueOf(expression); } @@ -214,6 +219,7 @@ public StrCaseCmp strCaseCmpValueOf(AggregationExpression expression) { return createStrCaseCmp().strcasecmpValueOf(expression); } + @SuppressWarnings("NullAway") private StrCaseCmp createStrCaseCmp() { return usesFieldRef() ? StrCaseCmp.valueOf(fieldReference) : StrCaseCmp.valueOf(expression); } @@ -260,6 +266,7 @@ public IndexOfBytes indexOf(AggregationExpression expression) { return createIndexOfBytesSubstringBuilder().indexOf(expression); } + @SuppressWarnings("NullAway") private IndexOfBytes.SubstringBuilder createIndexOfBytesSubstringBuilder() { return usesFieldRef() ? IndexOfBytes.valueOf(fieldReference) : IndexOfBytes.valueOf(expression); } @@ -306,6 +313,7 @@ public IndexOfCP indexOfCP(AggregationExpression expression) { return createIndexOfCPSubstringBuilder().indexOf(expression); } + @SuppressWarnings("NullAway") private IndexOfCP.SubstringBuilder createIndexOfCPSubstringBuilder() { return usesFieldRef() ? IndexOfCP.valueOf(fieldReference) : IndexOfCP.valueOf(expression); } @@ -343,6 +351,7 @@ public Split split(AggregationExpression expression) { return createSplit().split(expression); } + @SuppressWarnings("NullAway") private Split createSplit() { return usesFieldRef() ? Split.valueOf(fieldReference) : Split.valueOf(expression); } @@ -353,6 +362,7 @@ private Split createSplit() { * * @return new instance of {@link StrLenBytes}. */ + @SuppressWarnings("NullAway") public StrLenBytes length() { return usesFieldRef() ? StrLenBytes.stringLengthOf(fieldReference) : StrLenBytes.stringLengthOf(expression); } @@ -363,6 +373,7 @@ public StrLenBytes length() { * * @return new instance of {@link StrLenCP}. */ + @SuppressWarnings("NullAway") public StrLenCP lengthCP() { return usesFieldRef() ? StrLenCP.stringLengthOfCP(fieldReference) : StrLenCP.stringLengthOfCP(expression); } @@ -390,6 +401,7 @@ public SubstrCP substringCP(int codePointStart, int nrOfCodePoints) { return createSubstrCP().substringCP(codePointStart, nrOfCodePoints); } + @SuppressWarnings("NullAway") private SubstrCP createSubstrCP() { return usesFieldRef() ? SubstrCP.valueOf(fieldReference) : SubstrCP.valueOf(expression); } @@ -432,6 +444,7 @@ public Trim trim(AggregationExpression expression) { return trim().charsOf(expression); } + @SuppressWarnings("NullAway") private Trim createTrim() { return usesFieldRef() ? Trim.valueOf(fieldReference) : Trim.valueOf(expression); } @@ -474,6 +487,7 @@ public LTrim ltrim(AggregationExpression expression) { return ltrim().charsOf(expression); } + @SuppressWarnings("NullAway") private LTrim createLTrim() { return usesFieldRef() ? LTrim.valueOf(fieldReference) : LTrim.valueOf(expression); } @@ -516,6 +530,7 @@ public RTrim rtrim(AggregationExpression expression) { return rtrim().charsOf(expression); } + @SuppressWarnings("NullAway") private RTrim createRTrim() { return usesFieldRef() ? RTrim.valueOf(fieldReference) : RTrim.valueOf(expression); } @@ -572,6 +587,7 @@ public RegexFind regexFind(String regex, String options) { return createRegexFind().regex(regex).options(options); } + @SuppressWarnings("NullAway") private RegexFind createRegexFind() { return usesFieldRef() ? RegexFind.valueOf(fieldReference) : RegexFind.valueOf(expression); } @@ -628,6 +644,7 @@ public RegexFindAll regexFindAll(String regex, String options) { return createRegexFindAll().regex(regex).options(options); } + @SuppressWarnings("NullAway") private RegexFindAll createRegexFindAll() { return usesFieldRef() ? RegexFindAll.valueOf(fieldReference) : RegexFindAll.valueOf(expression); } @@ -683,6 +700,7 @@ public RegexMatch regexMatch(String regex, String options) { return createRegexMatch().regex(regex).options(options); } + @SuppressWarnings("NullAway") private RegexMatch createRegexMatch() { return usesFieldRef() ? RegexMatch.valueOf(fieldReference) : RegexMatch.valueOf(expression); } @@ -713,6 +731,7 @@ public ReplaceOne replaceOne(AggregationExpression search, String replacement) { return createReplaceOne().findValueOf(search).replacement(replacement); } + @SuppressWarnings("NullAway") private ReplaceOne createReplaceOne() { return usesFieldRef() ? ReplaceOne.valueOf(fieldReference) : ReplaceOne.valueOf(expression); } @@ -743,6 +762,7 @@ public ReplaceAll replaceAll(AggregationExpression search, String replacement) { return createReplaceAll().findValueOf(search).replacement(replacement); } + @SuppressWarnings("NullAway") private ReplaceAll createReplaceAll() { return usesFieldRef() ? ReplaceAll.valueOf(fieldReference) : ReplaceAll.valueOf(expression); } 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 918a961cc9..623af471d3 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 @@ -201,6 +201,8 @@ public static PathBuilder newBuilder() { @Override public UnwindOperation preserveNullAndEmptyArrays() { + Assert.notNull(field, "Path needs to be set first"); + if (arrayIndex != null) { return new UnwindOperation(field, arrayIndex, true); } @@ -211,6 +213,8 @@ public UnwindOperation preserveNullAndEmptyArrays() { @Override public UnwindOperation skipNullAndEmptyArrays() { + Assert.notNull(field, "Path needs to be set first"); + if (arrayIndex != null) { return new UnwindOperation(field, arrayIndex, false); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/VariableOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/VariableOperators.java index bb21d4fc81..b5a9ca0f21 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/VariableOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/VariableOperators.java @@ -332,6 +332,7 @@ private Document getMappedVariable(ExpressionVariable var, AggregationOperationC return new Document(var.variableName, var.expression); } + @SuppressWarnings("NullAway") private Object getMappedIn(AggregationOperationContext context) { return expression.toDocument(new NestedDelegatingExpressionAggregationOperationContext(context, this.vars.stream().map(var -> Fields.field(var.variableName)).collect(Collectors.toList()))); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolverCallback.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolverCallback.java index bf6b882375..fd80029118 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolverCallback.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolverCallback.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.core.convert; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; /** @@ -31,5 +32,5 @@ public interface DbRefResolverCallback { * @param property will never be {@literal null}. * @return */ - Object resolve(MongoPersistentProperty property); + @Nullable Object resolve(MongoPersistentProperty property); } 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 5858f38e6b..c72bc4b886 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 @@ -34,6 +34,7 @@ import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import com.mongodb.DBRef; @@ -71,7 +72,7 @@ public DefaultDbRefResolver(MongoDatabaseFactory mongoDbFactory) { } @Override - public Object resolveDbRef(MongoPersistentProperty property, @Nullable DBRef dbref, DbRefResolverCallback callback, + public @Nullable Object resolveDbRef(MongoPersistentProperty property, @Nullable DBRef dbref, DbRefResolverCallback callback, DbRefProxyHandler handler) { Assert.notNull(property, "Property must not be null"); @@ -86,7 +87,7 @@ public Object resolveDbRef(MongoPersistentProperty property, @Nullable DBRef dbr } @Override - public Document fetch(DBRef dbRef) { + public @Nullable Document fetch(DBRef dbRef) { return getReferenceLoader().fetchOne( DocumentReferenceQuery.forSingleDocument(Filters.eq(FieldName.ID.name(), dbRef.getId())), ReferenceCollection.fromDBRef(dbRef)); @@ -171,7 +172,7 @@ private boolean isLazyDbRef(MongoPersistentProperty property) { private static Stream documentWithId(Object identifier, Collection documents) { return documents.stream() // - .filter(it -> it.get(BasicMongoPersistentProperty.ID_FIELD_NAME).equals(identifier)) // + .filter(it -> ObjectUtils.nullSafeEquals(it.get(BasicMongoPersistentProperty.ID_FIELD_NAME), identifier)) // .limit(1); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolverCallback.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolverCallback.java index 82e5c9d0eb..376e0dd8cd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolverCallback.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolverCallback.java @@ -17,6 +17,7 @@ import org.bson.Document; import org.bson.conversions.Bson; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.model.ValueExpressionEvaluator; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; @@ -53,7 +54,7 @@ class DefaultDbRefResolverCallback implements DbRefResolverCallback { } @Override - public Object resolve(MongoPersistentProperty property) { + public @Nullable Object resolve(MongoPersistentProperty property) { return resolver.getValueInternal(property, surroundingObject, evaluator, path); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java index 07752caa6b..f5db41f006 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java @@ -114,7 +114,7 @@ public DefaultMongoTypeMapper(@Nullable String typeKey, List accessor, - MappingContext, ?> mappingContext, + @Nullable MappingContext, ?> mappingContext, List mappers) { super(accessor, mappingContext, mappers); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultReferenceResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultReferenceResolver.java index a7b3d6f21f..4df7c02f91 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultReferenceResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultReferenceResolver.java @@ -20,6 +20,7 @@ import java.util.Collections; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.DocumentReference; @@ -63,7 +64,8 @@ public DefaultReferenceResolver(ReferenceLoader referenceLoader, PersistenceExce } @Override - public Object resolveReference(MongoPersistentProperty property, Object source, + @SuppressWarnings("NullAway") + public @Nullable Object resolveReference(MongoPersistentProperty property, Object source, ReferenceLookupDelegate referenceLookupDelegate, MongoEntityReader entityReader) { LookupFunction lookupFunction = (property.isCollectionLike() || property.isMap()) ? collectionLookupFunction @@ -84,6 +86,7 @@ public Object resolveReference(MongoPersistentProperty property, Object source, * @see DBRef#lazy() * @see DocumentReference#lazy() */ + @SuppressWarnings("NullAway") protected boolean isLazyReference(MongoPersistentProperty property) { if (property.isDocumentReference()) { @@ -106,6 +109,7 @@ LazyLoadingProxyFactory getProxyFactory() { return proxyFactory; } + @SuppressWarnings("NullAway") private Object createLazyLoadingProxy(MongoPersistentProperty property, Object source, ReferenceLookupDelegate referenceLookupDelegate, LookupFunction lookupFunction, MongoEntityReader entityReader) { return proxyFactory.createLazyLoadingProxy(property, diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPointerFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPointerFactory.java index 8429584a6f..e03d215088 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPointerFactory.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentPointerFactory.java @@ -70,6 +70,7 @@ class DocumentPointerFactory { this.cache = new WeakHashMap<>(); } + @SuppressWarnings("NullAway") DocumentPointer computePointer( MappingContext, MongoPersistentProperty> mappingContext, MongoPersistentProperty property, Object value, Class typeHint) { @@ -87,7 +88,7 @@ DocumentPointer computePointer( if (usesDefaultLookup(property)) { - MongoPersistentProperty idProperty = persistentEntity.getIdProperty(); + MongoPersistentProperty idProperty = persistentEntity.getRequiredIdProperty(); Object idValue = persistentEntity.getIdentifierAccessor(value).getIdentifier(); if (idProperty.hasExplicitWriteTarget() @@ -114,6 +115,7 @@ DocumentPointer computePointer( .getDocumentPointer(mappingContext, persistentEntity, propertyAccessor); } + @SuppressWarnings("NullAway") private boolean usesDefaultLookup(MongoPersistentProperty property) { if (property.isDocumentReference()) { @@ -216,9 +218,16 @@ Object updatePlaceholders(org.bson.Document source, org.bson.Document target, MongoPersistentProperty persistentProperty = persistentEntity.getPersistentProperty(entry.getKey()); if (persistentProperty != null && persistentProperty.isEntity()) { - MongoPersistentEntity nestedEntity = mappingContext.getPersistentEntity(persistentProperty.getType()); - target.put(entry.getKey(), updatePlaceholders(document, new Document(), mappingContext, - nestedEntity, nestedEntity.getPropertyAccessor(propertyAccessor.getProperty(persistentProperty)))); + MongoPersistentEntity nestedEntity = mappingContext.getRequiredPersistentEntity(persistentProperty.getType()); + Object propertyValue = propertyAccessor.getProperty(persistentProperty); + + if(propertyValue == null) { + target.put(entry.getKey(), propertyValue); + } else { + PersistentPropertyAccessor nestedAccessor = nestedEntity.getPropertyAccessor(propertyValue); + target.put(entry.getKey(), updatePlaceholders(document, new Document(), mappingContext, + nestedEntity, nestedAccessor)); + } } else { target.put(entry.getKey(), updatePlaceholders((Document) entry.getValue(), new Document(), mappingContext, persistentEntity, propertyAccessor)); @@ -236,7 +245,7 @@ Object updatePlaceholders(org.bson.Document source, org.bson.Document target, String fieldName = entry.getKey().equals(FieldName.ID.name()) ? "id" : entry.getKey(); if (!fieldName.contains(".")) { - Object targetValue = propertyAccessor.getProperty(persistentEntity.getPersistentProperty(fieldName)); + Object targetValue = propertyAccessor.getProperty(persistentEntity.getRequiredPersistentProperty(fieldName)); target.put(attribute, targetValue); continue; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java index ed8530d0c5..b1e894efe9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core.convert; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; /** * The source object to resolve document references upon. Encapsulates the actual source and the reference specific @@ -66,7 +67,7 @@ public Object getSelf() { * @param source * @return */ - static @Nullable Object getTargetSource(Object source) { + static @Nullable Object getTargetSource(@Nullable Object source) { return source instanceof DocumentReferenceSource referenceSource ? referenceSource.getTargetSource() : source; } @@ -76,7 +77,8 @@ public Object getSelf() { * @param self * @return */ - static Object getSelf(Object self) { + @Contract("null -> null") + static @Nullable Object getSelf(@Nullable Object self) { return self instanceof DocumentReferenceSource referenceSource ? referenceSource.getSelf() : self; } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/GeoConverters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/GeoConverters.java index 2bca260b79..ae73ab68bd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/GeoConverters.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/GeoConverters.java @@ -25,6 +25,7 @@ import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; @@ -45,6 +46,7 @@ import org.springframework.data.mongodb.core.geo.GeoJsonPolygon; import org.springframework.data.mongodb.core.geo.Sphere; import org.springframework.data.mongodb.core.query.GeoCommand; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.NumberUtils; import org.springframework.util.ObjectUtils; @@ -130,7 +132,8 @@ enum DocumentToPointConverter implements Converter { INSTANCE; @Override - public Point convert(Document source) { + @Contract("null -> null; !null -> !null") + public @Nullable Point convert(@Nullable Document source) { if (source == null) { return null; @@ -157,7 +160,8 @@ enum PointToDocumentConverter implements Converter { INSTANCE; @Override - public Document convert(Point source) { + @Contract("null -> null; !null -> !null") + public @Nullable Document convert(@Nullable Point source) { return source == null ? null : new Document("x", source.getX()).append("y", source.getY()); } } @@ -174,7 +178,8 @@ enum BoxToDocumentConverter implements Converter { INSTANCE; @Override - public Document convert(Box source) { + @Contract("null -> null; !null -> !null") + public @Nullable Document convert(@Nullable Box source) { if (source == null) { return null; @@ -199,7 +204,9 @@ enum DocumentToBoxConverter implements Converter { INSTANCE; @Override - public Box convert(Document source) { + @Contract("null -> null; !null -> !null") + @SuppressWarnings("NullAway") + public @Nullable Box convert(@Nullable Document source) { if (source == null) { return null; @@ -223,7 +230,8 @@ enum CircleToDocumentConverter implements Converter { INSTANCE; @Override - public Document convert(Circle source) { + @Contract("null -> null; !null -> !null") + public @Nullable Document convert(@Nullable Circle source) { if (source == null) { return null; @@ -249,7 +257,8 @@ enum DocumentToCircleConverter implements Converter { INSTANCE; @Override - public Circle convert(Document source) { + @Contract("null -> null; !null -> !null") + public @Nullable Circle convert(@Nullable Document source) { if (source == null) { return null; @@ -286,7 +295,8 @@ enum SphereToDocumentConverter implements Converter { INSTANCE; @Override - public Document convert(Sphere source) { + @Contract("null -> null; !null -> !null") + public @Nullable Document convert(@Nullable Sphere source) { if (source == null) { return null; @@ -312,7 +322,8 @@ enum DocumentToSphereConverter implements Converter { INSTANCE; @Override - public Sphere convert(Document source) { + @Contract("null -> null; !null -> !null") + public @Nullable Sphere convert(@Nullable Document source) { if (source == null) { return null; @@ -349,7 +360,8 @@ enum PolygonToDocumentConverter implements Converter { INSTANCE; @Override - public Document convert(Polygon source) { + @Contract("null -> null; !null -> !null") + public @Nullable Document convert(@Nullable Polygon source) { if (source == null) { return null; @@ -381,18 +393,20 @@ enum DocumentToPolygonConverter implements Converter { @Override @SuppressWarnings({ "unchecked" }) - public Polygon convert(Document source) { + @Contract("null -> null; !null -> !null") + public @Nullable Polygon convert(@Nullable Document source) { if (source == null) { return null; } List points = (List) source.get("points"); - List newPoints = new ArrayList<>(points.size()); + Assert.notNull(points, "Points elements of polygon must not be null"); + List newPoints = new ArrayList<>(points.size()); for (Document element : points) { - Assert.notNull(element, "Point elements of polygon must not be null"); + Assert.notNull(element, "Point elements of polygon must not contain null"); newPoints.add(DocumentToPointConverter.INSTANCE.convert(element)); } @@ -412,7 +426,8 @@ enum GeoCommandToDocumentConverter implements Converter { @Override @SuppressWarnings("rawtypes") - public Document convert(GeoCommand source) { + @Contract("null -> null; !null -> !null") + public @Nullable Document convert(@Nullable GeoCommand source) { if (source == null) { return null; @@ -463,7 +478,8 @@ enum GeoJsonToDocumentConverter implements Converter, Document> { INSTANCE; @Override - public Document convert(GeoJson source) { + @Contract("null -> null; !null -> !null") + public @Nullable Document convert(@Nullable GeoJson source) { if (source == null) { return null; @@ -490,7 +506,7 @@ public Document convert(GeoJson source) { private Object convertIfNecessary(Object candidate) { - if (candidate instanceof GeoJson geoJson) { + if (candidate instanceof GeoJson geoJson) { return convertIfNecessary(geoJson.getCoordinates()); } @@ -551,7 +567,8 @@ enum DocumentToGeoJsonPointConverter implements Converter null; !null -> !null") + public @Nullable GeoJsonPoint convert(@Nullable Document source) { if (source == null) { return null; @@ -560,7 +577,10 @@ public GeoJsonPoint convert(Document source) { Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "Point"), String.format("Cannot convert type '%s' to Point", source.get("type"))); - List dbl = (List) source.get("coordinates"); + if(!(source.get("coordinates") instanceof List sourceCoordinates)) { + throw new IllegalArgumentException("Coordinates need to be present"); + } + List dbl = (List) sourceCoordinates; return new GeoJsonPoint(toPrimitiveDoubleValue(dbl.get(0)), toPrimitiveDoubleValue(dbl.get(1))); } } @@ -574,7 +594,8 @@ enum DocumentToGeoJsonPolygonConverter implements Converter null; !null -> !null") + public @Nullable GeoJsonPolygon convert(@Nullable Document source) { if (source == null) { return null; @@ -596,7 +617,8 @@ enum DocumentToGeoJsonMultiPolygonConverter implements Converter null; !null -> !null") + public @Nullable GeoJsonMultiPolygon convert(@Nullable Document source) { if (source == null) { return null; @@ -606,8 +628,9 @@ public GeoJsonMultiPolygon convert(Document source) { String.format("Cannot convert type '%s' to MultiPolygon", source.get("type"))); List dbl = (List) source.get("coordinates"); - List polygones = new ArrayList<>(); + Assert.notNull(dbl, "Source needs to contain coordinates"); + List polygones = new ArrayList<>(dbl.size()); for (Object polygon : dbl) { polygones.add(toGeoJsonPolygon((List) polygon)); } @@ -625,7 +648,8 @@ enum DocumentToGeoJsonLineStringConverter implements Converter null; !null -> !null") + public @Nullable GeoJsonLineString convert(@Nullable Document source) { if (source == null) { return null; @@ -649,7 +673,8 @@ enum DocumentToGeoJsonMultiPointConverter implements Converter null; !null -> !null") + public @Nullable GeoJsonMultiPoint convert(@Nullable Document source) { if (source == null) { return null; @@ -673,7 +698,8 @@ enum DocumentToGeoJsonMultiLineStringConverter implements Converter null; !null -> !null") + public @Nullable GeoJsonMultiLineString convert(@Nullable Document source) { if (source == null) { return null; @@ -682,10 +708,13 @@ public GeoJsonMultiLineString convert(Document source) { Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "MultiLineString"), String.format("Cannot convert type '%s' to MultiLineString", source.get("type"))); - List lines = new ArrayList<>(); - List cords = (List) source.get("coordinates"); + if(!(source.get("coordinates") instanceof List coordinates)) { + throw new IllegalArgumentException("coordinates need to be present"); + } + + List lines = new ArrayList<>(coordinates.size()); - for (Object line : cords) { + for (Object line : coordinates) { lines.add(new GeoJsonLineString(toListOfPoint((List) line))); } return new GeoJsonMultiLineString(lines); @@ -700,9 +729,9 @@ enum DocumentToGeoJsonGeometryCollectionConverter implements Converter null; !null -> !null") + public @Nullable GeoJsonGeometryCollection convert(@Nullable Document source) { if (source == null) { return null; @@ -711,8 +740,12 @@ public GeoJsonGeometryCollection convert(Document source) { Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "GeometryCollection"), String.format("Cannot convert type '%s' to GeometryCollection", source.get("type"))); - List> geometries = new ArrayList<>(); - for (Object o : (List) source.get("geometries")) { + if(!(source.get("geometries") instanceof List sourceGeometries)) { + throw new IllegalArgumentException("Geometries need to be present"); + } + + List> geometries = new ArrayList<>(sourceGeometries.size()); + for (Object o : sourceGeometries) { geometries.add(toGenericGeoJson((Document) o)); } @@ -732,7 +765,10 @@ static List toList(Point point) { * @since 1.7 */ @SuppressWarnings("unchecked") - static List toListOfPoint(List listOfCoordinatePairs) { + @Contract("null -> fail") + static List toListOfPoint(@Nullable List listOfCoordinatePairs) { + + Assert.notNull(listOfCoordinatePairs, "ListOfCoordinatePairs must not be null"); List points = new ArrayList<>(listOfCoordinatePairs.size()); @@ -755,7 +791,10 @@ static List toListOfPoint(List listOfCoordinatePairs) { * @return never {@literal null}. * @since 1.7 */ - static GeoJsonPolygon toGeoJsonPolygon(List dbList) { + @Contract("null -> fail") + static GeoJsonPolygon toGeoJsonPolygon(@Nullable List dbList) { + + Assert.notNull(dbList, "DbList must not be null"); GeoJsonPolygon polygon = new GeoJsonPolygon(toListOfPoint((List) dbList.get(0))); return dbList.size() > 1 ? polygon.withInnerRing(toListOfPoint((List) dbList.get(1))) : polygon; @@ -794,7 +833,8 @@ private static GeoJson toGenericGeoJson(Document source) { throw new IllegalArgumentException(String.format("No converter found capable of converting GeoJson type %s", type)); } - private static double toPrimitiveDoubleValue(Object value) { + @Contract("null -> fail") + private static double toPrimitiveDoubleValue(@Nullable Object value) { Assert.isInstanceOf(Number.class, value, "Argument must be a Number"); return NumberUtils.convertNumberToTargetClass((Number) value, Double.class); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java index 739d57f6ed..14e101e103 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java @@ -124,7 +124,7 @@ private ProxyFactory prepareProxyFactory(Class propertyType, Supplier propertyType = property.getType(); LazyLoadingInterceptor interceptor = new LazyLoadingInterceptor(property, callback, source, exceptionTranslator); @@ -180,10 +180,10 @@ public static class LazyLoadingInterceptor private final Lock readLock = Lock.of(rwLock.readLock()); private final Lock writeLock = Lock.of(rwLock.writeLock()); - private final MongoPersistentProperty property; - private final DbRefResolverCallback callback; - private final Object source; - private final PersistenceExceptionTranslator exceptionTranslator; + private final @Nullable MongoPersistentProperty property; + private final @Nullable DbRefResolverCallback callback; + private final @Nullable Object source; + private final @Nullable PersistenceExceptionTranslator exceptionTranslator; private volatile boolean resolved; private @Nullable Object result; @@ -201,7 +201,7 @@ public static LazyLoadingInterceptor none() { } @Override - public @Nullable Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable { + public @Nullable Object intercept(Object o, Method method, @Nullable Object @Nullable[] args, @Nullable MethodProxy proxy) throws Throwable { ReflectionUtils.makeAccessible(method); return method.invoke(o, args); @@ -209,8 +209,8 @@ public static LazyLoadingInterceptor none() { }; } - public LazyLoadingInterceptor(MongoPersistentProperty property, DbRefResolverCallback callback, Object source, - PersistenceExceptionTranslator exceptionTranslator) { + public LazyLoadingInterceptor(@Nullable MongoPersistentProperty property, @Nullable DbRefResolverCallback callback, @Nullable Object source, + @Nullable PersistenceExceptionTranslator exceptionTranslator) { this.property = property; this.callback = callback; @@ -224,7 +224,7 @@ public LazyLoadingInterceptor(MongoPersistentProperty property, DbRefResolverCal } @Override - public @Nullable Object intercept(Object o, Method method, Object @Nullable[] args, @Nullable MethodProxy proxy) throws Throwable { + public @Nullable Object intercept(Object o, Method method, @Nullable Object @Nullable[] args, @Nullable MethodProxy proxy) throws Throwable { if (INITIALIZE_METHOD.equals(method)) { return ensureResolved(); @@ -244,7 +244,7 @@ public LazyLoadingInterceptor(MongoPersistentProperty property, DbRefResolverCal return proxyToString(source); } - if (ReflectionUtils.isEqualsMethod(method)) { + if (ReflectionUtils.isEqualsMethod(method) && args != null) { return proxyEquals(o, args[0]); } 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 84e8964705..288de0889f 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 @@ -745,6 +745,7 @@ && peek(collection) instanceof Document) { } } + @SuppressWarnings("NullAway") private @Nullable Object readUnwrapped(ConversionContext context, DocumentAccessor documentAccessor, MongoPersistentProperty prop, MongoPersistentEntity unwrappedEntity) { @@ -761,6 +762,7 @@ && peek(collection) instanceof Document) { } @Override + @SuppressWarnings("NullAway") public DBRef toDBRef(Object object, @Nullable MongoPersistentProperty referringProperty) { org.springframework.data.mongodb.core.mapping.DBRef annotation; @@ -2460,7 +2462,7 @@ interface ValueConverter { * * @param */ - interface ContainerValueConverter<@Nullable T> { + interface ContainerValueConverter { @Nullable Object convert(ConversionContext context, @Nullable T source, TypeInformation typeHint); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConversionContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConversionContext.java index 8deb2bbc89..74be2949d0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConversionContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConversionContext.java @@ -68,12 +68,12 @@ public MongoPersistentProperty getProperty() { @Override @SuppressWarnings("unchecked") - public T write(@Nullable Object value, TypeInformation target) { + public @Nullable T write(@Nullable Object value, TypeInformation target) { return (T) mongoConverter.convertToMongoType(value, target); } @Override - public T read(@Nullable Object value, TypeInformation target) { + public @Nullable T read(@Nullable Object value, TypeInformation target) { return value instanceof Bson bson ? mongoConverter.read(target.getType(), bson) : ValueConversionContext.super.read(value, target); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java index 0316251dc1..67f9d5ec46 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java @@ -28,6 +28,7 @@ import java.util.regex.Pattern; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Example; import org.springframework.data.domain.ExampleMatcher.NullHandler; import org.springframework.data.domain.ExampleMatcher.PropertyValueTransformer; @@ -98,13 +99,17 @@ public Document getMappedExample(Example example) { * @param entity must not be {@literal null}. * @return */ - public Document getMappedExample(Example example, MongoPersistentEntity entity) { + @SuppressWarnings("NullAway") + public Document getMappedExample(Example example, @Nullable MongoPersistentEntity entity) { Assert.notNull(example, "Example must not be null"); - Assert.notNull(entity, "MongoPersistentEntity must not be null"); Document reference = (Document) converter.convertToMongoType(example.getProbe()); + if(entity != null) { + entity = mappingContext.getRequiredPersistentEntity(example.getProbeType()); + } + if (entity.getIdProperty() != null && ClassUtils.isAssignable(entity.getType(), example.getProbeType())) { Object identifier = entity.getIdentifierAccessor(example.getProbe()).getIdentifier(); 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 6c739a8563..7aa9019ffd 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 @@ -37,6 +37,7 @@ import org.bson.Document; import org.bson.conversions.Bson; import org.bson.types.ObjectId; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.converter.Converter; @@ -135,6 +136,7 @@ public Document getMappedObject(Bson query, Optional entity) { if (isNestedKeyword(query)) { @@ -687,7 +689,7 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers return converted; } - if (property != null && !documentField.getProperty().isMap() && sourceValue instanceof Document document) { + if (property != null && !property.isMap() && sourceValue instanceof Document document) { return BsonUtils.mapValues(document, (key, val) -> { if (isKeyword(key)) { @@ -697,11 +699,11 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers }); } - return valueConverter.write(value, conversionContext); + return value != null ? valueConverter.write(value, conversionContext) : value; } @Nullable - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "NullAway"}) private Object convertIdField(Field documentField, Object source) { Object value = source; @@ -913,6 +915,7 @@ protected boolean isKeyword(String candidate) { * @author Oliver Gierke * @author Christoph Strobl */ + @SuppressWarnings("NullAway") static class Keyword { private static final Set NON_DBREF_CONVERTING_KEYWORDS = Set.of("$", "$size", "$slice", "$gt", "$lt"); @@ -1158,6 +1161,7 @@ public MetadataBackedField(String name, MongoPersistentEntity entity, * @param context must not be {@literal null}. * @param property may be {@literal null}. */ + @SuppressWarnings("NullAway") public MetadataBackedField(String name, MongoPersistentEntity entity, MappingContext, MongoPersistentProperty> context, @Nullable MongoPersistentProperty property) { @@ -1201,7 +1205,7 @@ public MongoPersistentProperty getProperty() { } @Override - public MongoPersistentEntity getPropertyEntity() { + public @Nullable MongoPersistentEntity getPropertyEntity() { MongoPersistentProperty property = getProperty(); return property == null ? null : mappingContext.getPersistentEntity(property); } @@ -1217,7 +1221,7 @@ public boolean isAssociation() { } @Override - public Association getAssociation() { + public @Nullable Association getAssociation() { return association; } @@ -1417,6 +1421,7 @@ protected Converter getPropertyConverter() { * @return * @since 1.7 */ + @SuppressWarnings("NullAway") protected Converter getAssociationConverter() { return new AssociationConverter(name, getAssociation()); } @@ -1568,7 +1573,7 @@ public AssociationConverter(String name, Association as } @Override - public String convert(MongoPersistentProperty source) { + public @Nullable String convert(MongoPersistentProperty source) { if (associationFound) { return null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java index b686fa7d5e..a0e5a6f2bb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java @@ -125,7 +125,7 @@ public ReferenceLookupDelegate( @Nullable private Iterable retrieveRawDocuments(MongoPersistentProperty property, Object source, - LookupFunction lookupFunction, Object value) { + LookupFunction lookupFunction, @Nullable Object value) { DocumentReferenceQuery filter = computeFilter(property, source, spELContext); if (filter instanceof NoResultsFilter) { @@ -136,7 +136,8 @@ private Iterable retrieveRawDocuments(MongoPersistentProperty property return lookupFunction.apply(filter, referenceCollection); } - private ReferenceCollection computeReferenceContext(MongoPersistentProperty property, Object value, + @SuppressWarnings("NullAway") + private ReferenceCollection computeReferenceContext(MongoPersistentProperty property, @Nullable Object value, SpELContext spELContext) { // Use the first value as a reference for others in case of collection like @@ -194,7 +195,7 @@ private ReferenceCollection computeReferenceContext(MongoPersistentProperty prop * @return can be {@literal null}. */ @SuppressWarnings("unchecked") - private T parseValueOrGet(String value, ParameterBindingContext bindingContext, Supplier defaultValue) { + private T parseValueOrGet(String value, ParameterBindingContext bindingContext, Supplier<@Nullable T> defaultValue) { if (!StringUtils.hasText(value)) { return defaultValue.get(); @@ -219,7 +220,7 @@ private T parseValueOrGet(String value, ParameterBindingContext bindingConte return evaluated != null ? evaluated : defaultValue.get(); } - ParameterBindingContext bindingContext(MongoPersistentProperty property, Object source, SpELContext spELContext) { + ParameterBindingContext bindingContext(MongoPersistentProperty property, @Nullable Object source, SpELContext spELContext) { ValueProvider valueProvider = valueProviderFor(DocumentReferenceSource.getTargetSource(source)); @@ -227,7 +228,7 @@ ParameterBindingContext bindingContext(MongoPersistentProperty property, Object () -> evaluationContextFor(property, source, spELContext)); } - ValueProvider valueProviderFor(Object source) { + ValueProvider valueProviderFor(@Nullable Object source) { return index -> { if (source instanceof Document document) { @@ -237,7 +238,7 @@ ValueProvider valueProviderFor(Object source) { }; } - EvaluationContext evaluationContextFor(MongoPersistentProperty property, Object source, SpELContext spELContext) { + EvaluationContext evaluationContextFor(MongoPersistentProperty property, @Nullable Object source, SpELContext spELContext) { Object target = source instanceof DocumentReferenceSource documentReferenceSource ? documentReferenceSource.getTargetSource() @@ -263,7 +264,7 @@ EvaluationContext evaluationContextFor(MongoPersistentProperty property, Object * @param spELContext must not be {@literal null}. * @return never {@literal null}. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked","NullAway"}) DocumentReferenceQuery computeFilter(MongoPersistentProperty property, Object source, SpELContext spELContext) { DocumentReference documentReference = property.isDocumentReference() ? property.getDocumentReference() 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 c0253c2d70..ad3e4986fb 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 @@ -129,7 +129,7 @@ public static boolean isUpdateObject(@Nullable Document updateObj) { * org.springframework.data.mongodb.core.mapping.MongoPersistentEntity) */ @Override - protected Object delegateConvertToMongoType(Object source, @Nullable MongoPersistentEntity entity) { + protected @Nullable Object delegateConvertToMongoType(Object source, @Nullable MongoPersistentEntity entity) { if (entity != null && entity.isUnwrapped()) { return converter.convertToMongoType(source, entity); @@ -140,7 +140,8 @@ protected Object delegateConvertToMongoType(Object source, @Nullable MongoPersis } @Override - protected Entry getMappedObjectForField(Field field, Object rawValue) { + @SuppressWarnings("NullAway") + protected Entry getMappedObjectForField(Field field, @Nullable Object rawValue) { if (isDocument(rawValue)) { @@ -196,11 +197,12 @@ private boolean isQuery(@Nullable Object value) { return value instanceof Query; } - private Document getMappedValue(@Nullable Field field, Modifier modifier) { + private @Nullable Document getMappedValue(@Nullable Field field, Modifier modifier) { return new Document(modifier.getKey(), getMappedModifier(field, modifier)); } - private Object getMappedModifier(@Nullable Field field, Modifier modifier) { + @SuppressWarnings("NullAway") + private @Nullable Object getMappedModifier(@Nullable Field field, Modifier modifier) { Object value = modifier.getValue(); @@ -211,7 +213,7 @@ private Object getMappedModifier(@Nullable Field field, Modifier modifier) { : getMappedSort(sortObject, field.getPropertyEntity()); } - if (isAssociationConversionNecessary(field, value)) { + if (field != null && isAssociationConversionNecessary(field, value)) { if (ObjectUtils.isArray(value) || value instanceof Collection) { List targetPointers = new ArrayList<>(); for (Object val : converter.getConversionService().convert(value, List.class)) { @@ -229,7 +231,7 @@ private Object getMappedModifier(@Nullable Field field, Modifier modifier) { private TypeInformation getTypeHintForEntity(@Nullable Object source, MongoPersistentEntity entity) { TypeInformation info = entity.getTypeInformation(); - Class type = info.getActualType().getType(); + Class type = info.getRequiredActualType().getType(); if (source == null || type.isInterface() || java.lang.reflect.Modifier.isAbstract(type.getModifiers())) { return info; @@ -247,7 +249,7 @@ private TypeInformation getTypeHintForEntity(@Nullable Object source, MongoPe } @Override - protected Field createPropertyField(MongoPersistentEntity entity, String key, + protected Field createPropertyField(@Nullable MongoPersistentEntity entity, String key, MappingContext, MongoPersistentProperty> mappingContext) { return entity == null ? super.createPropertyField(entity, key, mappingContext) @@ -306,6 +308,7 @@ protected Converter getPropertyConverter() { } @Override + @SuppressWarnings("NullAway") protected Converter getAssociationConverter() { return new UpdateAssociationConverter(getMappingContext(), getAssociation(), key); } @@ -333,7 +336,7 @@ public UpdateAssociationConverter( } @Override - public String convert(MongoPersistentProperty source) { + public @Nullable String convert(MongoPersistentProperty source) { return super.convert(source) == null ? null : mapper.mapPropertyName(source); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/EncryptingConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/EncryptingConverter.java index 4097be7704..b31d8a2b7c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/EncryptingConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/EncryptingConverter.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.core.convert.encryption; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.convert.MongoConversionContext; import org.springframework.data.mongodb.core.convert.MongoValueConverter; import org.springframework.data.mongodb.core.encryption.EncryptionContext; @@ -28,7 +29,7 @@ public interface EncryptingConverter extends MongoValueConverter { @Override - default S read(Object value, MongoConversionContext context) { + default @Nullable S read(Object value, MongoConversionContext context) { return decrypt(value, buildEncryptionContext(context)); } @@ -39,10 +40,10 @@ default S read(Object value, MongoConversionContext context) { * @param context the context to operate in. * @return never {@literal null}. */ - S decrypt(Object encryptedValue, EncryptionContext context); + @Nullable S decrypt(Object encryptedValue, EncryptionContext context); @Override - default T write(Object value, MongoConversionContext context) { + default @Nullable T write(Object value, MongoConversionContext context) { return encrypt(value, buildEncryptionContext(context)); } @@ -53,7 +54,7 @@ default T write(Object value, MongoConversionContext context) { * @param context the context to operate in. * @return never {@literal null}. */ - T encrypt(Object value, EncryptionContext context); + T encrypt(@Nullable Object value, EncryptionContext context); /** * Obtain the {@link EncryptionContext} for a given {@link MongoConversionContext value conversion context}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java index fc2d38afc3..976bd988c4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java @@ -47,22 +47,22 @@ public MongoPersistentProperty getProperty() { } @Override - public Object convertToMongoType(Object value) { + public @Nullable Object convertToMongoType(Object value) { return conversionContext.write(value); } @Override - public EvaluationContext getEvaluationContext(Object source) { + public EvaluationContext getEvaluationContext(@Nullable Object source) { return conversionContext.getSpELContext().getEvaluationContext(source); } @Override - public T read(@Nullable Object value, TypeInformation target) { + public @Nullable T read(@Nullable Object value, TypeInformation target) { return conversionContext.read(value, target); } @Override - public T write(@Nullable Object value, TypeInformation target) { + public @Nullable T write(@Nullable Object value, TypeInformation target) { return conversionContext.write(value, target); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java index e7b427fcf2..f169fe96c3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java @@ -141,7 +141,8 @@ public Object decrypt(Object encryptedValue, EncryptionContext context) { } @Override - public Object encrypt(Object value, EncryptionContext context) { + @SuppressWarnings("NullAway") + public Object encrypt(@Nullable Object value, EncryptionContext context) { if (LOGGER.isDebugEnabled()) { LOGGER.debug(String.format("Encrypting %s.%s.", getProperty(context).getOwner().getName(), diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java index f2461d9df6..87fbb7a9a5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java @@ -43,7 +43,7 @@ public interface EncryptionContext { * @param value * @return */ - Object convertToMongoType(Object value); + @Nullable Object convertToMongoType(Object value); /** * Reads the value as an instance of the {@link PersistentProperty#getTypeInformation() property type}. @@ -123,6 +123,6 @@ default T read(@Nullable Object value, Class target) { @Nullable Object lookupValue(String path); - EvaluationContext getEvaluationContext(Object source); + EvaluationContext getEvaluationContext(@Nullable Object source); } 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 9f1567c0ec..cfae6761a8 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 @@ -139,7 +139,7 @@ private static void registerDeserializersIn(SimpleModule module) { private static abstract class GeoJsonDeserializer> extends JsonDeserializer { @Override - public @Nullable T deserialize(@Nullable JsonParser jp, @Nullable DeserializationContext ctxt) throws IOException { + public @Nullable T deserialize(JsonParser jp, @Nullable DeserializationContext ctxt) throws IOException { JsonNode node = jp.readValueAsTree(); JsonNode coordinates = node.get("coordinates"); 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 55ead9de14..30b9b49ce7 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 @@ -41,7 +41,7 @@ public class GeospatialIndex implements IndexDefinition { private @Nullable Integer max; private @Nullable Integer bits; private GeoSpatialIndexType type = GeoSpatialIndexType.GEO_2D; - private Double bucketSize = MongoClientVersion.isVersion5orNewer() ? null : 1.0; + private @Nullable Double bucketSize = MongoClientVersion.isVersion5orNewer() ? null : 1.0; 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/IndexInfo.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexInfo.java index 3ea9edc36b..e9817746c3 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 @@ -32,6 +32,7 @@ import org.springframework.util.Assert; import org.springframework.util.NumberUtils; import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; /** * Index information for a MongoDB index. @@ -89,7 +90,7 @@ public IndexInfo(List indexFields, String name, boolean unique, bool */ public static IndexInfo indexInfoOf(Document sourceDocument) { - Document keyDbObject = (Document) sourceDocument.get("key"); + Document keyDbObject = sourceDocument.get("key", new Document()); int numberOfElements = keyDbObject.keySet().size(); List indexFields = new ArrayList(numberOfElements); @@ -105,9 +106,10 @@ public static IndexInfo indexInfoOf(Document sourceDocument) { } else if ("text".equals(value)) { Document weights = (Document) sourceDocument.get("weights"); - - for (String fieldName : weights.keySet()) { - indexFields.add(IndexField.text(fieldName, Float.valueOf(weights.get(fieldName).toString()))); + if(weights != null) { + for (String fieldName : weights.keySet()) { + indexFields.add(IndexField.text(fieldName, Float.valueOf(weights.get(fieldName).toString()))); + } } } else { @@ -129,7 +131,7 @@ public static IndexInfo indexInfoOf(Document sourceDocument) { } } - String name = sourceDocument.get("name").toString(); + String name = ObjectUtils.nullSafeToString(sourceDocument.get("name")); boolean unique = sourceDocument.get("unique", false); boolean sparse = sourceDocument.get("sparse", false); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java index 05a96a7a1b..9daedff91c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java @@ -165,7 +165,7 @@ private void potentiallyAddIndexForProperty(MongoPersistentEntity root, Mongo } if (persistentProperty.isEntity()) { - indexes.addAll(resolveIndexForEntity(mappingContext.getPersistentEntity(persistentProperty), + indexes.addAll(resolveIndexForEntity(mappingContext.getRequiredPersistentEntity(persistentProperty), persistentProperty.isUnwrapped() ? "" : persistentProperty.getFieldName(), Path.of(persistentProperty), root.getCollection(), guard)); } @@ -232,7 +232,7 @@ private void guardAndPotentiallyAddIndexForProperty(MongoPersistentProperty pers if (persistentProperty.isEntity()) { try { - indexes.addAll(resolveIndexForEntity(mappingContext.getPersistentEntity(persistentProperty), + indexes.addAll(resolveIndexForEntity(mappingContext.getRequiredPersistentEntity(persistentProperty), propertyDotPath.toString(), propertyPath, collection, guard)); } catch (CyclicPropertyReferenceException e) { LOGGER.info(e.getMessage()); @@ -385,7 +385,7 @@ public void doWithPersistentProperty(MongoPersistentProperty persistentProperty) try { appendTextIndexInformation(propertyDotPath, propertyPath, indexDefinitionBuilder, - mappingContext.getPersistentEntity(persistentProperty.getActualType()), optionsForNestedType, guard); + mappingContext.getRequiredPersistentEntity(persistentProperty.getActualType()), optionsForNestedType, guard); } catch (CyclicPropertyReferenceException e) { LOGGER.info(e.getMessage()); } catch (InvalidDataAccessApiUsageException e) { @@ -576,7 +576,7 @@ private org.bson.Document resolveCompoundIndexKeyFromStringDefinition(String dot return new IndexDefinitionHolder(dotPath, indexDefinition, collection); } - private PartialIndexFilter evaluatePartialFilter(String filterExpression, PersistentEntity entity) { + private PartialIndexFilter evaluatePartialFilter(String filterExpression, @Nullable PersistentEntity entity) { Object result = ExpressionUtils.evaluate(filterExpression, () -> getEvaluationContextForProperty(entity)); @@ -587,7 +587,7 @@ private PartialIndexFilter evaluatePartialFilter(String filterExpression, Persis return PartialIndexFilter.of(BsonUtils.parse(filterExpression, null)); } - private org.bson.Document evaluateWildcardProjection(String projectionExpression, PersistentEntity entity) { + private org.bson.Document evaluateWildcardProjection(String projectionExpression, @Nullable PersistentEntity entity) { Object result = ExpressionUtils.evaluate(projectionExpression, () -> getEvaluationContextForProperty(entity)); @@ -598,7 +598,7 @@ private org.bson.Document evaluateWildcardProjection(String projectionExpression return BsonUtils.parse(projectionExpression, null); } - private Collation evaluateCollation(String collationExpression, PersistentEntity entity) { + private Collation evaluateCollation(String collationExpression, @Nullable PersistentEntity entity) { Object result = ExpressionUtils.evaluate(collationExpression, () -> getEvaluationContextForProperty(entity)); if (result instanceof org.bson.Document document) { 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 e524a2602c..e865009319 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 @@ -189,7 +189,7 @@ public void verify() { } @Override - public EvaluationContext getEvaluationContext(Object rootObject) { + public EvaluationContext getEvaluationContext(@Nullable Object rootObject) { return super.getEvaluationContext(rootObject); } @@ -247,7 +247,7 @@ public int compare(@Nullable MongoPersistentProperty o1, @Nullable MongoPersiste return o1.getFieldOrder() - o2.getFieldOrder(); } - return o1.getFieldOrder(); + return o1 != null ? o1.getFieldOrder() : -1; } } @@ -281,7 +281,7 @@ public int compare(@Nullable MongoPersistentProperty o1, @Nullable MongoPersiste } - @SuppressWarnings("null") + @SuppressWarnings("NullAway") Field currentIdPropertyField = currentIdProperty.getField(); if (newIdPropertyIsExplicit && currentIdPropertyIsExplicit) { @@ -355,7 +355,7 @@ private void assertUniqueness(MongoPersistentProperty property) { } @Override - public Collection getEncryptionKeyIds() { + public @Nullable Collection getEncryptionKeyIds() { Encrypted encrypted = findAnnotation(Encrypted.class); if (encrypted == null) { @@ -408,6 +408,7 @@ private static void potentiallyAssertTextScoreType(MongoPersistentProperty persi } } + @SuppressWarnings("NullAway") private static void potentiallyAssertDBRefTargetType(MongoPersistentProperty persistentProperty) { if (persistentProperty.isDbReference() && persistentProperty.getDBRef().lazy()) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java index 079f571880..027a570fa3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java @@ -255,6 +255,7 @@ public MongoField getMongoField() { } @Override + @SuppressWarnings("NullAway") public Collection getEncryptionKeyIds() { Encrypted encrypted = findAnnotation(Encrypted.class); @@ -279,6 +280,7 @@ public Collection getEncryptionKeyIds() { return target; } + @SuppressWarnings("NullAway") protected MongoField doGetMongoField() { MongoFieldBuilder builder = MongoField.builder(); @@ -292,6 +294,7 @@ protected MongoField doGetMongoField() { return builder.build(); } + @SuppressWarnings("NullAway") private String doGetFieldName() { if (isIdProperty()) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/CachingMongoPersistentProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/CachingMongoPersistentProperty.java index be31e2334f..eb8d08db64 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/CachingMongoPersistentProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/CachingMongoPersistentProperty.java @@ -121,12 +121,12 @@ public boolean isDbReference() { } @Override - public DBRef getDBRef() { + public @Nullable DBRef getDBRef() { return dbref.getNullable(); } @Override - public DocumentReference getDocumentReference() { + public @Nullable DocumentReference getDocumentReference() { return documentReference.getNullable(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java index d714054693..ac7f24a555 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java @@ -47,6 +47,7 @@ public UnwrappedMongoPersistentProperty(MongoPersistentProperty delegate, Unwrap } @Override + @SuppressWarnings("NullAway") public String getFieldName() { if (!context.getProperty().isUnwrapped()) { @@ -57,6 +58,7 @@ public String getFieldName() { } @Override + @SuppressWarnings("NullAway") public boolean hasExplicitFieldName() { return delegate.hasExplicitFieldName() || !ObjectUtils.isEmpty(context.getProperty().findAnnotation(Unwrapped.class).prefix()); @@ -143,6 +145,7 @@ public Class getType() { } @Override + @SuppressWarnings("NullAway") public MongoField getMongoField() { if (!context.getProperty().isUnwrapped()) { @@ -333,7 +336,7 @@ public boolean hasActualTypeAnnotation(Class annotationTyp } @Override - public TypeInformation getAssociationTargetTypeInformation() { + public @Nullable TypeInformation getAssociationTargetTypeInformation() { return delegate.getAssociationTargetTypeInformation(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceResults.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceResults.java index 72f4a9e2fd..1d4f644bd1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceResults.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceResults.java @@ -145,7 +145,8 @@ private static String parseOutputCollection(Document rawResults) { return null; } - return resultField instanceof Document document ? document.get("collection").toString() + return resultField instanceof Document document && document.containsKey("collection") + ? document.get("collection").toString() : resultField.toString(); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java index f0d0119f77..64146bb076 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java @@ -215,12 +215,12 @@ public ChangeStreamOptions getChangeStreamOptions() { } @Override - public String getCollectionName() { + public @Nullable String getCollectionName() { return collectionName; } @Override - public String getDatabaseName() { + public @Nullable String getDatabaseName() { return databaseName; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java index b150589d8a..87eb0d1cf9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java @@ -51,7 +51,7 @@ abstract class CursorReadingTask implements Task { private State state = State.CREATED; - private MongoCursor cursor; + private @Nullable MongoCursor cursor; /** * @param template must not be {@literal null}. @@ -109,6 +109,7 @@ public void run() { * is immediately {@link MongoCursor#close() closed} and a new {@link MongoCursor} is requested until a valid one is * retrieved or the {@link #state} changes. */ + @SuppressWarnings("NullAway") private void start() { lock.executeWithoutResult(() -> { @@ -188,6 +189,7 @@ public boolean awaitStart(Duration timeout) throws InterruptedException { return awaitStart.await(timeout.toNanos(), TimeUnit.NANOSECONDS); } + @SuppressWarnings("NullAway") protected Message createMessage(T source, Class targetType, RequestOptions options) { SimpleMessage message = new SimpleMessage<>(source, source, MessageProperties.builder() diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SubscriptionRequest.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SubscriptionRequest.java index e28c0b1408..7b914f16f5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SubscriptionRequest.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SubscriptionRequest.java @@ -105,7 +105,7 @@ static RequestOptions justDatabase(String database) { return new RequestOptions() { @Override - public String getCollectionName() { + public @Nullable String getCollectionName() { return null; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java index 6f2f7ce39f..06f63c09a7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java @@ -136,7 +136,7 @@ public static TailableCursorRequestOptionsBuilder builder() { } @Override - public String getCollectionName() { + public @Nullable String getCollectionName() { return collectionName; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java index c1ca9791a3..9ca6ce9099 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java @@ -21,6 +21,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -370,6 +371,7 @@ public Collation maxVariable(String maxVariable) { * * @return the native MongoDB {@link Document} representation of the {@link Collation}. */ + @SuppressWarnings("NullAway") public Document toDocument() { return map(toMongoDocumentConverter()); } @@ -379,7 +381,7 @@ public Document toDocument() { * * @return he native MongoDB representation of the {@link Collation}. */ - public com.mongodb.client.model.Collation toMongoCollation() { + public com.mongodb.client.model.@Nullable Collation toMongoCollation() { return map(toMongoCollationConverter()); } @@ -390,7 +392,7 @@ public com.mongodb.client.model.Collation toMongoCollation() { * @param * @return the converted result. */ - public R map(Converter mapper) { + public @Nullable R map(Converter mapper) { return mapper.convert(this); } 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 b97ed50134..aa1068ca5b 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 @@ -1094,7 +1094,7 @@ private boolean isEqual(@Nullable Object left, @Nullable Object right) { if (Collection.class.isAssignableFrom(left.getClass())) { - if (!Collection.class.isAssignableFrom(right.getClass())) { + if (right == null || !Collection.class.isAssignableFrom(right.getClass())) { return false; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java index c6bf9992e5..5ec4af3989 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Meta.java @@ -50,8 +50,8 @@ private enum MetaKey { private Map values = Collections.emptyMap(); private Set flags = Collections.emptySet(); - private Integer cursorBatchSize; - private Boolean allowDiskUse; + private @Nullable Integer cursorBatchSize; + private @Nullable Boolean allowDiskUse; public Meta() {} 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 c5d0a1638a..6adb1afdde 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 @@ -69,7 +69,7 @@ public class Query implements ReadConcernAware, ReadPreferenceAware { private long skip; private Limit limit = Limit.unlimited(); - private KeysetScrollPosition keysetScrollPosition; + private @Nullable KeysetScrollPosition keysetScrollPosition; private @Nullable ReadConcern readConcern; private @Nullable ReadPreference readPreference; @@ -243,7 +243,7 @@ public boolean hasReadConcern() { } @Override - public ReadConcern getReadConcern() { + public @Nullable ReadConcern getReadConcern() { return this.readConcern; } @@ -253,7 +253,7 @@ public boolean hasReadPreference() { } @Override - public ReadPreference getReadPreference() { + public @Nullable ReadPreference getReadPreference() { if (readPreference == null) { return getMeta().getFlags().contains(CursorOption.SECONDARY_READS) ? ReadPreference.primaryPreferred() : null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java index b7f877ce49..29f8adb2c6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/SerializationUtils.java @@ -25,6 +25,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; +import org.springframework.lang.Contract; import org.springframework.util.ObjectUtils; /** @@ -109,6 +110,7 @@ private static void toFlatMap(String currentPath, Object source, Map null; !null -> !null") public static @Nullable String serializeToJsonSafely(@Nullable Object value) { if (value == null) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java index b570855c98..3a312d9a9c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java @@ -176,14 +176,14 @@ private Optional getOrCreateDescription() { */ static class Restrictions { - private final Collection possibleValues; + private final Collection possibleValues; private final Collection allOf; private final Collection anyOf; private final Collection oneOf; private final @Nullable JsonSchemaObject notMatch; - Restrictions(Collection possibleValues, Collection allOf, - Collection anyOf, Collection oneOf, JsonSchemaObject notMatch) { + Restrictions(Collection possibleValues, Collection allOf, + Collection anyOf, Collection oneOf, @Nullable JsonSchemaObject notMatch) { this.possibleValues = possibleValues; this.allOf = allOf; @@ -205,7 +205,7 @@ static Restrictions empty() { * @param possibleValues must not be {@literal null}. * @return */ - Restrictions possibleValues(Collection possibleValues) { + Restrictions possibleValues(Collection possibleValues) { Assert.notNull(possibleValues, "PossibleValues must not be null"); return new Restrictions(possibleValues, allOf, anyOf, oneOf, notMatch); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformationContextSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformationContextSupport.java index f2a1394ab1..89edd4eab2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformationContextSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformationContextSupport.java @@ -108,7 +108,7 @@ public boolean parentIsSameOperation() { * @param value * @return */ - public Document addToPreviousOperation(Object value) { + public Document addToPreviousOperation(@Nullable Object value) { Assert.state(previousOperationObject != null, "No previous operation available"); @@ -122,11 +122,14 @@ public Document addToPreviousOperation(Object value) { * @param value * @return */ - public Object addToPreviousOrReturn(Object value) { + public @Nullable Object addToPreviousOrReturn(@Nullable Object value) { return hasPreviousOperation() ? addToPreviousOperation(value) : value; } + @SuppressWarnings("unchecked") private List extractArgumentListFrom(Document context) { - return (List) context.get(context.keySet().iterator().next()); + + Object o = context.get(context.keySet().iterator().next()); + return o instanceof List l ? (List) l : List.of(); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformer.java index 512f753042..da5748f523 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/ExpressionTransformer.java @@ -15,6 +15,8 @@ */ package org.springframework.data.mongodb.core.spel; +import org.jspecify.annotations.Nullable; + /** * SPI interface to implement components that can transform an {@link ExpressionTransformationContextSupport} into an * object. @@ -29,5 +31,5 @@ public interface ExpressionTransformer fromStream(InputStream stream) { */ public static class GridFsUploadBuilder { - private Object id; - private Lazy dataStream; - private String filename; - private Options options = Options.none(); + private @Nullable Object id; + private @Nullable Lazy dataStream; + private @Nullable String filename; + private @Nullable Options options = Options.none(); private GridFsUploadBuilder() {} @@ -137,6 +137,7 @@ public GridFsUploadBuilder content(Supplier stream) { * @param * @return this. */ + @SuppressWarnings("unchecked") public GridFsUploadBuilder id(T1 id) { this.id = id; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java index b1c81dbbbe..121dccee65 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java @@ -133,7 +133,7 @@ public Collation getCollation() { } @Override - public Object[] getValues() { + public @Nullable Object @Nullable[] getValues() { return super.getValues(); } 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 666329c947..e1abcdc2ab 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 @@ -77,14 +77,14 @@ public MongoRepositoryFactory(MongoOperations mongoOperations) { } @Override - public void setBeanClassLoader(ClassLoader classLoader) { + public void setBeanClassLoader(@Nullable ClassLoader classLoader) { super.setBeanClassLoader(classLoader); crudMethodMetadataPostProcessor.setBeanClassLoader(classLoader); } @Override - protected ProjectionFactory getProjectionFactory(ClassLoader classLoader, BeanFactory beanFactory) { + protected ProjectionFactory getProjectionFactory(@Nullable ClassLoader classLoader, @Nullable BeanFactory beanFactory) { return this.operations.getConverter().getProjectionFactory(); } 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 b443ae3f2e..13fabb0c03 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 @@ -79,14 +79,14 @@ public ReactiveMongoRepositoryFactory(ReactiveMongoOperations mongoOperations) { } @Override - public void setBeanClassLoader(ClassLoader classLoader) { + public void setBeanClassLoader(@Nullable ClassLoader classLoader) { super.setBeanClassLoader(classLoader); crudMethodMetadataPostProcessor.setBeanClassLoader(classLoader); } @Override - protected ProjectionFactory getProjectionFactory(ClassLoader classLoader, BeanFactory beanFactory) { + protected ProjectionFactory getProjectionFactory(@Nullable ClassLoader classLoader, @Nullable BeanFactory beanFactory) { return this.operations.getConverter().getProjectionFactory(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java index f26c1ada25..276b46e086 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java @@ -327,14 +327,14 @@ public static Object toJavaType(BsonValue value) { * @throws IllegalArgumentException if {@literal source} does not correspond to a {@link BsonValue} type. * @since 3.0 */ - public static BsonValue simpleToBsonValue(Object source) { + public static BsonValue simpleToBsonValue(@Nullable Object source) { return simpleToBsonValue(source, MongoClientSettings.getDefaultCodecRegistry()); } /** * Convert a given simple value (eg. {@link String}, {@link Long}) to its corresponding {@link BsonValue}. * - * @param source must not be {@literal null}. + * @param source can be {@literal null}. * @param codecRegistry The {@link CodecRegistry} used as a fallback to convert types using native {@link Codec}. Must * not be {@literal null}. * @return the corresponding {@link BsonValue} representation. @@ -342,7 +342,12 @@ public static BsonValue simpleToBsonValue(Object source) { * @since 4.2 */ @SuppressWarnings("unchecked") - public static BsonValue simpleToBsonValue(Object source, CodecRegistry codecRegistry) { + @Contract("null, _ -> !null") + public static BsonValue simpleToBsonValue(@Nullable Object source, CodecRegistry codecRegistry) { + + if(source == null) { + return BsonNull.VALUE; + } if (source instanceof BsonValue bsonValue) { return bsonValue; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/DateTimeFormatter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/DateTimeFormatter.java index b5c26755cf..3961fafc21 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/DateTimeFormatter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/DateTimeFormatter.java @@ -23,6 +23,8 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; +import org.jspecify.annotations.NullUnmarked; + /** * DateTimeFormatter implementation borrowed from MongoDB @@ -33,6 +35,7 @@ * @author Ross Lawley * @since 2.2 */ +@NullUnmarked class DateTimeFormatter { private static final int DATE_STRING_LENGTH = "1970-01-01".length(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/JsonBuffer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/JsonBuffer.java index 4b4b497dae..dcb9a3ff13 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/JsonBuffer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/JsonBuffer.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.util.json; import org.bson.json.JsonParseException; +import org.jspecify.annotations.NullUnmarked; /** * JsonBuffer implementation borrowed from @@ -32,6 +33,7 @@ * @author Christoph Strobl * @since 2.2 */ +@NullUnmarked class JsonScanner { private final JsonBuffer buffer; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/JsonToken.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/JsonToken.java index 293736123e..e73d57774b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/JsonToken.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/JsonToken.java @@ -20,6 +20,7 @@ import org.bson.BsonDouble; import org.bson.json.JsonParseException; import org.bson.types.Decimal128; +import org.jspecify.annotations.NullUnmarked; /** * JsonToken implementation borrowed from { private static final String ID_FIELD_NAME = FieldName.ID.name(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java index 6610326604..c1e519e2f5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java @@ -39,6 +39,7 @@ import org.bson.types.MaxKey; import org.bson.types.MinKey; import org.bson.types.ObjectId; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import org.springframework.data.spel.EvaluationContextProvider; import org.springframework.expression.EvaluationContext; @@ -62,6 +63,7 @@ * @author Rocco Lagrotteria * @since 2.2 */ +@NullUnmarked public class ParameterBindingJsonReader extends AbstractBsonReader { private static final Pattern ENTIRE_QUERY_BINDING_PATTERN = Pattern.compile("^\\?(\\d+)$|^[\\?:][#$]\\{.*\\}$"); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupportUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupportUnitTests.java index 609a456912..b5a40f5738 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupportUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMapReduceOperationSupportUnitTests.java @@ -74,7 +74,7 @@ void usesExtractedCollectionName() { mapReduceOpsSupport.mapReduce(Person.class).map(MAP_FUNCTION).reduce(REDUCE_FUNCTION).all(); verify(template).mapReduce(any(Query.class), eq(Person.class), eq(STAR_WARS), eq(Person.class), eq(MAP_FUNCTION), - eq(REDUCE_FUNCTION), isNull()); + eq(REDUCE_FUNCTION), any()); } @Test // DATAMONGO-1929 @@ -84,7 +84,7 @@ void usesExplicitCollectionName() { .inCollection("the-night-angel").all(); verify(template).mapReduce(any(Query.class), eq(Person.class), eq("the-night-angel"), eq(Person.class), - eq(MAP_FUNCTION), eq(REDUCE_FUNCTION), isNull()); + eq(MAP_FUNCTION), eq(REDUCE_FUNCTION), any()); } @Test // DATAMONGO-1929 @@ -108,7 +108,7 @@ void usesQueryWhenPresent() { mapReduceOpsSupport.mapReduce(Person.class).map(MAP_FUNCTION).reduce(REDUCE_FUNCTION).matching(query).all(); verify(template).mapReduce(eq(query), eq(Person.class), eq(STAR_WARS), eq(Person.class), eq(MAP_FUNCTION), - eq(REDUCE_FUNCTION), isNull()); + eq(REDUCE_FUNCTION), any()); } @Test // DATAMONGO-2416 @@ -121,7 +121,7 @@ void usesCriteriaWhenPresent() { .matching(where("lastname").is("skywalker")).all(); verify(template).mapReduce(eq(query), eq(Person.class), eq(STAR_WARS), eq(Person.class), eq(MAP_FUNCTION), - eq(REDUCE_FUNCTION), isNull()); + eq(REDUCE_FUNCTION), any()); } @Test // DATAMONGO-1929 @@ -132,7 +132,7 @@ void usesProjectionWhenPresent() { mapReduceOpsSupport.mapReduce(Person.class).map(MAP_FUNCTION).reduce(REDUCE_FUNCTION).as(Jedi.class).all(); verify(template).mapReduce(any(Query.class), eq(Person.class), eq(STAR_WARS), eq(Jedi.class), eq(MAP_FUNCTION), - eq(REDUCE_FUNCTION), isNull()); + eq(REDUCE_FUNCTION), any()); } interface Contact {} From 754c183cfad2ca8fd44126d48ff25af9f350d27a Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 17 Mar 2025 15:36:26 +0100 Subject: [PATCH 15/17] tmp save ..:: GAME OVER ::.. continue from last save point? [y/n] --- .../data/mongodb/BulkOperationException.java | 3 +- .../data/mongodb/core/CollectionOptions.java | 2 +- .../core/CollectionPreparerSupport.java | 6 +- .../mongodb/core/DefaultBulkOperations.java | 5 +- .../data/mongodb/core/EntityOperations.java | 26 ++++--- .../data/mongodb/core/MappedDocument.java | 5 +- .../data/mongodb/core/MongoTemplate.java | 74 ++++++++++--------- .../data/mongodb/core/QueryOperations.java | 6 ++ .../data/mongodb/core/ScrollUtils.java | 8 ++ .../core/aggregation/AggregationOptions.java | 6 +- .../core/convert/LazyLoadingProxyFactory.java | 5 +- .../core/convert/MappingMongoConverter.java | 67 ++++++++++------- .../mongodb/core/convert/MongoConverter.java | 2 +- .../mongodb/core/convert/MongoConverters.java | 16 ++-- .../mongodb/core/convert/MongoWriter.java | 2 +- .../encryption/ExplicitEncryptionContext.java | 7 +- .../encryption/MongoEncryptionConverter.java | 2 +- .../core/encryption/EncryptionContext.java | 6 +- .../UnwrappedMongoPersistentEntity.java | 7 +- .../core/messaging/CursorReadingTask.java | 2 +- .../LazyMappingDelegatingMessage.java | 5 +- .../mongodb/core/messaging/SimpleMessage.java | 4 +- .../core/messaging/TailableCursorRequest.java | 1 + .../data/mongodb/core/query/BasicQuery.java | 1 + .../mongodb/core/query/MetricConversion.java | 9 ++- .../data/mongodb/core/query/TextCriteria.java | 4 +- .../mongodb/core/schema/MongoJsonSchema.java | 6 +- .../schema/TypeUnifyingMergeFunction.java | 2 +- .../data/mongodb/gridfs/GridFsResource.java | 7 +- .../data/mongodb/gridfs/GridFsTemplate.java | 2 +- .../data/mongodb/gridfs/GridFsUpload.java | 8 +- .../gridfs/ReactiveGridFsResource.java | 2 +- .../mongodb/gridfs/ReactiveGridFsUpload.java | 9 ++- ...aultMongoHandlerObservationConvention.java | 7 ++ .../observability/MapRequestContext.java | 10 ++- .../observability/MongoHandlerContext.java | 20 ++--- .../repository/query/AbstractMongoQuery.java | 5 +- .../query/AbstractReactiveMongoQuery.java | 4 +- .../repository/query/CollationUtils.java | 2 + .../query/ConvertingParameterAccessor.java | 26 +++---- .../query/MongoParameterAccessor.java | 4 +- .../repository/query/MongoParameters.java | 19 +++-- .../MongoParametersParameterAccessor.java | 15 ++-- .../repository/query/MongoQueryCreator.java | 9 ++- .../repository/query/MongoQueryExecution.java | 8 +- .../repository/query/MongoQueryMethod.java | 4 +- .../repository/query/PartTreeMongoQuery.java | 1 + .../query/ReactiveMongoParameterAccessor.java | 12 ++- .../query/ReactiveMongoQueryExecution.java | 5 ++ .../query/ReactivePartTreeMongoQuery.java | 1 + .../query/ReactiveStringBasedMongoQuery.java | 10 ++- .../query/StringBasedMongoQuery.java | 2 + ...ssionDelegateValueExpressionEvaluator.java | 3 +- .../CrudMethodMetadataPostProcessor.java | 6 +- .../MappingMongoEntityInformation.java | 2 +- .../support/MongoRepositoryFactoryBean.java | 1 + .../QuerydslMongoPredicateExecutor.java | 5 +- .../ReactiveMongoRepositoryFactory.java | 2 + .../ReactiveMongoRepositoryFactoryBean.java | 1 + .../ReactiveSpringDataMongodbQuery.java | 2 +- .../support/SimpleMongoRepository.java | 4 +- .../support/SpringDataMongodbQuery.java | 8 +- .../support/SpringDataMongodbSerializer.java | 2 + .../data/mongodb/util/BsonUtils.java | 17 +++-- .../data/mongodb/util/DurationUtil.java | 6 +- .../util/MongoCompatibilityAdapter.java | 3 +- .../data/mongodb/util/MongoDbErrorCodes.java | 6 +- .../EvaluationContextExpressionEvaluator.java | 2 +- .../query/StubParameterAccessor.java | 2 +- 69 files changed, 355 insertions(+), 198 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java index b36382a58e..f6e36e4622 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java @@ -17,6 +17,7 @@ import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import com.mongodb.MongoBulkWriteException; @@ -43,7 +44,7 @@ public class BulkOperationException extends DataAccessException { * @param message must not be {@literal null}. * @param source must not be {@literal null}. */ - public BulkOperationException(String message, MongoBulkWriteException source) { + public BulkOperationException(@Nullable String message, MongoBulkWriteException source) { super(message, source); 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 4e6fd68be0..1e63c03f05 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 @@ -184,7 +184,7 @@ public CollectionOptions collation(@Nullable Collation collation) { * @since 2.1 */ public CollectionOptions schema(@Nullable MongoJsonSchema schema) { - return validator(Validator.schema(schema)); + return validator(schema != null ? Validator.schema(schema) : null); } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java index 644a3a54d1..93d81d86e0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java @@ -20,11 +20,13 @@ import java.util.function.BiFunction; import java.util.function.Function; +import jakarta.validation.constraints.Null; import org.bson.Document; import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; import com.mongodb.client.MongoCollection; +import org.jspecify.annotations.Nullable; /** * Support class for delegate implementations to apply {@link ReadConcern} and {@link ReadPreference} settings upon @@ -84,7 +86,7 @@ public boolean hasReadConcern() { } @Override - public ReadConcern getReadConcern() { + public @Nullable ReadConcern getReadConcern() { for (Object aware : sources) { if (aware instanceof ReadConcernAware rca && rca.hasReadConcern()) { @@ -108,7 +110,7 @@ public boolean hasReadPreference() { } @Override - public ReadPreference getReadPreference() { + public @Nullable ReadPreference getReadPreference() { for (Object aware : sources) { if (aware instanceof ReadPreferenceAware rpa && rpa.hasReadPreference()) { 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 7d3798d83f..638bb699df 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 @@ -412,7 +412,7 @@ public boolean skipEventPublishing() { return eventPublisher == null; } - @SuppressWarnings("rawtypes") + @SuppressWarnings({"rawtypes","NullAway"}) public T callback(Class callbackType, T entity, String collectionName) { if (skipEntityCallbacks()) { @@ -422,7 +422,7 @@ public T callback(Class callbackType, T entity, St return entityCallbacks.callback(callbackType, entity, collectionName); } - @SuppressWarnings("rawtypes") + @SuppressWarnings({"rawtypes","NullAway"}) public T callback(Class callbackType, T entity, Document document, String collectionName) { @@ -433,6 +433,7 @@ public T callback(Class callbackType, T entity, Do return entityCallbacks.callback(callbackType, entity, document, collectionName); } + @SuppressWarnings("NullAway") public void publishEvent(ApplicationEvent event) { if (skipEventPublishing()) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java index 7551b6ea4a..810be0c7a8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java @@ -24,11 +24,13 @@ import java.util.concurrent.TimeUnit; import org.bson.BsonNull; +import org.bson.BsonValue; import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.core.convert.ConversionService; import org.springframework.core.env.Environment; import org.springframework.core.env.EnvironmentCapable; +import org.springframework.core.env.StandardEnvironment; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.convert.CustomConversions; import org.springframework.data.expression.ValueEvaluationContext; @@ -64,6 +66,7 @@ import org.springframework.data.projection.TargetAware; import org.springframework.data.util.Optionals; import org.springframework.expression.spel.support.SimpleEvaluationContext; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.LinkedMultiValueMap; @@ -413,7 +416,7 @@ interface Entity { * * @return */ - Object getId(); + @Nullable Object getId(); /** * Returns the property value for {@code key}. @@ -521,7 +524,7 @@ interface AdaptibleEntity extends Entity { * @param id must not be {@literal null}. * @return */ - @Nullable + @Contract("null -> fail") T populateIdIfNecessary(@Nullable Object id); /** @@ -564,12 +567,12 @@ public String getIdFieldName() { } @Override - public Object getId() { + public @Nullable Object getId() { return getPropertyValue(ID_FIELD); } @Override - public Object getPropertyValue(String key) { + public @Nullable Object getPropertyValue(String key) { return map.get(key); } @@ -579,7 +582,7 @@ public Query getByIdQuery() { } @Override - public @Nullable T populateIdIfNecessary(@Nullable Object id) { + public T populateIdIfNecessary(@Nullable Object id) { map.put(ID_FIELD, id); @@ -721,7 +724,7 @@ public Object getId() { } @Override - public Object getPropertyValue(String key) { + public @Nullable Object getPropertyValue(String key) { return propertyAccessor.getProperty(entity.getRequiredPersistentProperty(key)); } @@ -836,7 +839,6 @@ public Map extractKeys(Document sortObject, Class sourceType) return keyset; } - @Nullable private Object getNestedPropertyValue(String key) { String[] segments = key.split("\\."); @@ -849,6 +851,10 @@ private Object getNestedPropertyValue(String key) { currentValue = currentEntity.getPropertyValue(segment); if (i < segments.length - 1) { + if(currentValue == null) { + return BsonNull.VALUE; + } + currentEntity = entityOperations.forEntity(currentValue); } } @@ -886,7 +892,7 @@ private static AdaptibleEntity of(T bean, } @Override - public @Nullable T populateIdIfNecessary(@Nullable Object id) { + public T populateIdIfNecessary(@Nullable Object id) { if (id == null) { return propertyAccessor.getBean(); @@ -1122,7 +1128,7 @@ public TimeSeriesOptions mapTimeSeriesOptions(TimeSeriesOptions source) { @Override public String getIdKeyName() { - return entity.getIdProperty().getName(); + return entity.getIdProperty() != null ? entity.getIdProperty().getName() : ID_FIELD; } private String mappedNameOrDefault(String name) { @@ -1142,7 +1148,7 @@ private ValueEvaluationContext getEvaluationContextForEntity(@Nullable Persisten return mongoEntity.getValueEvaluationContext(null); } - return ValueEvaluationContext.of(this.environment, SimpleEvaluationContext.forReadOnlyDataBinding().build()); + return ValueEvaluationContext.of(this.environment != null ? this.environment : new StandardEnvironment(), SimpleEvaluationContext.forReadOnlyDataBinding().build()); } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappedDocument.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappedDocument.java index da4766343a..cd9ba90453 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappedDocument.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappedDocument.java @@ -20,6 +20,7 @@ import org.bson.Document; import org.bson.conversions.Bson; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.UpdateDefinition; @@ -70,7 +71,7 @@ public boolean hasNonNullId() { return hasId() && document.get(ID_FIELD) != null; } - public Object getId() { + public @Nullable Object getId() { return document.get(ID_FIELD); } @@ -86,7 +87,7 @@ public Bson getIdFilter() { return new Document(ID_FIELD, document.get(ID_FIELD)); } - public Object get(String key) { + public @Nullable Object get(String key) { return document.get(key); } 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 a173df155e..10683fe3bf 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.projection.EntityProjection; import org.springframework.data.util.CloseableIterator; import org.springframework.data.util.Optionals; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -474,7 +475,7 @@ public Stream stream(Query query, Class entityType, String collectionN return doStream(query, entityType, collectionName, entityType); } - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions","NullAway"}) protected Stream doStream(Query query, Class entityType, String collectionName, Class returnType) { Assert.notNull(query, "Query must not be null"); @@ -507,7 +508,7 @@ public String getCollectionName(Class entityClass) { } @Override - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions","NullAway"}) public Document executeCommand(String jsonCommand) { Assert.hasText(jsonCommand, "JsonCommand must not be null nor empty"); @@ -516,7 +517,7 @@ public Document executeCommand(String jsonCommand) { } @Override - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions","NullAway"}) public Document executeCommand(Document command) { Assert.notNull(command, "Command must not be null"); @@ -525,7 +526,7 @@ public Document executeCommand(Document command) { } @Override - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions","NullAway"}) public Document executeCommand(Document command, @Nullable ReadPreference readPreference) { Assert.notNull(command, "Command must not be null"); @@ -572,7 +573,7 @@ protected void executeQuery(Query query, String collectionName, DocumentCallback } @Override - public T execute(DbCallback action) { + public @Nullable T execute(DbCallback action) { Assert.notNull(action, "DbCallback must not be null"); @@ -585,14 +586,14 @@ public T execute(DbCallback action) { } @Override - public T execute(Class entityClass, CollectionCallback callback) { + public @Nullable T execute(Class entityClass, CollectionCallback callback) { Assert.notNull(entityClass, "EntityClass must not be null"); return execute(getCollectionName(entityClass), callback); } @Override - public T execute(String collectionName, CollectionCallback callback) { + public @Nullable T execute(String collectionName, CollectionCallback callback) { Assert.notNull(collectionName, "CollectionName must not be null"); Assert.notNull(callback, "CollectionCallback must not be null"); @@ -687,6 +688,7 @@ private MongoCollection createView(String name, String source, Aggrega return doCreateView(name, source, aggregation.getAggregationPipeline(), options); } + @SuppressWarnings("NullAway") protected MongoCollection doCreateView(String name, String source, List pipeline, @Nullable ViewOptions options) { @@ -702,8 +704,9 @@ protected MongoCollection doCreateView(String name, String source, Lis } @Override - @SuppressWarnings("ConstantConditions") - public MongoCollection getCollection(String collectionName) { + @SuppressWarnings({"ConstantConditions","NullAway"}) + @Contract("null -> fail") + public MongoCollection getCollection(@Nullable String collectionName) { Assert.notNull(collectionName, "CollectionName must not be null"); @@ -716,7 +719,7 @@ public boolean collectionExists(Class entityClass) { } @Override - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions","NullAway"}) public boolean collectionExists(String collectionName) { Assert.notNull(collectionName, "CollectionName must not be null"); @@ -833,7 +836,7 @@ public boolean exists(Query query, String collectionName) { } @Override - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions", "NullAway"}) public boolean exists(Query query, @Nullable Class entityClass, String collectionName) { if (query == null) { @@ -933,7 +936,7 @@ public List findDistinct(Query query, String field, Class entityClass, } @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked","NullAway"}) public List findDistinct(Query query, String field, String collectionName, Class entityClass, Class resultClass) { @@ -1084,7 +1087,7 @@ public GeoResults geoNear(NearQuery near, Class domainType, String col } @Override - public T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class entityType, + public @Nullable T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class entityType, String collectionName, Class resultType) { Assert.notNull(query, "Query must not be null"); @@ -1194,6 +1197,7 @@ public long estimatedCount(String collectionName) { return doEstimatedCount(CollectionPreparerDelegate.of(this), collectionName, new EstimatedDocumentCountOptions()); } + @SuppressWarnings("NullAway") protected long doEstimatedCount(CollectionPreparer> collectionPreparer, String collectionName, EstimatedDocumentCountOptions options) { return execute(collectionName, @@ -1211,6 +1215,7 @@ public long exactCount(Query query, @Nullable Class entityClass, String colle return doExactCount(createDelegate(query), collectionName, mappedQuery, options); } + @SuppressWarnings("NullAway") protected long doExactCount(CollectionPreparer> collectionPreparer, String collectionName, Document filter, CountOptions options) { return execute(collectionName, collection -> collectionPreparer.prepare(collection) @@ -1509,7 +1514,7 @@ protected T doSave(String collectionName, T objectToSave, MongoWriter wri return maybeCallAfterSave(saved, dbDoc, collectionName); } - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions","NullAway"}) protected Object insertDocument(String collectionName, Document document, Class entityClass) { if (LOGGER.isDebugEnabled()) { @@ -1563,6 +1568,7 @@ protected List insertDocumentList(String collectionName, List return MappedDocument.toIds(documents); } + @SuppressWarnings("NullAway") protected Object saveDocument(String collectionName, Document dbDoc, Class entityClass) { if (LOGGER.isDebugEnabled()) { @@ -1661,7 +1667,7 @@ public UpdateResult updateMulti(Query query, UpdateDefinition update, Class e return doUpdate(collectionName, query, update, entityClass, false, true); } - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions", "NullAway"}) protected UpdateResult doUpdate(String collectionName, Query query, UpdateDefinition update, @Nullable Class entityClass, boolean upsert, boolean multi) { @@ -1777,7 +1783,7 @@ public DeleteResult remove(Query query, Class entityClass, String collectionN return doRemove(collectionName, query, entityClass, true); } - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions","NullAway"}) protected DeleteResult doRemove(String collectionName, Query query, @Nullable Class entityClass, boolean multi) { @@ -2102,6 +2108,7 @@ protected UpdateResult replace(Query query, Class entityType, T replac * @param entityClass * @return */ + @SuppressWarnings("NullAway") protected List doFindAndDelete(String collectionName, Query query, Class entityClass) { List result = find(query, entityClass, collectionName); @@ -2135,7 +2142,7 @@ private AggregationResults doAggregate(Aggregation aggregation, String co return doAggregate(aggregation, collectionName, outputType, context.getAggregationOperationContext()); } - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions","NullAway"}) protected AggregationResults doAggregate(Aggregation aggregation, String collectionName, Class outputType, AggregationOperationContext context) { @@ -2218,7 +2225,7 @@ protected AggregationResults doAggregate(Aggregation aggregation, String }); } - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions","NullAway"}) protected Stream aggregateStream(Aggregation aggregation, String collectionName, Class outputType, @Nullable AggregationOperationContext context) { @@ -2333,7 +2340,7 @@ protected String replaceWithResourceIfNecessary(String function) { } @Override - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions","NullAway"}) public Set getCollectionNames() { return execute(db -> { Set result = new LinkedHashSet<>(); @@ -2417,7 +2424,7 @@ protected MongoCollection doCreateCollection(String collectionName, Do * @return the collection that was created * @since 3.3.3 */ - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions","NullAway"}) protected MongoCollection doCreateCollection(String collectionName, CreateCollectionOptions collectionOptions) { @@ -2688,8 +2695,8 @@ Document getMappedValidator(Validator validator, Class domainType) { * @return the List of converted objects. */ @SuppressWarnings("ConstantConditions") - protected T doFindAndRemove(CollectionPreparer collectionPreparer, String collectionName, Document query, - Document fields, Document sort, @Nullable Collation collation, Class entityClass) { + protected @Nullable T doFindAndRemove(CollectionPreparer collectionPreparer, String collectionName, Document query, + @Nullable Document fields, @Nullable Document sort, @Nullable Collation collation, Class entityClass) { if (LOGGER.isDebugEnabled()) { LOGGER.debug(String.format("findAndRemove using query: %s fields: %s sort: %s for class: %s in collection: %s", @@ -2704,8 +2711,8 @@ protected T doFindAndRemove(CollectionPreparer collectionPreparer, String co } @SuppressWarnings("ConstantConditions") - protected T doFindAndModify(CollectionPreparer collectionPreparer, String collectionName, Document query, - Document fields, Document sort, Class entityClass, UpdateDefinition update, + protected @Nullable T doFindAndModify(CollectionPreparer collectionPreparer, String collectionName, Document query, + @Nullable Document fields, @Nullable Document sort, Class entityClass, UpdateDefinition update, @Nullable FindAndModifyOptions options) { if (options == null) { @@ -2809,6 +2816,7 @@ CollectionPreparer> createCollectionPreparer(Query que collectionName); } + @SuppressWarnings("NullAway") private UpdateResult doReplace(ReplaceOptions options, Class entityType, String collectionName, UpdateContext updateContext, CollectionPreparer> collectionPreparer, Document replacement) { @@ -3082,10 +3090,10 @@ private class ExistsCallback implements CollectionCallback { private final CollectionPreparer collectionPreparer; private final Document mappedQuery; - private final com.mongodb.client.model.Collation collation; + private final com.mongodb.client.model.@Nullable Collation collation; ExistsCallback(CollectionPreparer collectionPreparer, Document mappedQuery, - com.mongodb.client.model.Collation collation) { + com.mongodb.client.model.@Nullable Collation collation) { this.collectionPreparer = collectionPreparer; this.mappedQuery = mappedQuery; @@ -3110,12 +3118,12 @@ private static class FindAndRemoveCallback implements CollectionCallback> collectionPreparer; private final Document query; - private final Document fields; - private final Document sort; + private final @Nullable Document fields; + private final @Nullable Document sort; private final Optional collation; FindAndRemoveCallback(CollectionPreparer> collectionPreparer, Document query, - Document fields, Document sort, @Nullable Collation collation) { + @Nullable Document fields, @Nullable Document sort, @Nullable Collation collation) { this.collectionPreparer = collectionPreparer; this.query = query; @@ -3138,14 +3146,14 @@ private static class FindAndModifyCallback implements CollectionCallback> collectionPreparer; private final Document query; - private final Document fields; - private final Document sort; + private final @Nullable Document fields; + private final @Nullable Document sort; private final Object update; private final List arrayFilters; private final FindAndModifyOptions options; FindAndModifyCallback(CollectionPreparer> collectionPreparer, Document query, - Document fields, Document sort, Object update, List arrayFilters, FindAndModifyOptions options) { + @Nullable Document fields, @Nullable Document sort, Object update, List arrayFilters, FindAndModifyOptions options) { this.collectionPreparer = collectionPreparer; this.query = query; @@ -3585,7 +3593,7 @@ static class SessionBoundMongoTemplate extends MongoTemplate { } @Override - public MongoCollection getCollection(String collectionName) { + public MongoCollection getCollection(@Nullable String collectionName) { // native MongoDB objects that offer methods with ClientSession must not be proxied. return delegate.getCollection(collectionName); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java index ffb89dd300..4ae618eaa1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java @@ -63,6 +63,7 @@ import org.springframework.data.mongodb.util.BsonUtils; import org.springframework.data.projection.EntityProjection; import org.springframework.data.util.Lazy; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import com.mongodb.client.model.CountOptions; @@ -283,6 +284,7 @@ MappedDocument prepareId(Class type) { * @param * @return the {@link MappedDocument} containing the changes. */ + @SuppressWarnings("NullAway") MappedDocument prepareId(@Nullable MongoPersistentEntity entity) { if (entity == null || source.hasId()) { @@ -361,6 +363,7 @@ Document getMappedQuery(@Nullable MongoPersistentEntity entity) { return queryMapper.getMappedObject(getQueryObject(), entity); } + @SuppressWarnings("NullAway") Document getMappedFields(@Nullable MongoPersistentEntity entity, EntityProjection projection) { Document fields = evaluateFields(entity); @@ -888,6 +891,8 @@ Document getMappedShardKey(MongoPersistentEntity entity) { */ List getUpdatePipeline(@Nullable Class domainType) { + Assert.isInstanceOf(AggregationUpdate.class, update); + Class type = domainType != null ? domainType : Object.class; AggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(type, mappingContext, @@ -901,6 +906,7 @@ List getUpdatePipeline(@Nullable Class domainType) { * @param entity * @return */ + @SuppressWarnings("NullAway") Document getMappedUpdate(@Nullable MongoPersistentEntity entity) { if (update != null) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScrollUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScrollUtils.java index 85ddce7656..62e6d6c513 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScrollUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScrollUtils.java @@ -29,6 +29,7 @@ import org.springframework.data.domain.Window; import org.springframework.data.mongodb.core.EntityOperations.Entity; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.util.Assert; /** * Utilities to run scroll queries and create {@link Window} results. @@ -48,7 +49,11 @@ class ScrollUtils { */ static KeysetScrollQuery createKeysetPaginationQuery(Query query, String idPropertyName) { + KeysetScrollPosition keyset = query.getKeyset(); + + Assert.notNull(keyset, "Query.keyset must not be null"); + KeysetScrollDirector director = KeysetScrollDirector.of(keyset.getDirection()); Document sortObject = director.getSortObject(idPropertyName, query); Document fieldsObject = director.getFieldsObject(query.getFieldsObject(), sortObject); @@ -61,6 +66,9 @@ static Window createWindow(Query query, List result, Class sourceTy Document sortObject = query.getSortObject(); KeysetScrollPosition keyset = query.getKeyset(); + + Assert.notNull(keyset, "Query.keyset must not be null"); + Direction direction = keyset.getDirection(); KeysetScrollDirector director = KeysetScrollDirector.of(direction); 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 b9934b5f53..a930b18244 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 @@ -299,7 +299,7 @@ public boolean hasReadConcern() { } @Override - public ReadConcern getReadConcern() { + public @Nullable ReadConcern getReadConcern() { return readConcern.orElse(null); } @@ -309,7 +309,7 @@ public boolean hasReadPreference() { } @Override - public ReadPreference getReadPreference() { + public @Nullable ReadPreference getReadPreference() { return readPreference.orElse(null); } @@ -426,7 +426,7 @@ static Document createCursor(int cursorBatchSize) { */ public static class Builder { - private Boolean allowDiskUse; + private @Nullable Boolean allowDiskUse; private boolean explain; private @Nullable Document cursor; private @Nullable Collation collation; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java index 14e101e103..eff58e7bd4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java @@ -30,6 +30,7 @@ import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import org.springframework.aop.framework.ProxyFactory; import org.springframework.cglib.core.SpringNamingPolicy; @@ -160,6 +161,7 @@ private Class getEnhancedTypeFor(Class type) { return enhancer.createClass(); } + @NullUnmarked public static class LazyLoadingInterceptor implements MethodInterceptor, org.springframework.cglib.proxy.MethodInterceptor, Serializable { @@ -344,6 +346,7 @@ private void readObject(ObjectInputStream in) throws IOException { } } + @SuppressWarnings("NullAway") private @Nullable Object resolve() { try (AcquiredLock l = readLock.lock()) { @@ -366,7 +369,7 @@ private void readObject(ObjectInputStream in) throws IOException { return writeLock.execute(() -> callback.resolve(property)); } catch (RuntimeException ex) { - DataAccessException translatedException = exceptionTranslator.translateExceptionIfPossible(ex); + DataAccessException translatedException = exceptionTranslator != null ? exceptionTranslator.translateExceptionIfPossible(ex) : null; if (translatedException instanceof ClientSessionException) { throw new LazyLoadingException("Unable to lazily resolve DBRef; Invalid session state", ex); 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 288de0889f..2d073869ae 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 @@ -95,6 +95,7 @@ import org.springframework.data.util.Predicates; import org.springframework.data.util.TypeInformation; import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -420,7 +421,7 @@ FieldName getFieldName(MongoPersistentProperty prop) { return accessor.getBean(); } - private Object doReadOrProject(ConversionContext context, Bson source, TypeInformation typeHint, + private Object doReadOrProject(ConversionContext context, @Nullable Bson source, TypeInformation typeHint, EntityProjection typeDescriptor) { if (typeDescriptor.isProjection()) { @@ -468,10 +469,14 @@ protected S read(TypeInformation type, Bson bson) { * @return the converted object, will never be {@literal null}. * @since 3.2 */ - @SuppressWarnings("unchecked") - protected S readDocument(ConversionContext context, Bson bson, + @SuppressWarnings({"unchecked","NullAway"}) + protected S readDocument(ConversionContext context, @Nullable Bson bson, TypeInformation typeHint) { + if(bson == null) { + bson = new Document(); + } + Document document = bson instanceof BasicDBObject dbObject ? new Document(dbObject) : (Document) bson; TypeInformation typeToRead = getTypeMapper().readType(document, typeHint); Class rawType = typeToRead.getType(); @@ -781,6 +786,7 @@ public DBRef toDBRef(Object object, @Nullable MongoPersistentProperty referringP } @Override + @SuppressWarnings("NullAway") public DocumentPointer toDocumentPointer(Object source, @Nullable MongoPersistentProperty referringProperty) { if (source instanceof LazyLoadingProxy proxy) { @@ -800,6 +806,7 @@ public DocumentPointer toDocumentPointer(Object source, @Nullable MongoPersisten throw new IllegalArgumentException("The referringProperty is neither a DBRef nor a document reference"); } + @SuppressWarnings("NullAway") DocumentPointer createDocumentPointer(Object source, @Nullable MongoPersistentProperty referringProperty) { if (referringProperty == null) { @@ -864,7 +871,7 @@ private boolean requiresTypeHint(Class type) { /** * Internal write conversion method which should be used for nested invocations. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked","NullAway"}) protected void writeInternal(@Nullable Object obj, Bson bson, @Nullable TypeInformation typeHint) { if (null == obj) { @@ -1268,6 +1275,7 @@ protected String potentiallyEscapeMapKey(String source) { * * @param key */ + @SuppressWarnings("NullAway") private String potentiallyConvertMapKey(Object key) { if (key instanceof String stringValue) { @@ -1357,8 +1365,9 @@ private void writeSimpleInternal(@Nullable Object value, Bson bson, MongoPersist * Checks whether we have a custom conversion registered for the given value into an arbitrary simple Mongo type. * Returns the converted value if so. If not, we perform special enum handling or simply return the value as is. */ - @Nullable - private Object getPotentiallyConvertedSimpleWrite(@Nullable Object value, @Nullable Class typeHint) { + @Contract("null, _-> null") + @SuppressWarnings("NullAway") + private @Nullable Object getPotentiallyConvertedSimpleWrite(@Nullable Object value, @Nullable Class typeHint) { if (value == null) { return null; @@ -1394,7 +1403,7 @@ private Object getPotentiallyConvertedSimpleWrite(@Nullable Object value, @Nulla * * @since 3.2 */ - protected Object getPotentiallyConvertedSimpleRead(Object value, TypeInformation target) { + protected @Nullable Object getPotentiallyConvertedSimpleRead(@Nullable Object value, TypeInformation target) { return getPotentiallyConvertedSimpleRead(value, target.getType()); } @@ -1402,10 +1411,11 @@ protected Object getPotentiallyConvertedSimpleRead(Object value, TypeInformation * Checks whether we have a custom conversion for the given simple object. Converts the given value if so, applies * {@link Enum} handling or returns the value as is. */ + @Contract("null, _ -> null; _, null -> param1") @SuppressWarnings({ "rawtypes", "unchecked" }) - private Object getPotentiallyConvertedSimpleRead(Object value, @Nullable Class target) { + private @Nullable Object getPotentiallyConvertedSimpleRead(@Nullable Object value, @Nullable Class target) { - if (target == null) { + if (target == null || value == null) { return value; } @@ -1424,6 +1434,7 @@ private Object getPotentiallyConvertedSimpleRead(Object value, @Nullable Class source, + @SuppressWarnings({"unchecked","NullAway"}) + protected @Nullable Object readCollectionOrArray(ConversionContext context, @Nullable Collection source, TypeInformation targetType) { Assert.notNull(targetType, "Target type must not be null"); + Assert.notNull(source, "Source must not be null"); Class collectionType = targetType.isSubTypeOf(Collection.class) // ? targetType.getType() // @@ -1520,7 +1532,7 @@ protected Object readCollectionOrArray(ConversionContext context, Collection * @return the converted {@link Map}, will never be {@literal null}. * @since 3.2 */ - protected Map readMap(ConversionContext context, Bson bson, TypeInformation targetType) { + protected @Nullable Map readMap(ConversionContext context, @Nullable Bson bson, TypeInformation targetType) { Assert.notNull(bson, "Document must not be null"); Assert.notNull(targetType, "TypeInformation must not be null"); @@ -1802,6 +1814,7 @@ private List bulkReadAndConvertDBRefs(ConversionContext context, List event) { if (canPublishEvent()) { @@ -1881,12 +1894,12 @@ public MappingMongoConverter with(MongoDatabaseFactory dbFactory) { return target; } - private T doConvert(Object value, Class target) { + private @Nullable T doConvert(Object value, Class target) { return doConvert(value, target, null); } @SuppressWarnings("ConstantConditions") - private T doConvert(Object value, Class target, + private @Nullable T doConvert(Object value, Class target, @Nullable Class fallback) { if (conversionService.canConvert(value.getClass(), target) || fallback == null) { @@ -1940,7 +1953,7 @@ static class MongoDbPropertyValueProvider implements PropertyValueProvider @Nullable T getPropertyValue(MongoPersistentProperty property) { String expression = property.getSpelExpression(); @@ -2109,7 +2122,7 @@ enum NoOpParameterValueProvider implements ParameterValueProvider T getParameterValue(Parameter parameter) { + public @Nullable T getParameterValue(Parameter parameter) { return null; } } @@ -2137,7 +2150,7 @@ public List> getParameterTypes( } @Override - public org.springframework.data.util.TypeInformation getProperty(String property) { + public org.springframework.data.util.@Nullable TypeInformation getProperty(String property) { return delegate.getProperty(property); } @@ -2172,7 +2185,7 @@ public TypeInformation getRawTypeInformation() { } @Override - public org.springframework.data.util.TypeInformation getActualType() { + public org.springframework.data.util.@Nullable TypeInformation getActualType() { return delegate.getActualType(); } @@ -2187,7 +2200,7 @@ public List> getParameterTypes( } @Override - public org.springframework.data.util.TypeInformation getSuperTypeInformation(Class superType) { + public org.springframework.data.util.@Nullable TypeInformation getSuperTypeInformation(Class superType) { return delegate.getSuperTypeInformation(superType); } @@ -2313,7 +2326,7 @@ public ConversionContext withPath(ObjectPath currentPath) { } @Override - public S findContextualEntity(MongoPersistentEntity entity, Document document) { + public @Nullable S findContextualEntity(MongoPersistentEntity entity, Document document) { Object identifier = document.get(BasicMongoPersistentProperty.ID_FIELD_NAME); @@ -2356,7 +2369,7 @@ protected static class DefaultConversionContext implements ConversionContext { DefaultConversionContext(MongoConverter sourceConverter, org.springframework.data.convert.CustomConversions customConversions, ObjectPath path, - ContainerValueConverter<@Nullable Bson> documentConverter, ContainerValueConverter> collectionConverter, + ContainerValueConverter<@Nullable Bson> documentConverter, ContainerValueConverter<@Nullable Collection> collectionConverter, ContainerValueConverter<@Nullable Bson> mapConverter, ContainerValueConverter<@Nullable DBRef> dbRefConverter, ValueConverter<@Nullable Object> elementConverter) { @@ -2370,8 +2383,8 @@ protected static class DefaultConversionContext implements ConversionContext { this.elementConverter = elementConverter; } - @SuppressWarnings("unchecked") @Override + @SuppressWarnings({"unchecked", "NullAway"}) public S convert(Object source, TypeInformation typeHint, ConversionContext context) { @@ -2452,7 +2465,7 @@ public ObjectPath getPath() { */ interface ValueConverter { - Object convert(T source, TypeInformation typeHint); + @Nullable Object convert(@Nullable T source, TypeInformation typeHint); } @@ -2479,7 +2492,7 @@ class ProjectingConversionContext extends DefaultConversionContext { ProjectingConversionContext(MongoConverter sourceConverter, CustomConversions customConversions, ObjectPath path, ContainerValueConverter> collectionConverter, ContainerValueConverter mapConverter, - ContainerValueConverter<@Nullable DBRef> dbRefConverter, ValueConverter elementConverter, + ContainerValueConverter<@Nullable DBRef> dbRefConverter, ValueConverter<@Nullable Object> elementConverter, EntityProjection projection) { super(sourceConverter, customConversions, path, (context, source, typeHint) -> doReadOrProject(context, source, typeHint, projection), @@ -2531,7 +2544,7 @@ public void setProperty(PersistentProperty property, @Nullable Object value) } @Override - public Object getProperty(PersistentProperty property) { + public @Nullable Object getProperty(PersistentProperty property) { return delegate.getProperty(translate(property)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverter.java index 658ea5cfdb..e147d64cc5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverter.java @@ -101,7 +101,7 @@ public interface MongoConverter * @throws IllegalArgumentException if {@literal targetType} is {@literal null}. * @since 2.1 */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked","NullAway"}) default @Nullable T mapValueToTargetType(S source, Class targetType, DbRefResolver dbRefResolver) { Assert.notNull(targetType, "TargetType must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java index f9a67d73a0..1fd45e1960 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java @@ -47,6 +47,7 @@ import org.bson.types.Code; import org.bson.types.Decimal128; import org.bson.types.ObjectId; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.TypeDescriptor; @@ -142,7 +143,7 @@ public String convert(ObjectId id) { enum StringToObjectIdConverter implements Converter { INSTANCE; - public ObjectId convert(String source) { + public @Nullable ObjectId convert(String source) { return StringUtils.hasText(source) ? new ObjectId(source) : null; } } @@ -206,7 +207,7 @@ public Decimal128 convert(BigInteger source) { enum StringToBigDecimalConverter implements Converter { INSTANCE; - public BigDecimal convert(String source) { + public @Nullable BigDecimal convert(String source) { return StringUtils.hasText(source) ? new BigDecimal(source) : null; } } @@ -235,7 +236,7 @@ public String convert(BigInteger source) { enum StringToBigIntegerConverter implements Converter { INSTANCE; - public BigInteger convert(String source) { + public @Nullable BigInteger convert(String source) { return StringUtils.hasText(source) ? new BigInteger(source) : null; } } @@ -312,20 +313,25 @@ public String convert(Term source) { * @author Christoph Strobl * @since 1.7 */ + @SuppressWarnings("NullAway") enum DocumentToNamedMongoScriptConverter implements Converter { INSTANCE; @Override - public NamedMongoScript convert(Document source) { + public @Nullable NamedMongoScript convert(Document source) { if (source.isEmpty()) { return null; } String id = source.get(FieldName.ID.name()).toString(); + Assert.notNull(id, "Script id must not be null"); + Object rawValue = source.get("value"); + Assert.isInstanceOf(Code.class, rawValue); + return new NamedMongoScript(id, ((Code) rawValue).getCode()); } } @@ -379,7 +385,7 @@ enum StringToCurrencyConverter implements Converter { INSTANCE; @Override - public Currency convert(String source) { + public @Nullable Currency convert(String source) { return StringUtils.hasText(source) ? Currency.getInstance(source) : 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 12aaf24cd9..8aeb576c67 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 @@ -58,7 +58,7 @@ public interface MongoWriter extends EntityWriter { @Nullable Object convertToMongoType(@Nullable Object obj, @Nullable TypeInformation typeInformation); - default Object convertToMongoType(@Nullable Object obj, MongoPersistentEntity entity) { + default @Nullable Object convertToMongoType(@Nullable Object obj, MongoPersistentEntity entity) { return convertToMongoType(obj, entity.getTypeInformation()); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java index 976bd988c4..07ddf93d48 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java @@ -53,7 +53,12 @@ public MongoPersistentProperty getProperty() { @Override public EvaluationContext getEvaluationContext(@Nullable Object source) { - return conversionContext.getSpELContext().getEvaluationContext(source); + + if(conversionContext.getSpELContext() != null) { + return conversionContext.getSpELContext().getEvaluationContext(source); + } + + throw new IllegalStateException("SpEL context not present"); } @Override diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java index f169fe96c3..9e4991dfb1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java @@ -67,7 +67,7 @@ public MongoEncryptionConverter(Encryption encryption, En } @Override - public Object decrypt(Object encryptedValue, EncryptionContext context) { + public @Nullable Object decrypt(Object encryptedValue, EncryptionContext context) { Object decryptedValue = encryptedValue; if (encryptedValue instanceof Binary || encryptedValue instanceof BsonBinary) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java index 87fbb7a9a5..a2a2083255 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java @@ -52,7 +52,7 @@ public interface EncryptionContext { * @return can be {@literal null}. * @throws IllegalStateException if value cannot be read as an instance of {@link Class type}. */ - default T read(@Nullable Object value) { + default @Nullable T read(@Nullable Object value) { return (T) read(value, getProperty().getTypeInformation()); } @@ -64,7 +64,7 @@ default T read(@Nullable Object value) { * @return can be {@literal null}. * @throws IllegalStateException if value cannot be read as an instance of {@link Class type}. */ - default T read(@Nullable Object value, Class target) { + default @Nullable T read(@Nullable Object value, Class target) { return read(value, TypeInformation.of(target)); } @@ -76,7 +76,7 @@ default T read(@Nullable Object value, Class target) { * @return can be {@literal null}. * @throws IllegalStateException if value cannot be read as an instance of {@link Class type}. */ - T read(@Nullable Object value, TypeInformation target); + @Nullable T read(@Nullable Object value, TypeInformation target); /** * Write the value as an instance of the {@link PersistentProperty#getTypeInformation() property type}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentEntity.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentEntity.java index 7060ed2e8c..5c404a9d12 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentEntity.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentEntity.java @@ -32,6 +32,7 @@ import org.springframework.data.spel.EvaluationContextProvider; import org.springframework.data.util.Streamable; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Contract; /** * Unwrapped variant of {@link MongoPersistentEntity}. @@ -282,7 +283,9 @@ public Spliterator spliterator() { return delegate.spliterator(); } - private MongoPersistentProperty wrap(MongoPersistentProperty source) { + @Contract("null -> null; !null -> !null") + private @Nullable MongoPersistentProperty wrap(@Nullable MongoPersistentProperty source) { + if (source == null) { return source; } @@ -325,7 +328,7 @@ public boolean isUnwrapped() { } @Override - public Collection getEncryptionKeyIds() { + public @Nullable Collection getEncryptionKeyIds() { return delegate.getEncryptionKeyIds(); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java index 87eb0d1cf9..662960284d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java @@ -214,7 +214,7 @@ private void emitMessage(Message message) { private @Nullable T getNext() { return lock.execute(() -> { - if (State.RUNNING.equals(state)) { + if (cursor != null && State.RUNNING.equals(state)) { return cursor.tryNext(); } throw new IllegalStateException(String.format("Cursor %s is not longer open", cursor)); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/LazyMappingDelegatingMessage.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/LazyMappingDelegatingMessage.java index 1c934e8302..f9a9c4131d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/LazyMappingDelegatingMessage.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/LazyMappingDelegatingMessage.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core.messaging; import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.util.ClassUtils; @@ -38,12 +39,12 @@ class LazyMappingDelegatingMessage implements Message { } @Override - public S getRaw() { + public @Nullable S getRaw() { return delegate.getRaw(); } @Override - public T getBody() { + public @Nullable T getBody() { if (delegate.getBody() == null || targetType.equals(delegate.getBody().getClass())) { return targetType.cast(delegate.getBody()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SimpleMessage.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SimpleMessage.java index 730e0d95bb..acb7bfd8a2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SimpleMessage.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/SimpleMessage.java @@ -46,12 +46,12 @@ class SimpleMessage implements Message { } @Override - public S getRaw() { + public @Nullable S getRaw() { return raw; } @Override - public T getBody() { + public @Nullable T getBody() { return body; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java index 06f63c09a7..3fffcad894 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java @@ -121,6 +121,7 @@ public static class TailableCursorRequestOptions implements SubscriptionRequest. TailableCursorRequestOptions() {} + @SuppressWarnings("NullAway") public static TailableCursorRequestOptions of(RequestOptions options) { return builder().collection(options.getCollectionName()).build(); } 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 9926404e5e..b7d3455677 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 @@ -91,6 +91,7 @@ public BasicQuery(Document queryObject, Document fieldsObject) { * @param query the query to copy. * @since 4.4 */ + @SuppressWarnings("NullAway") public BasicQuery(Query query) { super(query); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MetricConversion.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MetricConversion.java index 571bbd275c..5625de5e93 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MetricConversion.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MetricConversion.java @@ -20,9 +20,11 @@ import java.math.MathContext; import java.math.RoundingMode; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Distance; import org.springframework.data.geo.Metric; import org.springframework.data.geo.Metrics; +import org.springframework.util.Assert; /** * {@link Metric} and {@link Distance} conversions using the metric system. @@ -151,8 +153,8 @@ static ConversionMultiplierBuilder builder() { */ private static class ConversionMultiplierBuilder { - private Number from; - private Number to; + private @Nullable Number from; + private @Nullable Number to; ConversionMultiplierBuilder() {} @@ -177,6 +179,9 @@ ConversionMultiplierBuilder to(Metric to) { } ConversionMultiplier build() { + + Assert.notNull(from, "[From] must be set first"); + Assert.notNull(to, "[To] must be set first"); return new ConversionMultiplier(this.from, this.to); } } 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 ba16c3c6d8..660abb9f65 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 @@ -20,6 +20,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -71,7 +72,8 @@ public static TextCriteria forDefaultLanguage() { * @param language * @return */ - public static TextCriteria forLanguage(String language) { + @Contract("null -> fail") + public static TextCriteria forLanguage(@Nullable String language) { Assert.hasText(language, "Language must not be null or empty"); return new TextCriteria(language); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java index f6e4071eaf..7931485cbb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java @@ -212,7 +212,7 @@ interface Path { /** * @return the name of the currently processed element */ - String currentElement(); + @Nullable String currentElement(); /** * @return the path leading to the currently processed element in dot {@literal '.'} notation. @@ -285,11 +285,11 @@ static Resolution ofValue(Path path, Object value) { * @param value the value to apply. * @return */ - static Resolution ofValue(String key, Object value) { + static Resolution ofValue(@Nullable String key, Object value) { return new Resolution() { @Override - public String getKey() { + public @Nullable String getKey() { return key; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypeUnifyingMergeFunction.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypeUnifyingMergeFunction.java index 315bfd94d7..87bdd8c618 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypeUnifyingMergeFunction.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypeUnifyingMergeFunction.java @@ -154,7 +154,7 @@ public SimplePath append(String next) { } @Override - public String currentElement() { + public @Nullable String currentElement() { return CollectionUtils.lastElement(path); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java index e2819222d4..db6ce9833d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java @@ -105,6 +105,7 @@ public InputStream getInputStream() throws IOException, IllegalStateException { } @Override + @SuppressWarnings("NullAway") public long contentLength() throws IOException { verifyExists(); @@ -122,6 +123,7 @@ public boolean exists() { } @Override + @SuppressWarnings("NullAway") public long lastModified() throws IOException { verifyExists(); @@ -139,6 +141,7 @@ public String getDescription() { * @return never {@literal null}. * @throws IllegalStateException if the file does not {@link #exists()}. */ + @SuppressWarnings("NullAway") public Object getId() { Assert.state(exists(), () -> String.format("%s does not exist.", getDescription())); @@ -147,7 +150,8 @@ public Object getId() { } @Override - public Object getFileId() { + @SuppressWarnings("NullAway") + public @Nullable Object getFileId() { Assert.state(exists(), () -> String.format("%s does not exist.", getDescription())); return BsonUtils.toJavaType(getGridFSFile().getId()); @@ -169,6 +173,7 @@ public Object getFileId() { * provided via {@link GridFSFile}. * @throws IllegalStateException if the file does not {@link #exists()}. */ + @SuppressWarnings("NullAway") public String getContentType() { Assert.state(exists(), () -> String.format("%s does not exist.", getDescription())); 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 d688932f6d..722a57edc1 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 @@ -167,7 +167,7 @@ public void delete(Query query) { } @Override - public ClassLoader getClassLoader() { + public @Nullable ClassLoader getClassLoader() { return null; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java index 19afa37cdb..49085f8007 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java @@ -70,6 +70,7 @@ public String getFilename() { } @Override + @SuppressWarnings("NullAway") public InputStream getContent() { return dataStream.orElse(InputStream.nullInputStream()); } @@ -99,7 +100,7 @@ public static class GridFsUploadBuilder { private @Nullable Object id; private @Nullable Lazy dataStream; private @Nullable String filename; - private @Nullable Options options = Options.none(); + private Options options = Options.none(); private GridFsUploadBuilder() {} @@ -225,6 +226,11 @@ public GridFsUploadBuilder contentType(String contentType) { } public GridFsUpload build() { + + Assert.notNull(dataStream, "DataStream must be set first"); + Assert.notNull(filename, "Filename must be set first"); + Assert.notNull(options, "Options must be set first"); + return new GridFsUpload(id, dataStream, filename, options); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsResource.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsResource.java index 3efc6edcc8..e889ec7183 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsResource.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsResource.java @@ -115,7 +115,7 @@ public static ReactiveGridFsResource absent(String filename) { } @Override - public Object getFileId() { + public @Nullable Object getFileId() { return id instanceof BsonValue bsonValue ? BsonUtils.toJavaType(bsonValue) : id; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java index c1fe458219..f523677549 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java @@ -95,8 +95,8 @@ public static ReactiveGridFsUploadBuilder fromPublisher(Publisher { private @Nullable Object id; - private Publisher dataStream; - private String filename; + private @Nullable Publisher dataStream; + private @Nullable String filename; private Options options = Options.none(); private ReactiveGridFsUploadBuilder() {} @@ -206,6 +206,11 @@ public ReactiveGridFsUploadBuilder contentType(String contentType) { } public ReactiveGridFsUpload build() { + + Assert.notNull(dataStream, "DataStream must be set first"); + Assert.notNull(filename, "Filename must be set first"); + Assert.notNull(options, "Options must be set first"); + return new ReactiveGridFsUpload(id, dataStream, filename, options); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java index b823ce223b..132a51ba46 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java @@ -21,6 +21,7 @@ import org.springframework.data.mongodb.observability.MongoObservation.LowCardinalityCommandKeyNames; import org.springframework.data.mongodb.util.MongoCompatibilityAdapter; +import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import com.mongodb.ConnectionString; @@ -67,6 +68,10 @@ public KeyValues getLowCardinalityKeyValues(MongoHandlerContext context) { .and(LowCardinalityCommandKeyNames.MONGODB_COLLECTION.withValue(context.getCollectionName())); } + if(context.getCommandStartedEvent() == null) { + throw new IllegalStateException("not command started event present"); + } + ConnectionDescription connectionDescription = context.getCommandStartedEvent().getConnectionDescription(); if (connectionDescription != null) { @@ -111,6 +116,8 @@ public String getContextualName(MongoHandlerContext context) { String collectionName = context.getCollectionName(); CommandStartedEvent commandStartedEvent = context.getCommandStartedEvent(); + Assert.notNull(commandStartedEvent, "CommandStartedEvent must not be null"); + if (ObjectUtils.isEmpty(collectionName)) { return commandStartedEvent.getCommandName(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MapRequestContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MapRequestContext.java index 854e1481fc..6185c95db5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MapRequestContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MapRequestContext.java @@ -17,9 +17,11 @@ import java.util.HashMap; import java.util.Map; +import java.util.NoSuchElementException; import java.util.stream.Stream; import com.mongodb.RequestContext; +import org.jspecify.annotations.Nullable; /** * A {@link Map}-based {@link RequestContext}. @@ -42,7 +44,13 @@ public MapRequestContext(Map context) { @Override public T get(Object key) { - return (T) map.get(key); + + + T value = (T) map.get(key); + if(value != null) { + return value; + } + throw new NoSuchElementException("%s is missing".formatted(key)); } @Override diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoHandlerContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoHandlerContext.java index b86e8ec70a..cab9cd5cb8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoHandlerContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoHandlerContext.java @@ -54,12 +54,12 @@ public class MongoHandlerContext extends SenderContext { "killCursors", "listIndexes", "reIndex")); private final @Nullable ConnectionString connectionString; - private final CommandStartedEvent commandStartedEvent; - private final RequestContext requestContext; - private final String collectionName; + private final @Nullable CommandStartedEvent commandStartedEvent; + private final @Nullable RequestContext requestContext; + private final @Nullable String collectionName; - private CommandSucceededEvent commandSucceededEvent; - private CommandFailedEvent commandFailedEvent; + private @Nullable CommandSucceededEvent commandSucceededEvent; + private @Nullable CommandFailedEvent commandFailedEvent; public MongoHandlerContext(@Nullable ConnectionString connectionString, CommandStartedEvent commandStartedEvent, RequestContext requestContext) { @@ -71,24 +71,24 @@ public MongoHandlerContext(@Nullable ConnectionString connectionString, CommandS this.collectionName = getCollectionName(commandStartedEvent); } - public CommandStartedEvent getCommandStartedEvent() { + public @Nullable CommandStartedEvent getCommandStartedEvent() { return this.commandStartedEvent; } - public RequestContext getRequestContext() { + public @Nullable RequestContext getRequestContext() { return this.requestContext; } public String getDatabaseName() { - return commandStartedEvent.getDatabaseName(); + return commandStartedEvent != null ? commandStartedEvent.getDatabaseName() : "n/a"; } - public String getCollectionName() { + public @Nullable String getCollectionName() { return this.collectionName; } public String getCommandName() { - return commandStartedEvent.getCommandName(); + return commandStartedEvent != null ? commandStartedEvent.getCommandName() : "n/a"; } public @Nullable ConnectionString getConnectionString() { 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 b52df43379..e160fd879a 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 @@ -105,7 +105,7 @@ public MongoQueryMethod getQueryMethod() { } @Override - public Object execute(Object[] parameters) { + public @Nullable Object execute(Object[] parameters) { ConvertingParameterAccessor accessor = new ConvertingParameterAccessor(operations.getConverter(), new MongoParametersParameterAccessor(method, parameters)); @@ -160,6 +160,7 @@ private Query applyAnnotatedReadPreferenceIfPresent(Query query) { return query.withReadPreference(com.mongodb.ReadPreference.valueOf(method.getAnnotatedReadPreference())); } + @SuppressWarnings("NullAway") private MongoQueryExecution getExecution(ConvertingParameterAccessor accessor, FindWithQuery operation) { if (isDeleteQuery()) { @@ -280,6 +281,7 @@ protected Query createCountQuery(ConvertingParameterAccessor accessor) { * @throws IllegalStateException if no update could be found. * @since 3.4 */ + @SuppressWarnings("NullAway") protected UpdateDefinition createUpdate(ConvertingParameterAccessor accessor) { if (accessor.getUpdate() != null) { @@ -373,6 +375,7 @@ protected ValueExpressionEvaluator getExpressionEvaluatorFor(MongoParameterAcces * @return the {@link CodecRegistry} used. * @since 2.4 */ + @SuppressWarnings("NullAway") protected CodecRegistry getCodecRegistry() { return operations.execute(MongoDatabase::getCodecRegistry); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java index f5b1e2f7df..d363c93442 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractReactiveMongoQuery.java @@ -195,6 +195,7 @@ private ReactiveMongoQueryExecution getExecution(MongoParameterAccessor accessor return new ResultProcessingExecution(getExecutionToWrap(accessor, operation), resultProcessing); } + @SuppressWarnings("NullAway") private ReactiveMongoQueryExecution getExecutionToWrap(MongoParameterAccessor accessor, FindWithQuery operation) { if (isDeleteQuery()) { @@ -334,6 +335,7 @@ protected Mono createCountQuery(ConvertingParameterAccessor accessor) { * @throws IllegalStateException if no update could be found. * @since 3.4 */ + @SuppressWarnings("NullAway") protected Mono createUpdate(MongoParameterAccessor accessor) { if (accessor.getUpdate() != null) { @@ -425,7 +427,7 @@ ValueExpressionEvaluator getValueExpressionEvaluator(MongoParameterAccessor acce return new ValueExpressionEvaluator() { @Override - public T evaluate(String expressionString) { + public @Nullable T evaluate(String expressionString) { ValueExpression expression = valueExpressionDelegate.parse(expressionString); ValueEvaluationContext evaluationContext = valueEvaluationContextProvider .getEvaluationContext(accessor.getValues(), expression.getExpressionDependencies()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/CollationUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/CollationUtils.java index df99017896..108c6ee796 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/CollationUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/CollationUtils.java @@ -25,6 +25,7 @@ import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.util.json.ParameterBindingContext; import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec; +import org.springframework.util.Assert; import org.springframework.util.NumberUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -96,6 +97,7 @@ private CollationUtils() { ObjectUtils.nullSafeClassName(placeholderValue))); } + Assert.notNull(placeholderValue, "PlaceholderValue must not be null"); return Collation.parse(collationExpression.replace(placeholder, placeholderValue.toString())); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java index 0032ca3fb1..d075b67efe 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java @@ -74,7 +74,7 @@ public PotentiallyConvertingIterator iterator() { } @Override - public ScrollPosition getScrollPosition() { + public @Nullable ScrollPosition getScrollPosition() { return delegate.getScrollPosition(); } @@ -87,34 +87,34 @@ public Sort getSort() { } @Override - public Class findDynamicProjection() { + public @Nullable Class findDynamicProjection() { return delegate.findDynamicProjection(); } - public Object getBindableValue(int index) { + public @Nullable Object getBindableValue(int index) { return getConvertedValue(delegate.getBindableValue(index), null); } @Override - public Range getDistanceRange() { + public @Nullable Range getDistanceRange() { return delegate.getDistanceRange(); } - public Point getGeoNearLocation() { + public @Nullable Point getGeoNearLocation() { return delegate.getGeoNearLocation(); } - public TextCriteria getFullText() { + public @Nullable TextCriteria getFullText() { return delegate.getFullText(); } @Override - public Collation getCollation() { + public @Nullable Collation getCollation() { return delegate.getCollation(); } @Override - public UpdateDefinition getUpdate() { + public @Nullable UpdateDefinition getUpdate() { return delegate.getUpdate(); } @@ -130,7 +130,7 @@ public Limit getLimit() { * @param typeInformation can be {@literal null}. * @return can be {@literal null}. */ - private @Nullable Object getConvertedValue(Object value, @Nullable TypeInformation typeInformation) { + private @Nullable Object getConvertedValue(@Nullable Object value, @Nullable TypeInformation typeInformation) { return writer.convertToMongoType(value, typeInformation == null ? null : typeInformation.getActualType()); } @@ -160,11 +160,11 @@ public boolean hasNext() { return delegate.hasNext(); } - public Object next() { + public @Nullable Object next() { return delegate.next(); } - public Object nextConverted(MongoPersistentProperty property) { + public @Nullable Object nextConverted(MongoPersistentProperty property) { Object next = next(); @@ -227,7 +227,7 @@ private static Collection asCollection(@Nullable Object source) { } @Override - public Object[] getValues() { + public Object @Nullable[] getValues() { return delegate.getValues(); } @@ -243,6 +243,6 @@ public interface PotentiallyConvertingIterator extends Iterator { * * @return */ - Object nextConverted(MongoPersistentProperty property); + @Nullable Object nextConverted(MongoPersistentProperty property); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameterAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameterAccessor.java index d9cacdbb14..00d748f8a9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameterAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameterAccessor.java @@ -41,7 +41,7 @@ public interface MongoParameterAccessor extends ParameterAccessor { * @return the maximum distance to apply to the geo query or {@literal null} if there's no {@link Distance} parameter * at all or the given value for it was {@literal null}. */ - Range getDistanceRange(); + @Nullable Range getDistanceRange(); /** * Returns the {@link Point} to use for a geo-near query. @@ -75,7 +75,7 @@ public interface MongoParameterAccessor extends ParameterAccessor { * @return * @since 1.8 */ - Object[] getValues(); + Object @Nullable[] getValues(); /** * Returns the {@link Update} to be used for an update execution. 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 1ed39c9851..3453e05617 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 @@ -46,9 +46,9 @@ public class MongoParameters extends Parameters private final int rangeIndex; private final int maxDistanceIndex; - private final @Nullable Integer fullTextIndex; - private final @Nullable Integer nearIndex; - private final @Nullable Integer collationIndex; + private final int fullTextIndex; + private final int nearIndex; + private final int collationIndex; private final int updateIndex; private final TypeInformation domainType; @@ -89,9 +89,8 @@ private MongoParameters(ParametersSource parametersSource, NearIndex nearIndex) this.nearIndex = nearIndex.nearIndex; } - private MongoParameters(List parameters, int maxDistanceIndex, @Nullable Integer nearIndex, - @Nullable Integer fullTextIndex, int rangeIndex, @Nullable Integer collationIndex, int updateIndex, - TypeInformation domainType) { + private MongoParameters(List parameters, int maxDistanceIndex, int nearIndex, int fullTextIndex, + int rangeIndex, int collationIndex, int updateIndex, TypeInformation domainType) { super(parameters); @@ -106,7 +105,7 @@ private MongoParameters(List parameters, int maxDistanceIndex, @ static class NearIndex { - private final @Nullable Integer nearIndex; + private final int nearIndex; public NearIndex(ParametersSource parametersSource, boolean isGeoNearMethod) { @@ -191,7 +190,7 @@ public int getNearIndex() { * @since 1.6 */ public int getFullTextParameterIndex() { - return fullTextIndex != null ? fullTextIndex : -1; + return fullTextIndex; } /** @@ -199,7 +198,7 @@ public int getFullTextParameterIndex() { * @since 1.6 */ public boolean hasFullTextParameter() { - return this.fullTextIndex != null && this.fullTextIndex >= 0; + return this.fullTextIndex >= 0; } /** @@ -217,7 +216,7 @@ public int getRangeIndex() { * @since 2.2 */ public int getCollationParameterIndex() { - return collationIndex != null ? collationIndex : -1; + return collationIndex; } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java index 121dccee65..66529dfce9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java @@ -25,6 +25,7 @@ import org.springframework.data.mongodb.core.query.TextCriteria; import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.data.repository.query.ParametersParameterAccessor; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -53,7 +54,8 @@ public MongoParametersParameterAccessor(MongoQueryMethod method, Object[] values this.method = method; } - public Range getDistanceRange() { + @SuppressWarnings("NullAway") + public @Nullable Range getDistanceRange() { MongoParameters mongoParameters = method.getParameters(); @@ -70,7 +72,7 @@ public Range getDistanceRange() { return Range.of(Bound.unbounded(), maxDistance); } - public Point getGeoNearLocation() { + public @Nullable Point getGeoNearLocation() { int nearIndex = method.getParameters().getNearIndex(); @@ -101,7 +103,8 @@ public Point getGeoNearLocation() { return index >= 0 ? potentiallyConvertFullText(getValue(index)) : null; } - protected TextCriteria potentiallyConvertFullText(Object fullText) { + @Contract("null -> fail") + protected TextCriteria potentiallyConvertFullText(@Nullable Object fullText) { Assert.notNull(fullText, "Fulltext parameter must not be 'null'."); @@ -123,7 +126,7 @@ protected TextCriteria potentiallyConvertFullText(Object fullText) { } @Override - public Collation getCollation() { + public @Nullable Collation getCollation() { if (method.getParameters().getCollationParameterIndex() == -1) { return null; @@ -133,12 +136,12 @@ public Collation getCollation() { } @Override - public @Nullable Object @Nullable[] getValues() { + public Object @Nullable[] getValues() { return super.getValues(); } @Override - public UpdateDefinition getUpdate() { + public @Nullable UpdateDefinition getUpdate() { int updateIndex = method.getParameters().getUpdateIndex(); return updateIndex == -1 ? null : (UpdateDefinition) getValue(updateIndex); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java index d616f783ee..7e327f4e20 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java @@ -111,7 +111,7 @@ public MongoQueryCreator(PartTree tree, ConvertingParameterAccessor accessor, protected Criteria create(Part part, Iterator iterator) { if (isGeoNearQuery && part.getType().equals(Type.NEAR)) { - return null; + return new Criteria(); } PersistentPropertyPath path = context.getPersistentPropertyPath(part.getProperty()); @@ -141,7 +141,7 @@ protected Criteria or(Criteria base, Criteria criteria) { } @Override - protected Query complete(Criteria criteria, Sort sort) { + protected Query complete(@Nullable Criteria criteria, Sort sort) { Query query = (criteria == null ? new Query() : new Query(criteria)).with(sort); @@ -161,6 +161,7 @@ protected Query complete(Criteria criteria, Sort sort) { * @param parameters * @return */ + @SuppressWarnings("NullAway") private Criteria from(Part part, MongoPersistentProperty property, Criteria criteria, Iterator parameters) { Type type = part.getType(); @@ -333,6 +334,7 @@ private Criteria createContainingCriteria(Part part, MongoPersistentProperty pro * @param value * @return the criteria extended with the regex. */ + @SuppressWarnings("NullAway") private Criteria addAppropriateLikeRegexTo(Criteria criteria, Part part, Object value) { if (value == null) { @@ -413,10 +415,11 @@ private Streamable asStreamable(Object value) { return Streamable.of(value); } - private String toLikeRegex(String source, Part part) { + private @Nullable String toLikeRegex(String source, Part part) { return MongoRegexCreator.INSTANCE.toRegularExpression(source, toMatchMode(part.getType())); } + @SuppressWarnings("NullAway") private boolean isSpherical(MongoPersistentProperty property) { if (property.isAnnotationPresent(GeoSpatialIndexed.class)) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java index 0e57eaada9..abdcf62930 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java @@ -171,10 +171,12 @@ public Object execute(Query query) { return isListOfGeoResult(method.getReturnType()) ? results.getContent() : results; } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked","NullAway"}) GeoResults doExecuteQuery(Query query) { Point nearLocation = accessor.getGeoNearLocation(); + Assert.notNull(nearLocation, "[query.location] must not be null"); + NearQuery nearQuery = NearQuery.near(nearLocation); if (query != null) { @@ -182,6 +184,8 @@ GeoResults doExecuteQuery(Query query) { } Range distances = accessor.getDistanceRange(); + Assert.notNull(nearLocation, "[query.distance] must not be null"); + distances.getLowerBound().getValue().ifPresent(it -> nearQuery.minDistance(it).in(it.getMetric())); distances.getUpperBound().getValue().ifPresent(it -> nearQuery.maxDistance(it).in(it.getMetric())); @@ -267,7 +271,7 @@ public DeleteExecution(MongoOperations operations, MongoQueryMethod method) { } @Override - public Object execute(Query query) { + public @Nullable Object execute(Query query) { String collectionName = method.getEntityInformation().getCollectionName(); Class type = method.getEntityInformation().getJavaType(); 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 8ed3446eec..fc4ea90f49 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 @@ -478,7 +478,7 @@ public boolean hasAnnotatedUpdate() { * @return the {@link Update} or {@literal null} if not present. * @since 3.4 */ - public Update getUpdateSource() { + public @Nullable Update getUpdateSource() { return lookupUpdateAnnotation().orElse(null); } @@ -488,6 +488,7 @@ public Update getUpdateSource() { * @since 3.4 * @throws IllegalStateException */ + @SuppressWarnings("NullAway") public void verify() { if (isModifyingQuery()) { @@ -526,6 +527,7 @@ public void verify() { } } + @SuppressWarnings("NullAway") private boolean isNumericOrVoidReturnValue() { Class resultType = getReturnedObjectType(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQuery.java index fdf08ba9d8..6116cc5534 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQuery.java @@ -78,6 +78,7 @@ public PartTree getTree() { } @Override + @SuppressWarnings("NullAway") protected Query createQuery(ConvertingParameterAccessor accessor) { MongoQueryCreator creator = new MongoQueryCreator(tree, accessor, context, isGeoNearQuery); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoParameterAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoParameterAccessor.java index 324f01d61f..9534a9cf4f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoParameterAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoParameterAccessor.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.repository.query; +import org.jspecify.annotations.Nullable; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -51,16 +52,21 @@ public ReactiveMongoParameterAccessor(MongoQueryMethod method, Object[] values) * @see org.springframework.data.mongodb.repository.query.MongoParametersParameterAccessor#getValues() */ @Override - public Object[] getValues() { + public Object @Nullable[] getValues() { - Object[] result = new Object[super.getValues().length]; + Object[] values = super.getValues(); + if(values == null) { + return new Object[0]; + } + + Object[] result = new Object[values.length]; for (int i = 0; i < result.length; i++) { result[i] = getValue(i); } return result; } - public Object getBindableValue(int index) { + public @Nullable Object getBindableValue(int index) { return getValue(getParameters().getBindableParameter(index).getIndex()); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java index dea3695775..06f946d745 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java @@ -86,6 +86,8 @@ public Publisher execute(Query query, Class type, String co private Flux> doExecuteQuery(@Nullable Query query, Class type, String collection) { Point nearLocation = accessor.getGeoNearLocation(); + Assert.notNull(nearLocation, "[query.location] ist not present"); + NearQuery nearQuery = NearQuery.near(nearLocation); if (query != null) { @@ -93,6 +95,8 @@ private Flux> doExecuteQuery(@Nullable Query query, Class t } Range distances = accessor.getDistanceRange(); + + Assert.notNull(distances, "[query.range] ist not present"); distances.getUpperBound().getValue().ifPresent(it -> nearQuery.maxDistance(it).in(it.getMetric())); distances.getLowerBound().getValue().ifPresent(it -> nearQuery.minDistance(it).in(it.getMetric())); @@ -195,6 +199,7 @@ public ResultProcessingExecution(ReactiveMongoQueryExecution delegate, Converter } @Override + @SuppressWarnings("NullAway") public Publisher execute(Query query, Class type, String collection) { return (Publisher) converter.convert(delegate.execute(query, type, collection)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactivePartTreeMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactivePartTreeMongoQuery.java index b27adfab93..4aa773091b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactivePartTreeMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactivePartTreeMongoQuery.java @@ -87,6 +87,7 @@ protected Mono createCountQuery(ConvertingParameterAccessor accessor) { return Mono.fromSupplier(() -> createQueryInternal(accessor, true)); } + @SuppressWarnings("NullAway") private Query createQueryInternal(ConvertingParameterAccessor accessor, boolean isCountQuery) { MongoQueryCreator creator = new MongoQueryCreator(tree, accessor, context, !isCountQuery && isGeoNearQuery); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java index cef642dd5e..4bfe2ca39f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveStringBasedMongoQuery.java @@ -15,6 +15,8 @@ */ package org.springframework.data.mongodb.repository.query; +import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import reactor.core.publisher.Mono; import org.apache.commons.logging.Log; @@ -45,7 +47,7 @@ public class ReactiveStringBasedMongoQuery extends AbstractReactiveMongoQuery { private static final Log LOG = LogFactory.getLog(ReactiveStringBasedMongoQuery.class); private final String query; - private final String fieldSpec; + private final @Nullable String fieldSpec; private final ValueExpressionParser expressionParser; @@ -62,6 +64,7 @@ public class ReactiveStringBasedMongoQuery extends AbstractReactiveMongoQuery { * @param delegate must not be {@literal null}. * @since 4.4.0 */ + @SuppressWarnings("NullAway") public ReactiveStringBasedMongoQuery(ReactiveMongoQueryMethod method, ReactiveMongoOperations mongoOperations, ValueExpressionDelegate delegate) { this(method.getAnnotatedQuery(), method, mongoOperations, delegate); @@ -77,7 +80,8 @@ public ReactiveStringBasedMongoQuery(ReactiveMongoQueryMethod method, ReactiveMo * @param delegate must not be {@literal null}. * @since 4.4.0 */ - public ReactiveStringBasedMongoQuery(@NonNull String query, ReactiveMongoQueryMethod method, + @SuppressWarnings("NullAway") + public ReactiveStringBasedMongoQuery(String query, ReactiveMongoQueryMethod method, ReactiveMongoOperations mongoOperations, ValueExpressionDelegate delegate) { super(method, mongoOperations, delegate); @@ -131,7 +135,7 @@ protected Mono createQuery(ConvertingParameterAccessor accessor) { }); } - private Mono getBindingContext(String json, ConvertingParameterAccessor accessor, + private Mono getBindingContext(@Nullable String json, ConvertingParameterAccessor accessor, ParameterBindingDocumentCodec codec) { ExpressionDependencies dependencies = codec.captureExpressionDependencies(json, accessor::getBindableValue, diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java index 5e2fba381b..c990d3269d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java @@ -55,6 +55,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { * @param expressionSupport must not be {@literal null}. * @since 4.4.0 */ + @SuppressWarnings("NullAway") public StringBasedMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations, ValueExpressionDelegate expressionSupport) { this(method.getAnnotatedQuery(), method, mongoOperations, expressionSupport); @@ -70,6 +71,7 @@ public StringBasedMongoQuery(MongoQueryMethod method, MongoOperations mongoOpera * @param expressionSupport must not be {@literal null}. * @since 4.3 */ + @SuppressWarnings("NullAway") public StringBasedMongoQuery(String query, MongoQueryMethod method, MongoOperations mongoOperations, ValueExpressionDelegate expressionSupport) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ValueExpressionDelegateValueExpressionEvaluator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ValueExpressionDelegateValueExpressionEvaluator.java index c479f3faa9..360f5e80eb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ValueExpressionDelegateValueExpressionEvaluator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ValueExpressionDelegateValueExpressionEvaluator.java @@ -17,6 +17,7 @@ import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.springframework.data.expression.ValueEvaluationContext; import org.springframework.data.expression.ValueExpression; import org.springframework.data.mapping.model.ValueExpressionEvaluator; @@ -34,7 +35,7 @@ class ValueExpressionDelegateValueExpressionEvaluator implements ValueExpression @SuppressWarnings("unchecked") @Override - public T evaluate(String expressionString) { + public @Nullable T evaluate(String expressionString) { ValueExpression expression = delegate.parse(expressionString); return (T) expression.evaluate(expressionToContext.apply(expression)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java index 5c50c79ea9..abd828a9f7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java @@ -54,7 +54,7 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B private @Nullable ClassLoader classLoader = ClassUtils.getDefaultClassLoader(); @Override - public void setBeanClassLoader(ClassLoader classLoader) { + public void setBeanClassLoader(@Nullable ClassLoader classLoader) { this.classLoader = classLoader; } @@ -121,7 +121,7 @@ static MethodInvocation currentInvocation() throws IllegalStateException { } @Override - public Object invoke(MethodInvocation invocation) throws Throwable { + public @Nullable Object invoke(MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); @@ -220,7 +220,7 @@ public boolean isStatic() { } @Override - public Object getTarget() { + public @Nullable Object getTarget() { MethodInvocation invocation = CrudMethodMetadataPopulatingMethodInterceptor.currentInvocation(); return TransactionSynchronizationManager.getResource(invocation.getMethod()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java index c6d42388ef..443108d2f0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java @@ -113,7 +113,7 @@ public boolean isVersioned() { } @Override - public Object getVersion(T entity) { + public @Nullable Object getVersion(T entity) { if (!isVersioned()) { return null; 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 ec75a5c27b..cec54de0bb 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 @@ -31,6 +31,7 @@ * * @author Oliver Gierke */ +@SuppressWarnings("NullAway") public class MongoRepositoryFactoryBean, S, ID extends Serializable> extends RepositoryFactoryBeanSupport { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QuerydslMongoPredicateExecutor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QuerydslMongoPredicateExecutor.java index ec845510ce..833ce69458 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QuerydslMongoPredicateExecutor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QuerydslMongoPredicateExecutor.java @@ -23,6 +23,7 @@ import org.bson.Document; +import org.jspecify.annotations.Nullable; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -245,12 +246,12 @@ protected FluentQuerydsl create(Predicate predicate, Sort sort, int limit } @Override - public T oneValue() { + public @Nullable T oneValue() { return createQuery().fetchOne(); } @Override - public T firstValue() { + public @Nullable T firstValue() { return createQuery().fetchFirst(); } 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 13fabb0c03..ae8561bc17 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 @@ -86,6 +86,7 @@ public void setBeanClassLoader(@Nullable ClassLoader classLoader) { } @Override + @SuppressWarnings("NullAway") protected ProjectionFactory getProjectionFactory(@Nullable ClassLoader classLoader, @Nullable BeanFactory beanFactory) { return this.operations.getConverter().getProjectionFactory(); } @@ -130,6 +131,7 @@ protected Object getTargetRepository(RepositoryInformation information) { } @Override + @SuppressWarnings("NullAway") protected Optional getQueryLookupStrategy(Key key, ValueExpressionDelegate valueExpressionDelegate) { return Optional.of(new MongoQueryLookupStrategy(operations, mappingContext, valueExpressionDelegate)); 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 341280436f..e3d71325f9 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 @@ -78,6 +78,7 @@ public void setMappingContext(MappingContext mappingContext) { } @Override + @SuppressWarnings("NullAway") protected RepositoryFactorySupport createRepositoryFactory() { RepositoryFactorySupport factory = getFactoryInstance(operations); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveSpringDataMongodbQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveSpringDataMongodbQuery.java index 2d9c7e29b3..a86ada0aad 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveSpringDataMongodbQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveSpringDataMongodbQuery.java @@ -304,7 +304,7 @@ static class NoMatchException extends RuntimeException { @Override public synchronized Throwable fillInStackTrace() { - return null; + return this; } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java index 2c469c777d..7e6e2fc82e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java @@ -427,12 +427,12 @@ protected FluentQueryByExample create(Example predicate, Sort sort, } @Override - public T oneValue() { + public @Nullable T oneValue() { return createQuery().oneValue(); } @Override - public T firstValue() { + public @Nullable T firstValue() { return createQuery().firstValue(); } 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 cf92c07c28..809dbab8cf 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 @@ -44,6 +44,7 @@ import com.querydsl.core.types.Expression; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Predicate; +import org.springframework.lang.Contract; /** * Spring Data specific simple {@link com.querydsl.core.Fetchable} {@link com.querydsl.core.SimpleQuery Query} @@ -183,7 +184,7 @@ public Page fetchPage(Pageable pageable) { } @Override - public T fetchFirst() { + public @Nullable T fetchFirst() { try { return find.matching(createQuery()).firstValue(); } catch (RuntimeException e) { @@ -192,7 +193,7 @@ public T fetchFirst() { } @Override - public T fetchOne() { + public @Nullable T fetchOne() { try { return find.matching(createQuery()).oneValue(); } catch (RuntimeException e) { @@ -262,7 +263,8 @@ protected List getIds(Class targetType, Predicate condition) { return mongoOperations.findDistinct(query, FieldName.ID.name(), targetType, Object.class); } - private static T handleException(RuntimeException e, T defaultValue) { + @Contract("_, !null -> !null") + private static @Nullable T handleException(RuntimeException e, @Nullable T defaultValue) { if (e.getClass().getName().endsWith("$NoResults")) { return defaultValue; 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 854fe2aa1a..756d04d0c2 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 @@ -20,6 +20,7 @@ import java.util.regex.Pattern; import org.bson.Document; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.convert.MongoConverter; @@ -48,6 +49,7 @@ * @author Christoph Strobl * @author Mark Paluch */ +@NullUnmarked class SpringDataMongodbSerializer extends MongodbDocumentSerializer { private static final String ID_KEY = FieldName.ID.name(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java index 276b46e086..83df5f7798 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java @@ -127,7 +127,7 @@ public static Map asMap(@Nullable Bson bson, CodecRegistry codec * @return * @since 3.2.5 */ - public static Document asDocument(Bson bson) { + public static Document asDocument(@Nullable Bson bson) { return asDocument(bson, MongoClientSettings.getDefaultCodecRegistry()); } @@ -141,7 +141,7 @@ public static Document asDocument(Bson bson) { * @return never {@literal null}. * @since 4.0 */ - public static Document asDocument(Bson bson, CodecRegistry codecRegistry) { + public static Document asDocument(@Nullable Bson bson, CodecRegistry codecRegistry) { Map map = asMap(bson, codecRegistry); @@ -404,7 +404,9 @@ public static BsonValue simpleToBsonValue(@Nullable Object source, CodecRegistry BsonCapturingWriter writer = new BsonCapturingWriter(value.getClass()); codec.encode(writer, value, ObjectUtils.isArray(value) || value instanceof Collection ? EncoderContext.builder().build() : null); - return writer.getCapturedValue(); + Object captured = writer.getCapturedValue(); + return captured instanceof BsonValue bv ? bv : BsonNull.VALUE; + } catch (CodecConfigurationException e) { throw new IllegalArgumentException( String.format("Unable to convert %s to BsonValue.", source != null ? source.getClass().getName() : "null")); @@ -547,7 +549,7 @@ public static Document parse(String json, @Nullable CodecRegistryProvider codecR * @return can be {@literal null}. * @since 4.2 */ - public static Object resolveValue(Bson bson, FieldName fieldName) { + public static @Nullable Object resolveValue(Bson bson, FieldName fieldName) { return resolveValue(asMap(bson), fieldName); } @@ -562,8 +564,7 @@ public static Object resolveValue(Bson bson, FieldName fieldName) { * @return can be {@literal null}. * @since 4.2 */ - @Nullable - public static Object resolveValue(Map source, FieldName fieldName) { + public static @Nullable Object resolveValue(Map source, FieldName fieldName) { if (fieldName.isKey()) { return source.get(fieldName.name()); @@ -648,9 +649,9 @@ public static boolean hasValue(Bson bson, String key) { * @param source can be {@literal null}. * @return can be {@literal null}. */ - @Nullable @SuppressWarnings("unchecked") - private static Map getAsMap(Object source) { + @Contract("null -> null") + private static @Nullable Map getAsMap(@Nullable Object source) { if (source instanceof Document document) { return document; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/DurationUtil.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/DurationUtil.java index 827c81aa0c..78eb59a461 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/DurationUtil.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/DurationUtil.java @@ -71,12 +71,12 @@ public static Duration evaluate(String value, Supplier evalua return evaluate(value, new ValueEvaluationContext() { @Override - public @Nullable Environment getEnvironment() { - return null; + public Environment getEnvironment() { + throw new IllegalStateException(); } @Override - public @Nullable EvaluationContext getEvaluationContext() { + public EvaluationContext getEvaluationContext() { return evaluationContext.get(); } }); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoCompatibilityAdapter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoCompatibilityAdapter.java index 641ccd274f..ba1e32356a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoCompatibilityAdapter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoCompatibilityAdapter.java @@ -44,6 +44,7 @@ * @author Christoph Strobl * @since 4.3 */ +@SuppressWarnings("NullAway") public class MongoCompatibilityAdapter { private static final String NO_LONGER_SUPPORTED = "%s is no longer supported on Mongo Client 5 or newer"; @@ -198,7 +199,7 @@ public interface MongoDatabaseAdapterBuilder { MongoDatabaseAdapter forDb(com.mongodb.client.MongoDatabase db); } - @SuppressWarnings({ "unchecked", "DataFlowIssue" }) + @SuppressWarnings({ "unchecked", "DataFlowIssue", "NullAway" }) public static class MongoDatabaseAdapter { private static final @Nullable Method LIST_COLLECTION_NAMES_METHOD; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoDbErrorCodes.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoDbErrorCodes.java index 9df6d098ac..7fcc1383d5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoDbErrorCodes.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoDbErrorCodes.java @@ -15,7 +15,9 @@ */ package org.springframework.data.mongodb.util; +import java.util.Collections; import java.util.HashMap; +import java.util.Map; import com.mongodb.MongoException; @@ -128,7 +130,9 @@ public final class MongoDbErrorCodes { clientSessionCodes.put(263, "OperationNotSupportedInTransaction"); clientSessionCodes.put(264, "TooManyLogicalSessions"); - errorCodes = new HashMap<>( + transactionCodes = new HashMap<>(0); + + errorCodes = new HashMap<>( dataAccessResourceFailureCodes.size() + dataIntegrityViolationCodes.size() + duplicateKeyCodes.size() + invalidDataAccessApiUsageException.size() + permissionDeniedCodes.size() + clientSessionCodes.size(), 1f); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/EvaluationContextExpressionEvaluator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/EvaluationContextExpressionEvaluator.java index ff0454cff7..57fecd284c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/EvaluationContextExpressionEvaluator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/EvaluationContextExpressionEvaluator.java @@ -54,7 +54,7 @@ Expression getParsedExpression(String expressionString) { } @SuppressWarnings("unchecked") - T evaluateExpression(String expressionString, Map variables) { + @Nullable T evaluateExpression(String expressionString, Map variables) { Expression expression = getParsedExpression(expressionString); EvaluationContext ctx = getEvaluationContext(expressionString); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StubParameterAccessor.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StubParameterAccessor.java index 30ed064e00..3ed7ace0f9 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StubParameterAccessor.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StubParameterAccessor.java @@ -121,7 +121,7 @@ public Collation getCollation() { * @see org.springframework.data.mongodb.repository.query.MongoParameterAccessor#getValues() */ @Override - public Object[] getValues() { + public Object @Nullable[] getValues() { return this.values; } From a71d0c2e4c27f3d152a8360ba0a38a37229400a4 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 18 Mar 2025 10:27:52 +0100 Subject: [PATCH 16/17] polish some stuff --- .../data/mongodb/BindableMongoExpression.java | 15 +- .../data/mongodb/BulkOperationException.java | 2 +- .../data/mongodb/MongoDatabaseUtils.java | 12 +- .../data/mongodb/MongoResourceHolder.java | 3 +- .../data/mongodb/MongoTransactionManager.java | 16 +- .../data/mongodb/MongoTransactionOptions.java | 2 +- .../mongodb/ReactiveMongoDatabaseUtils.java | 23 ++- .../mongodb/ReactiveMongoResourceHolder.java | 3 +- .../ReactiveMongoTransactionManager.java | 11 +- .../SessionAwareMethodInterceptor.java | 3 +- .../SimpleMongoTransactionOptions.java | 3 +- .../data/mongodb/aot/MongoRuntimeHints.java | 2 +- .../config/MongoConfigurationSupport.java | 7 +- .../config/ServerAddressPropertyEditor.java | 8 +- .../data/mongodb/core/ChangeStreamEvent.java | 12 +- .../mongodb/core/ChangeStreamOptions.java | 8 +- .../data/mongodb/core/CollectionOptions.java | 3 +- .../core/CollectionPreparerSupport.java | 3 +- .../data/mongodb/core/CountQuery.java | 9 +- .../mongodb/core/DefaultBulkOperations.java | 4 +- .../core/DefaultReactiveBulkOperations.java | 4 +- .../core/DefaultReactiveIndexOperations.java | 24 +-- .../mongodb/core/DefaultScriptOperations.java | 28 ++-- .../core/DefaultWriteConcernResolver.java | 3 +- .../data/mongodb/core/EntityOperations.java | 13 +- ...ExecutableAggregationOperationSupport.java | 2 +- .../core/ExecutableFindOperationSupport.java | 14 +- .../ExecutableInsertOperationSupport.java | 7 +- .../MongoEncryptionSettingsFactoryBean.java | 2 - .../data/mongodb/core/MongoTemplate.java | 137 +++++++++++------- .../core/ReactiveMongoClientFactoryBean.java | 2 +- .../mongodb/core/ReactiveMongoTemplate.java | 62 +++++--- 32 files changed, 242 insertions(+), 205 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java index 470964252c..d44da10431 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java @@ -31,8 +31,7 @@ * A {@link MongoExpression} using the {@link ParameterBindingDocumentCodec} for parsing a raw ({@literal json}) * expression. The expression will be wrapped within { ... } if necessary. The actual parsing and parameter * binding of placeholders like {@code ?0} is delayed upon first call on the target {@link Document} via - * {@link #toDocument()}. - *
+ * {@link #toDocument()}.
* *
  * $toUpper : $name                -> { '$toUpper' : '$name' }
@@ -55,7 +54,7 @@ public class BindableMongoExpression implements MongoExpression {
 
 	private final @Nullable CodecRegistryProvider codecRegistryProvider;
 
-	private final Object @Nullable[] args;
+	private final Object @Nullable [] args;
 
 	private final Lazy target;
 
@@ -63,9 +62,9 @@ public class BindableMongoExpression implements MongoExpression {
 	 * Create a new instance of {@link BindableMongoExpression}.
 	 *
 	 * @param expression must not be {@literal null}.
-	 * @param args can be {@literal null}.
+	 * @param args must not be {@literal null} but may contain {@literal null} elements.
 	 */
-	public BindableMongoExpression(String expression, Object @Nullable[] args) {
+	public BindableMongoExpression(String expression, Object @Nullable [] args) {
 		this(expression, null, args);
 	}
 
@@ -74,10 +73,10 @@ public BindableMongoExpression(String expression, Object @Nullable[] args) {
 	 *
 	 * @param expression must not be {@literal null}.
 	 * @param codecRegistryProvider can be {@literal null}.
-	 * @param args can be {@literal null}.
+	 * @param args must not be {@literal null} but may contain {@literal null} elements.
 	 */
 	public BindableMongoExpression(String expression, @Nullable CodecRegistryProvider codecRegistryProvider,
-			Object @Nullable[] args) {
+			Object @Nullable [] args) {
 
 		Assert.notNull(expression, "Expression must not be null");
 
@@ -139,7 +138,7 @@ private Document parse() {
 
 	private static String wrapJsonIfNecessary(String json) {
 
-		if(!StringUtils.hasText(json)) {
+		if (!StringUtils.hasText(json)) {
 			return json;
 		}
 
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java
index f6e36e4622..12d8c966af 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java
@@ -41,7 +41,7 @@ public class BulkOperationException extends DataAccessException {
 	/**
 	 * Creates a new {@link BulkOperationException} with the given message and source {@link MongoBulkWriteException}.
 	 *
-	 * @param message must not be {@literal null}.
+	 * @param message can be {@literal null}.
 	 * @param source must not be {@literal null}.
 	 */
 	public BulkOperationException(@Nullable String message, MongoBulkWriteException source) {
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java
index acc406de26..042a5ba1d3 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java
@@ -29,8 +29,7 @@
 /**
  * Helper class for managing a {@link MongoDatabase} instances via {@link MongoDatabaseFactory}. Used for obtaining
  * {@link ClientSession session bound} resources, such as {@link MongoDatabase} and
- * {@link com.mongodb.client.MongoCollection} suitable for transactional usage.
- * 
+ * {@link com.mongodb.client.MongoCollection} suitable for transactional usage.
* Note: Intended for internal usage only. * * @author Christoph Strobl @@ -42,8 +41,7 @@ public class MongoDatabaseUtils { /** * Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory} using - * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}. - *
+ * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current * {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}. * @@ -55,8 +53,7 @@ public static MongoDatabase getDatabase(MongoDatabaseFactory factory) { } /** - * Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory}. - *
+ * Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current * {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}. * @@ -70,8 +67,7 @@ public static MongoDatabase getDatabase(MongoDatabaseFactory factory, SessionSyn /** * Obtain the {@link MongoDatabase database} with given name form the given {@link MongoDatabaseFactory factory} using - * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}. - *
+ * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current * {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}. * diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java index 2998a0c9b1..81c25d0998 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java @@ -23,8 +23,7 @@ /** * MongoDB specific {@link ResourceHolderSupport resource holder}, wrapping a {@link ClientSession}. - * {@link MongoTransactionManager} binds instances of this class to the thread. - *
+ * {@link MongoTransactionManager} binds instances of this class to the thread.
* Note: Intended for internal usage only. * * @author Christoph Strobl diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java index 0c449635d9..1f97bb69e9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java @@ -36,19 +36,15 @@ /** * A {@link org.springframework.transaction.PlatformTransactionManager} implementation that manages - * {@link ClientSession} based transactions for a single {@link MongoDatabaseFactory}. - *
- * Binds a {@link ClientSession} from the specified {@link MongoDatabaseFactory} to the thread. - *
+ * {@link ClientSession} based transactions for a single {@link MongoDatabaseFactory}.
+ * Binds a {@link ClientSession} from the specified {@link MongoDatabaseFactory} to the thread.
* {@link TransactionDefinition#isReadOnly() Readonly} transactions operate on a {@link ClientSession} and enable causal * consistency, and also {@link ClientSession#startTransaction() start}, {@link ClientSession#commitTransaction() - * commit} or {@link ClientSession#abortTransaction() abort} a transaction. - *
+ * commit} or {@link ClientSession#abortTransaction() abort} a transaction.
* Application code is required to retrieve the {@link com.mongodb.client.MongoDatabase} via * {@link MongoDatabaseUtils#getDatabase(MongoDatabaseFactory)} instead of a standard * {@link MongoDatabaseFactory#getMongoDatabase()} call. Spring classes such as - * {@link org.springframework.data.mongodb.core.MongoTemplate} use this strategy implicitly. - *
+ * {@link org.springframework.data.mongodb.core.MongoTemplate} use this strategy implicitly.
* By default failure of a {@literal commit} operation raises a {@link TransactionSystemException}. One may override * {@link #doCommit(MongoTransactionObject)} to implement the * Retry Commit Operation @@ -153,7 +149,8 @@ protected void doBegin(Object transaction, TransactionDefinition definition) thr } try { - MongoTransactionOptions mongoTransactionOptions = transactionOptionsResolver.resolve(definition).mergeWith(options); + MongoTransactionOptions mongoTransactionOptions = transactionOptionsResolver.resolve(definition) + .mergeWith(options); mongoTransactionObject.startTransaction(mongoTransactionOptions.toDriverOptions()); } catch (MongoException ex) { throw new TransactionSystemException(String.format("Could not start Mongo transaction for session %s.", @@ -208,6 +205,7 @@ protected final void doCommit(DefaultTransactionStatus status) throws Transactio * By default those labels are ignored, nevertheless one might check for * {@link MongoException#UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL transient commit errors labels} and retry the the * commit.
+ * *
 	 * 
 	 * int retries = 3;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java
index 7bb1ac980c..0fcaa19002 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java
@@ -149,7 +149,7 @@ default  T map(Function mappingFunction) {
 	/**
 	 * Factory method to wrap given MongoDB driver native {@link TransactionOptions} into {@link MongoTransactionOptions}.
 	 *
-	 * @param options
+	 * @param options can be {@literal null}.
 	 * @return {@link MongoTransactionOptions#NONE} if given object is {@literal null}.
 	 */
 	static MongoTransactionOptions of(@Nullable TransactionOptions options) {
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java
index 7c291288f2..3d1c2ee89c 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java
@@ -16,10 +16,9 @@
 package org.springframework.data.mongodb;
 
 import reactor.core.publisher.Mono;
-
-import org.jspecify.annotations.Nullable;
 import reactor.util.context.Context;
 
+import org.jspecify.annotations.Nullable;
 import org.springframework.transaction.NoTransactionException;
 import org.springframework.transaction.reactive.ReactiveResourceSynchronization;
 import org.springframework.transaction.reactive.TransactionSynchronization;
@@ -36,8 +35,7 @@
 /**
  * Helper class for managing reactive {@link MongoDatabase} instances via {@link ReactiveMongoDatabaseFactory}. Used for
  * obtaining {@link ClientSession session bound} resources, such as {@link MongoDatabase} and {@link MongoCollection}
- * suitable for transactional usage.
- * 
+ * suitable for transactional usage.
* Note: Intended for internal usage only. * * @author Mark Paluch @@ -75,8 +73,7 @@ public static Mono isTransactionActive(ReactiveMongoDatabaseFactory dat /** * Obtain the default {@link MongoDatabase database} form the given {@link ReactiveMongoDatabaseFactory factory} using - * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}. - *
+ * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber * {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}. * @@ -104,12 +101,12 @@ public static Mono getDatabase(ReactiveMongoDatabaseFactory facto /** * Obtain the {@link MongoDatabase database} with given name form the given {@link ReactiveMongoDatabaseFactory - * factory} using {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}. - *
+ * factory} using {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber * {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}. * - * @param dbName the name of the {@link MongoDatabase} to get. + * @param dbName the name of the {@link MongoDatabase} to get. If {@literal null} the default database of the + * {@link ReactiveMongoDatabaseFactory}. * @param factory the {@link ReactiveMongoDatabaseFactory} to get the {@link MongoDatabase} from. * @return the {@link MongoDatabase} that is potentially associated with a transactional {@link ClientSession}. */ @@ -119,17 +116,17 @@ public static Mono getDatabase(@Nullable String dbName, ReactiveM /** * Obtain the {@link MongoDatabase database} with given name form the given {@link ReactiveMongoDatabaseFactory - * factory}. - *
+ * factory}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber * {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}. * - * @param dbName the name of the {@link MongoDatabase} to get. + * @param dbName the name of the {@link MongoDatabase} to get. If {@literal null} the default database of the * + * {@link ReactiveMongoDatabaseFactory}. * @param factory the {@link ReactiveMongoDatabaseFactory} to get the {@link MongoDatabase} from. * @param sessionSynchronization the synchronization to use. Must not be {@literal null}. * @return the {@link MongoDatabase} that is potentially associated with a transactional {@link ClientSession}. */ - public static Mono getDatabase(String dbName, ReactiveMongoDatabaseFactory factory, + public static Mono getDatabase(@Nullable String dbName, ReactiveMongoDatabaseFactory factory, SessionSynchronization sessionSynchronization) { return doGetMongoDatabase(dbName, factory, sessionSynchronization); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java index 6705ffe526..d01364b202 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java @@ -23,8 +23,7 @@ /** * MongoDB specific resource holder, wrapping a {@link ClientSession}. {@link ReactiveMongoTransactionManager} binds - * instances of this class to the subscriber context. - *
+ * instances of this class to the subscriber context.
* Note: Intended for internal usage only. * * @author Mark Paluch diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java index 5ae44955a0..4f293c8ed6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java @@ -64,7 +64,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransactionManager implements InitializingBean { private @Nullable ReactiveMongoDatabaseFactory databaseFactory; - private @Nullable MongoTransactionOptions options; + private MongoTransactionOptions options; private final MongoTransactionOptionsResolver transactionOptionsResolver; /** @@ -79,7 +79,9 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction * @see #setDatabaseFactory(ReactiveMongoDatabaseFactory) */ public ReactiveMongoTransactionManager() { + this.transactionOptionsResolver = MongoTransactionOptionsResolver.defaultResolver(); + this.options = MongoTransactionOptions.NONE; } /** @@ -98,7 +100,7 @@ public ReactiveMongoTransactionManager(ReactiveMongoDatabaseFactory databaseFact * starting a new transaction. * * @param databaseFactory must not be {@literal null}. - * @param options can be {@literal null}. + * @param options can be {@literal null}. Will default {@link MongoTransactionOptions#NONE} if {@literal null}. */ public ReactiveMongoTransactionManager(ReactiveMongoDatabaseFactory databaseFactory, @Nullable TransactionOptions options) { @@ -112,7 +114,8 @@ public ReactiveMongoTransactionManager(ReactiveMongoDatabaseFactory databaseFact * * @param databaseFactory must not be {@literal null}. * @param transactionOptionsResolver must not be {@literal null}. - * @param defaultTransactionOptions can be {@literal null}. + * @param defaultTransactionOptions can be {@literal null}. Will default {@link MongoTransactionOptions#NONE} if + * {@literal null}. * @since 4.3 */ public ReactiveMongoTransactionManager(ReactiveMongoDatabaseFactory databaseFactory, @@ -124,7 +127,7 @@ public ReactiveMongoTransactionManager(ReactiveMongoDatabaseFactory databaseFact this.databaseFactory = databaseFactory; this.transactionOptionsResolver = transactionOptionsResolver; - this.options = defaultTransactionOptions; + this.options = defaultTransactionOptions != null ? defaultTransactionOptions : MongoTransactionOptions.NONE; } @Override diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java index beff621bcb..ec30478a54 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java @@ -34,8 +34,7 @@ /** * {@link MethodInterceptor} implementation looking up and invoking an alternative target method having - * {@link ClientSession} as its first argument. This allows seamless integration with the existing code base. - *
+ * {@link ClientSession} as its first argument. This allows seamless integration with the existing code base.
* The {@link MethodInterceptor} is aware of methods on {@code MongoCollection} that my return new instances of itself * like (eg. {@link com.mongodb.reactivestreams.client.MongoCollection#withWriteConcern(WriteConcern)} and decorate them * if not already proxied. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java index 321125458f..5c50ba686a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java @@ -115,7 +115,8 @@ public String toString() { }); } - private static @Nullable T getValue(Map options, OptionKey key, Function convertFunction) { + private static @Nullable T getValue(Map options, OptionKey key, + Function convertFunction) { String value = options.get(key.getKey()); return value != null ? convertFunction.apply(value) : null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java index 453418ffd6..f2442960ed 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.aot; -import static org.springframework.data.mongodb.aot.MongoAotPredicates.*; +import static org.springframework.data.mongodb.aot.MongoAotPredicates.isReactorPresent; import java.util.Arrays; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java index 1d1903ee10..b01827d8c6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java @@ -53,7 +53,7 @@ public abstract class MongoConfigurationSupport { /** * Return the name of the database to connect to. * - * @return must not be {@literal null}. + * @return never {@literal null}. */ protected abstract String getDatabaseName(); @@ -77,7 +77,7 @@ protected Collection getMappingBasePackages() { * Creates a {@link MongoMappingContext} equipped with entity classes scanned from the mapping base package. * * @see #getMappingBasePackages() - * @return + * @return never {@literal null}. */ @Bean public MongoMappingContext mongoMappingContext(MongoCustomConversions customConversions, @@ -176,8 +176,7 @@ protected Set> scanForEntities(String basePackage) throws ClassNotFound String beanClassName = candidate.getBeanClassName(); Assert.notNull(beanClassName, "BeanClassName cannot be null"); - initialEntitySet - .add(ClassUtils.forName(beanClassName, MongoConfigurationSupport.class.getClassLoader())); + initialEntitySet.add(ClassUtils.forName(beanClassName, MongoConfigurationSupport.class.getClassLoader())); } } 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 a09a5e2486..9ff59e5b22 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 @@ -83,7 +83,7 @@ public void setAsText(@Nullable String replicaSetString) { private @Nullable ServerAddress parseServerAddress(String source) { if (!StringUtils.hasText(source)) { - if(LOG.isWarnEnabled()) { + if (LOG.isWarnEnabled()) { LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "source", source)); } return null; @@ -92,7 +92,7 @@ public void setAsText(@Nullable String replicaSetString) { String[] hostAndPort = extractHostAddressAndPort(source.trim()); if (hostAndPort.length > 2) { - if(LOG.isWarnEnabled()) { + if (LOG.isWarnEnabled()) { LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "source", source)); } return null; @@ -104,11 +104,11 @@ public void setAsText(@Nullable String replicaSetString) { return port == null ? new ServerAddress(hostAddress) : new ServerAddress(hostAddress, port); } catch (UnknownHostException e) { - if(LOG.isWarnEnabled()) { + if (LOG.isWarnEnabled()) { LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "host", hostAndPort[0])); } } catch (NumberFormatException e) { - if(LOG.isWarnEnabled()) { + if (LOG.isWarnEnabled()) { LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "port", hostAndPort[1])); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java index 7fa31cefe6..8a74ace28b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java @@ -89,7 +89,8 @@ public ChangeStreamEvent(@Nullable ChangeStreamDocument raw, Class */ public @Nullable Instant getTimestamp() { - return getBsonTimestamp() != null && raw != null ? converter.getConversionService().convert(raw.getClusterTime(), Instant.class) + return getBsonTimestamp() != null && raw != null + ? converter.getConversionService().convert(raw.getClusterTime(), Instant.class) : null; } @@ -136,8 +137,7 @@ public BsonTimestamp getBsonTimestamp() { * * @return can be {@literal null}. */ - @Nullable - public String getCollectionName() { + public @Nullable String getCollectionName() { return raw != null ? raw.getNamespace().getCollectionName() : null; } @@ -157,14 +157,14 @@ public String getCollectionName() { } /** - * Get the potentially converted {@link ChangeStreamDocument#getFullDocumentBeforeChange() document} before being changed. + * Get the potentially converted {@link ChangeStreamDocument#getFullDocumentBeforeChange() document} before being + * changed. * * @return {@literal null} when {@link #getRaw()} or {@link ChangeStreamDocument#getFullDocumentBeforeChange()} is * {@literal null}. * @since 4.0 */ - @Nullable - public T getBodyBeforeChange() { + public @Nullable T getBodyBeforeChange() { if (raw == null || raw.getFullDocumentBeforeChange() == null) { return null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java index 4ff8a130c0..92cd09a66a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java @@ -257,14 +257,12 @@ public ChangeStreamOptionsBuilder collation(Collation collation) { } /** - * Set the filter to apply. - *
+ * Set the filter to apply.
* Fields on aggregation expression root level are prefixed to map to fields contained in * {@link ChangeStreamDocument#getFullDocument() fullDocument}. However {@literal operationType}, {@literal ns}, * {@literal documentKey} and {@literal fullDocument} are reserved words that will be omitted, and therefore taken * as given, during the mapping procedure. You may want to have a look at the - * structure of Change Events. - *
+ * structure of Change Events.
* Use {@link org.springframework.data.mongodb.core.aggregation.TypedAggregation} to ensure filter expressions are * mapped to domain type fields. * @@ -358,7 +356,7 @@ public ChangeStreamOptionsBuilder fullDocumentBeforeChangeLookup(FullDocumentBef * * @return this. * @since 4.0 - * @see #fullDocumentBeforeChangeLookup(FullDocumentBeforeChange) + * @see #fullDocumentBeforeChangeLookup(FullDocumentBeforeChange) */ public ChangeStreamOptionsBuilder returnFullDocumentBeforeChange() { return fullDocumentBeforeChangeLookup(FullDocumentBeforeChange.WHEN_AVAILABLE); 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 1e63c03f05..92b90097d1 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 @@ -461,7 +461,8 @@ public static class ValidationOptions { private final @Nullable ValidationLevel validationLevel; private final @Nullable ValidationAction validationAction; - public ValidationOptions(@Nullable Validator validator, @Nullable ValidationLevel validationLevel, @Nullable ValidationAction validationAction) { + public ValidationOptions(@Nullable Validator validator, @Nullable ValidationLevel validationLevel, + @Nullable ValidationAction validationAction) { this.validator = validator; this.validationLevel = validationLevel; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java index 93d81d86e0..bdf0b90ee3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java @@ -20,13 +20,12 @@ import java.util.function.BiFunction; import java.util.function.Function; -import jakarta.validation.constraints.Null; import org.bson.Document; +import org.jspecify.annotations.Nullable; import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; import com.mongodb.client.MongoCollection; -import org.jspecify.annotations.Nullable; /** * Support class for delegate implementations to apply {@link ReadConcern} and {@link ReadPreference} settings upon diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java index 85ac36f828..11d9f09afd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java @@ -26,7 +26,6 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; import org.springframework.data.mongodb.core.query.MetricConversion; -import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** @@ -155,14 +154,12 @@ private Collection rewriteCollection(Collection source) { * @param $and potentially existing {@code $and} condition. * @return the rewritten query {@link Document}. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "NullAway" }) private static Document createGeoWithin(String key, Document source, @Nullable Object $and) { boolean spheric = source.containsKey("$nearSphere"); Object $near = spheric ? source.get("$nearSphere") : source.get("$near"); - Assert.notNull($near, "Invalid near query - must contain $nearSphere or $near"); - Number maxDistance = getMaxDistance(source, $near, spheric); List $centerMax = Arrays.asList(toCenterCoordinates($near), maxDistance); @@ -236,6 +233,7 @@ private static boolean containsNearWithMinDistance(Document source) { return source.containsKey("$minDistance"); } + @SuppressWarnings("NullAway") private static Object toCenterCoordinates(Object value) { if (ObjectUtils.isArray(value)) { @@ -254,9 +252,6 @@ private static Object toCenterCoordinates(Object value) { if (document.containsKey("$geometry")) { Document geoJsonPoint = document.get("$geometry", Document.class); - if(!geoJsonPoint.containsKey("coordinates")) { - throw new IllegalStateException("Invalid geometry without coordinates."); - } return geoJsonPoint.get("coordinates"); } } 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 638bb699df..394dff4a9c 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 @@ -412,7 +412,7 @@ public boolean skipEventPublishing() { return eventPublisher == null; } - @SuppressWarnings({"rawtypes","NullAway"}) + @SuppressWarnings({ "rawtypes", "NullAway" }) public T callback(Class callbackType, T entity, String collectionName) { if (skipEntityCallbacks()) { @@ -422,7 +422,7 @@ public T callback(Class callbackType, T entity, St return entityCallbacks.callback(callbackType, entity, collectionName); } - @SuppressWarnings({"rawtypes","NullAway"}) + @SuppressWarnings({ "rawtypes", "NullAway" }) public T callback(Class callbackType, T entity, Document document, String collectionName) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java index 2458d29ec3..e2407dcff1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java @@ -359,7 +359,7 @@ public boolean skipEventPublishing() { return eventPublisher == null; } - @SuppressWarnings({"rawtypes","NullAway"}) + @SuppressWarnings({ "rawtypes", "NullAway" }) public Mono callback(Class callbackType, T entity, String collectionName) { if (skipEntityCallbacks()) { @@ -369,7 +369,7 @@ public Mono callback(Class callbackType, T enti return entityCallbacks.callback(callbackType, entity, collectionName); } - @SuppressWarnings({"rawtypes","NullAway"}) + @SuppressWarnings({ "rawtypes", "NullAway" }) public Mono callback(Class callbackType, T entity, Document document, String collectionName) { 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 53ca30af53..69ade2e163 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 @@ -19,7 +19,6 @@ import reactor.core.publisher.Mono; import java.util.Collection; -import java.util.Optional; import org.bson.Document; import org.jspecify.annotations.Nullable; @@ -48,7 +47,7 @@ public class DefaultReactiveIndexOperations implements ReactiveIndexOperations { private final ReactiveMongoOperations mongoOperations; private final String collectionName; private final QueryMapper queryMapper; - private final Optional> type; + private final @Nullable Class type; /** * Creates a new {@link DefaultReactiveIndexOperations}. @@ -59,7 +58,7 @@ public class DefaultReactiveIndexOperations implements ReactiveIndexOperations { */ public DefaultReactiveIndexOperations(ReactiveMongoOperations mongoOperations, String collectionName, QueryMapper queryMapper) { - this(mongoOperations, collectionName, queryMapper, Optional.empty()); + this(mongoOperations, collectionName, queryMapper, null); } /** @@ -71,12 +70,7 @@ public DefaultReactiveIndexOperations(ReactiveMongoOperations mongoOperations, S * @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) { - this(mongoOperations, collectionName, queryMapper, Optional.of(type)); - } - - private DefaultReactiveIndexOperations(ReactiveMongoOperations mongoOperations, String collectionName, - QueryMapper queryMapper, Optional> type) { + QueryMapper queryMapper, @Nullable Class type) { Assert.notNull(mongoOperations, "ReactiveMongoOperations must not be null"); Assert.notNull(collectionName, "Collection must not be null"); @@ -94,9 +88,7 @@ public Mono ensureIndex(IndexDefinition indexDefinition) { return mongoOperations.execute(collectionName, collection -> { - MongoPersistentEntity entity = type - .map(val -> (MongoPersistentEntity) queryMapper.getMappingContext().getRequiredPersistentEntity(val)) - .orElseGet(() -> lookupPersistentEntity(collectionName)); + MongoPersistentEntity entity = getConfiguredEntity(); IndexOptions indexOptions = IndexConverters.indexDefinitionToIndexOptionsConverter().convert(indexDefinition); @@ -152,6 +144,14 @@ public Flux getIndexInfo() { .map(IndexConverters.documentToIndexInfoConverter()::convert); } + private @Nullable MongoPersistentEntity getConfiguredEntity() { + + if (type != null) { + return queryMapper.getMappingContext().getRequiredPersistentEntity(type); + } + return lookupPersistentEntity(collectionName); + } + private IndexOptions addPartialFilterIfPresent(IndexOptions ops, Document sourceOptions, @Nullable MongoPersistentEntity entity) { 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 745e10726b..6dde79e0e8 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 @@ -15,9 +15,9 @@ */ package org.springframework.data.mongodb.core; -import static java.util.UUID.*; -import static org.springframework.data.mongodb.core.query.Criteria.*; -import static org.springframework.data.mongodb.core.query.Query.*; +import static java.util.UUID.randomUUID; +import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.springframework.data.mongodb.core.query.Query.query; import java.util.ArrayList; import java.util.Arrays; @@ -28,8 +28,8 @@ import org.bson.Document; import org.bson.types.ObjectId; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; -import org.springframework.dao.DataAccessException; import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.mongodb.core.script.ExecutableMongoScript; import org.springframework.data.mongodb.core.script.NamedMongoScript; @@ -39,8 +39,6 @@ import org.springframework.util.StringUtils; import com.mongodb.BasicDBList; -import com.mongodb.MongoException; -import com.mongodb.client.MongoDatabase; /** * Default implementation of {@link ScriptOperations} capable of saving and executing {@link ExecutableMongoScript}. @@ -52,6 +50,7 @@ * @deprecated since 2.2. The {@code eval} command has been removed in MongoDB Server 4.2.0. */ @Deprecated +@NullUnmarked class DefaultScriptOperations implements ScriptOperations { private static final String SCRIPT_COLLECTION_NAME = "system.js"; @@ -92,12 +91,12 @@ public NamedMongoScript register(NamedMongoScript script) { return mongoOperations.execute(db -> { - Document command = new Document("$eval", script.getCode()); - BasicDBList commandArgs = new BasicDBList(); - commandArgs.addAll(Arrays.asList(convertScriptArgs(false, args))); - command.append("args", commandArgs); - return db.runCommand(command).get("retval"); - }); + Document command = new Document("$eval", script.getCode()); + BasicDBList commandArgs = new BasicDBList(); + commandArgs.addAll(Arrays.asList(convertScriptArgs(false, args))); + command.append("args", commandArgs); + return db.runCommand(command).get("retval"); + }); } @Override @@ -105,8 +104,9 @@ public NamedMongoScript register(NamedMongoScript script) { Assert.hasText(scriptName, "ScriptName must not be null or empty"); - return mongoOperations.execute(db -> db.runCommand(new Document("eval", String.format("%s(%s)", scriptName, convertAndJoinScriptArgs(args)))) - .get("retval")); + return mongoOperations.execute( + db -> db.runCommand(new Document("eval", String.format("%s(%s)", scriptName, convertAndJoinScriptArgs(args)))) + .get("retval")); } @Override diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultWriteConcernResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultWriteConcernResolver.java index a1830cd940..c445e06f8a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultWriteConcernResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultWriteConcernResolver.java @@ -15,9 +15,10 @@ */ package org.springframework.data.mongodb.core; -import com.mongodb.WriteConcern; import org.jspecify.annotations.Nullable; +import com.mongodb.WriteConcern; + /** * Default {@link WriteConcernResolver} resolving the {@link WriteConcern} from the given {@link MongoAction}. * diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java index 810be0c7a8..87a937a09e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java @@ -24,7 +24,6 @@ import java.util.concurrent.TimeUnit; import org.bson.BsonNull; -import org.bson.BsonValue; import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.core.convert.ConversionService; @@ -66,7 +65,6 @@ import org.springframework.data.projection.TargetAware; import org.springframework.data.util.Optionals; import org.springframework.expression.spel.support.SimpleEvaluationContext; -import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.LinkedMultiValueMap; @@ -416,7 +414,8 @@ interface Entity { * * @return */ - @Nullable Object getId(); + @Nullable + Object getId(); /** * Returns the property value for {@code key}. @@ -521,10 +520,9 @@ interface AdaptibleEntity extends Entity { * Populates the identifier of the backing entity if it has an identifier property and there's no identifier * currently present. * - * @param id must not be {@literal null}. + * @param id can be {@literal null}. * @return */ - @Contract("null -> fail") T populateIdIfNecessary(@Nullable Object id); /** @@ -851,7 +849,7 @@ private Object getNestedPropertyValue(String key) { currentValue = currentEntity.getPropertyValue(segment); if (i < segments.length - 1) { - if(currentValue == null) { + if (currentValue == null) { return BsonNull.VALUE; } @@ -1148,7 +1146,8 @@ private ValueEvaluationContext getEvaluationContextForEntity(@Nullable Persisten return mongoEntity.getValueEvaluationContext(null); } - return ValueEvaluationContext.of(this.environment != null ? this.environment : new StandardEnvironment(), SimpleEvaluationContext.forReadOnlyDataBinding().build()); + return ValueEvaluationContext.of(this.environment != null ? this.environment : new StandardEnvironment(), + SimpleEvaluationContext.forReadOnlyDataBinding().build()); } /** 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 33bfcf7fa3..d28afada0a 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 @@ -103,7 +103,7 @@ private String getCollectionName(@Nullable Aggregation aggregation) { return collection; } - if (aggregation instanceof TypedAggregation typedAggregation) { + if (aggregation instanceof TypedAggregation typedAggregation) { if (typedAggregation.getInputType() != null) { return template.getCollectionName(typedAggregation.getInputType()); 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 75a1955aad..1bf880fb19 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 @@ -16,14 +16,13 @@ package org.springframework.data.mongodb.core; import java.util.List; -import java.util.Optional; import java.util.stream.Stream; import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.dao.IncorrectResultSizeDataAccessException; -import org.springframework.data.domain.Window; import org.springframework.data.domain.ScrollPosition; +import org.springframework.data.domain.Window; import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.SerializationUtils; @@ -208,7 +207,7 @@ private String asString() { static class DelegatingQueryCursorPreparer implements CursorPreparer { private final @Nullable CursorPreparer delegate; - private Optional limit = Optional.empty(); + private int limit = -1; DelegatingQueryCursorPreparer(@Nullable CursorPreparer delegate) { this.delegate = delegate; @@ -218,18 +217,21 @@ static class DelegatingQueryCursorPreparer implements CursorPreparer { public FindIterable prepare(FindIterable iterable) { FindIterable target = delegate != null ? delegate.prepare(iterable) : iterable; - return limit.map(target::limit).orElse(target); + if (limit >= 0) { + target.limit(limit); + } + return target; } CursorPreparer limit(int limit) { - this.limit = Optional.of(limit); + this.limit = limit; return this; } @Override public @Nullable ReadPreference getReadPreference() { - return delegate != null ? delegate.getReadPreference() : null; + return delegate != null ? delegate.getReadPreference() : null; } } 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 a8e6397ae8..34e5e3f623 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 @@ -56,10 +56,11 @@ static class ExecutableInsertSupport implements ExecutableInsert { private final MongoTemplate template; private final Class domainType; - @Nullable private final String collection; - @Nullable private final BulkMode bulkMode; + private final @Nullable String collection; + private final @Nullable BulkMode bulkMode; - ExecutableInsertSupport(MongoTemplate template, Class domainType, @Nullable String collection, @Nullable BulkMode bulkMode) { + ExecutableInsertSupport(MongoTemplate template, Class domainType, @Nullable String collection, + @Nullable BulkMode bulkMode) { this.template = template; this.domainType = domainType; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java index 4019cb8b38..f361b19bba 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBean.java @@ -91,8 +91,6 @@ public void setSchemaMap(Map schemaMap) { @Override public AutoEncryptionSettings getObject() { - - return AutoEncryptionSettings.builder() // .bypassAutoEncryption(bypassAutoEncryption) // .keyVaultNamespace(keyVaultNamespace) // 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 10683fe3bf..0e8bbb2ba3 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 @@ -15,12 +15,22 @@ */ package org.springframework.data.mongodb.core; -import static org.springframework.data.mongodb.core.query.SerializationUtils.*; +import static org.springframework.data.mongodb.core.query.SerializationUtils.serializeToJsonSafely; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Scanner; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.BiPredicate; import java.util.stream.Collectors; @@ -92,7 +102,18 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; -import org.springframework.data.mongodb.core.mapping.event.*; +import org.springframework.data.mongodb.core.mapping.event.AfterConvertCallback; +import org.springframework.data.mongodb.core.mapping.event.AfterConvertEvent; +import org.springframework.data.mongodb.core.mapping.event.AfterDeleteEvent; +import org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent; +import org.springframework.data.mongodb.core.mapping.event.AfterSaveCallback; +import org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent; +import org.springframework.data.mongodb.core.mapping.event.BeforeConvertCallback; +import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent; +import org.springframework.data.mongodb.core.mapping.event.BeforeDeleteEvent; +import org.springframework.data.mongodb.core.mapping.event.BeforeSaveCallback; +import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent; +import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent; import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions; import org.springframework.data.mongodb.core.mapreduce.MapReduceResults; import org.springframework.data.mongodb.core.query.BasicQuery; @@ -131,7 +152,21 @@ import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoIterable; -import com.mongodb.client.model.*; +import com.mongodb.client.model.CountOptions; +import com.mongodb.client.model.CreateCollectionOptions; +import com.mongodb.client.model.CreateViewOptions; +import com.mongodb.client.model.DeleteOptions; +import com.mongodb.client.model.EstimatedDocumentCountOptions; +import com.mongodb.client.model.FindOneAndDeleteOptions; +import com.mongodb.client.model.FindOneAndReplaceOptions; +import com.mongodb.client.model.FindOneAndUpdateOptions; +import com.mongodb.client.model.ReturnDocument; +import com.mongodb.client.model.TimeSeriesGranularity; +import com.mongodb.client.model.TimeSeriesOptions; +import com.mongodb.client.model.UpdateOptions; +import com.mongodb.client.model.ValidationAction; +import com.mongodb.client.model.ValidationLevel; +import com.mongodb.client.model.ValidationOptions; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; @@ -475,7 +510,7 @@ public Stream stream(Query query, Class entityType, String collectionN return doStream(query, entityType, collectionName, entityType); } - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) protected Stream doStream(Query query, Class entityType, String collectionName, Class returnType) { Assert.notNull(query, "Query must not be null"); @@ -508,7 +543,7 @@ public String getCollectionName(Class entityClass) { } @Override - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) public Document executeCommand(String jsonCommand) { Assert.hasText(jsonCommand, "JsonCommand must not be null nor empty"); @@ -517,7 +552,7 @@ public Document executeCommand(String jsonCommand) { } @Override - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) public Document executeCommand(Document command) { Assert.notNull(command, "Command must not be null"); @@ -526,7 +561,7 @@ public Document executeCommand(Document command) { } @Override - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) public Document executeCommand(Document command, @Nullable ReadPreference readPreference) { Assert.notNull(command, "Command must not be null"); @@ -704,7 +739,7 @@ protected MongoCollection doCreateView(String name, String source, Lis } @Override - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) @Contract("null -> fail") public MongoCollection getCollection(@Nullable String collectionName) { @@ -719,7 +754,7 @@ public boolean collectionExists(Class entityClass) { } @Override - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) public boolean collectionExists(String collectionName) { Assert.notNull(collectionName, "CollectionName must not be null"); @@ -836,7 +871,7 @@ public boolean exists(Query query, String collectionName) { } @Override - @SuppressWarnings({"ConstantConditions", "NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) public boolean exists(Query query, @Nullable Class entityClass, String collectionName) { if (query == null) { @@ -936,7 +971,7 @@ public List findDistinct(Query query, String field, Class entityClass, } @Override - @SuppressWarnings({"unchecked","NullAway"}) + @SuppressWarnings({ "unchecked", "NullAway" }) public List findDistinct(Query query, String field, String collectionName, Class entityClass, Class resultClass) { @@ -1052,18 +1087,20 @@ public GeoResults geoNear(NearQuery near, Class domainType, String col } @Override - public @Nullable T findAndModify(Query query, UpdateDefinition update, Class entityClass, String collectionName) { + public @Nullable T findAndModify(Query query, UpdateDefinition update, Class entityClass, + String collectionName) { return findAndModify(query, update, new FindAndModifyOptions(), entityClass, collectionName); } @Override - public @Nullable T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class entityClass) { + public @Nullable T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, + Class entityClass) { return findAndModify(query, update, options, entityClass, getCollectionName(entityClass)); } @Override - public @Nullable T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class entityClass, - String collectionName) { + public @Nullable T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, + Class entityClass, String collectionName) { Assert.notNull(query, "Query must not be null"); Assert.notNull(update, "Update must not be null"); @@ -1087,8 +1124,8 @@ public GeoResults geoNear(NearQuery near, Class domainType, String col } @Override - public @Nullable T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class entityType, - String collectionName, Class resultType) { + public @Nullable T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, + Class entityType, String collectionName, Class resultType) { Assert.notNull(query, "Query must not be null"); Assert.notNull(replacement, "Replacement must not be null"); @@ -1305,7 +1342,7 @@ protected MongoCollection prepareCollection(MongoCollection if (ObjectUtils.nullSafeEquals(WriteResultChecking.EXCEPTION, writeResultChecking)) { if (wc == null || wc.getWObject() == null - || (wc.getWObject()instanceof Number concern && concern.intValue() < 1)) { + || (wc.getWObject() instanceof Number concern && concern.intValue() < 1)) { return WriteConcern.ACKNOWLEDGED; } } @@ -1514,7 +1551,7 @@ protected T doSave(String collectionName, T objectToSave, MongoWriter wri return maybeCallAfterSave(saved, dbDoc, collectionName); } - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) protected Object insertDocument(String collectionName, Document document, Class entityClass) { if (LOGGER.isDebugEnabled()) { @@ -1667,7 +1704,7 @@ public UpdateResult updateMulti(Query query, UpdateDefinition update, Class e return doUpdate(collectionName, query, update, entityClass, false, true); } - @SuppressWarnings({"ConstantConditions", "NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) protected UpdateResult doUpdate(String collectionName, Query query, UpdateDefinition update, @Nullable Class entityClass, boolean upsert, boolean multi) { @@ -1783,7 +1820,7 @@ public DeleteResult remove(Query query, Class entityClass, String collectionN return doRemove(collectionName, query, entityClass, true); } - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) protected DeleteResult doRemove(String collectionName, Query query, @Nullable Class entityClass, boolean multi) { @@ -1958,7 +1995,8 @@ public List mapReduce(Query query, Class domainType, String inputColle } if (mapReduceOptions.getOutputSharded().isPresent()) { - MongoCompatibilityAdapter.mapReduceIterableAdapter(mapReduce).sharded(mapReduceOptions.getOutputSharded().get()); + MongoCompatibilityAdapter.mapReduceIterableAdapter(mapReduce) + .sharded(mapReduceOptions.getOutputSharded().get()); } if (StringUtils.hasText(mapReduceOptions.getOutputCollection()) && !mapReduceOptions.usesInlineOutput()) { @@ -2057,7 +2095,7 @@ public List findAllAndRemove(Query query, Class entityClass, String co } @Override - public UpdateResult replace(Query query, T replacement, ReplaceOptions options, String collectionName){ + public UpdateResult replace(Query query, T replacement, ReplaceOptions options, String collectionName) { Assert.notNull(replacement, "Replacement must not be null"); return replace(query, (Class) ClassUtils.getUserClass(replacement), replacement, options, collectionName); @@ -2142,7 +2180,7 @@ private AggregationResults doAggregate(Aggregation aggregation, String co return doAggregate(aggregation, collectionName, outputType, context.getAggregationOperationContext()); } - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) protected AggregationResults doAggregate(Aggregation aggregation, String collectionName, Class outputType, AggregationOperationContext context) { @@ -2225,7 +2263,7 @@ protected AggregationResults doAggregate(Aggregation aggregation, String }); } - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) protected Stream aggregateStream(Aggregation aggregation, String collectionName, Class outputType, @Nullable AggregationOperationContext context) { @@ -2340,7 +2378,7 @@ protected String replaceWithResourceIfNecessary(String function) { } @Override - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) public Set getCollectionNames() { return execute(db -> { Set result = new LinkedHashSet<>(); @@ -2424,7 +2462,7 @@ protected MongoCollection doCreateCollection(String collectionName, Do * @return the collection that was created * @since 3.3.3 */ - @SuppressWarnings({"ConstantConditions","NullAway"}) + @SuppressWarnings({ "ConstantConditions", "NullAway" }) protected MongoCollection doCreateCollection(String collectionName, CreateCollectionOptions collectionOptions) { @@ -2502,8 +2540,9 @@ private CreateCollectionOptions getCreateCollectionOptions(Document document) { * @param entityClass the parameterized type of the returned list. * @return the converted object or {@literal null} if none exists. */ - protected @Nullable T doFindOne(String collectionName, CollectionPreparer> collectionPreparer, - Document query, Document fields, Class entityClass) { + protected @Nullable T doFindOne(String collectionName, + CollectionPreparer> collectionPreparer, Document query, Document fields, + Class entityClass) { return doFindOne(collectionName, collectionPreparer, query, fields, CursorPreparer.NO_OP_PREPARER, entityClass); } @@ -2521,8 +2560,9 @@ private CreateCollectionOptions getCreateCollectionOptions(Document document) { * @since 2.2 */ @SuppressWarnings("ConstantConditions") - protected @Nullable T doFindOne(String collectionName, CollectionPreparer> collectionPreparer, - Document query, Document fields, CursorPreparer preparer, Class entityClass) { + protected @Nullable T doFindOne(String collectionName, + CollectionPreparer> collectionPreparer, Document query, Document fields, + CursorPreparer preparer, Class entityClass) { MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); @@ -2695,8 +2735,9 @@ Document getMappedValidator(Validator validator, Class domainType) { * @return the List of converted objects. */ @SuppressWarnings("ConstantConditions") - protected @Nullable T doFindAndRemove(CollectionPreparer collectionPreparer, String collectionName, Document query, - @Nullable Document fields, @Nullable Document sort, @Nullable Collation collation, Class entityClass) { + protected @Nullable T doFindAndRemove(CollectionPreparer collectionPreparer, String collectionName, + Document query, @Nullable Document fields, @Nullable Document sort, @Nullable Collation collation, + Class entityClass) { if (LOGGER.isDebugEnabled()) { LOGGER.debug(String.format("findAndRemove using query: %s fields: %s sort: %s for class: %s in collection: %s", @@ -2711,8 +2752,8 @@ Document getMappedValidator(Validator validator, Class domainType) { } @SuppressWarnings("ConstantConditions") - protected @Nullable T doFindAndModify(CollectionPreparer collectionPreparer, String collectionName, Document query, - @Nullable Document fields, @Nullable Document sort, Class entityClass, UpdateDefinition update, + protected @Nullable T doFindAndModify(CollectionPreparer collectionPreparer, String collectionName, + Document query, @Nullable Document fields, @Nullable Document sort, Class entityClass, UpdateDefinition update, @Nullable FindAndModifyOptions options) { if (options == null) { @@ -2732,8 +2773,7 @@ Document getMappedValidator(Validator validator, Class domainType) { LOGGER.debug(String.format( "findAndModify using query: %s fields: %s sort: %s for class: %s and update: %s in collection: %s", serializeToJsonSafely(mappedQuery), fields, serializeToJsonSafely(sort), entityClass, - serializeToJsonSafely(mappedUpdate), - collectionName)); + serializeToJsonSafely(mappedUpdate), collectionName)); } return executeFindOneInternal( @@ -2757,9 +2797,10 @@ Document getMappedValidator(Validator validator, Class domainType) { * @return {@literal null} if object does not exist, {@link FindAndReplaceOptions#isReturnNew() return new} is * {@literal false} and {@link FindAndReplaceOptions#isUpsert() upsert} is {@literal false}. */ - protected @Nullable T doFindAndReplace(CollectionPreparer collectionPreparer, String collectionName, Document mappedQuery, - Document mappedFields, Document mappedSort, com.mongodb.client.model.@Nullable Collation collation, - Class entityType, Document replacement, FindAndReplaceOptions options, Class resultType) { + protected @Nullable T doFindAndReplace(CollectionPreparer collectionPreparer, String collectionName, + Document mappedQuery, Document mappedFields, Document mappedSort, + com.mongodb.client.model.@Nullable Collation collation, Class entityType, Document replacement, + FindAndReplaceOptions options, Class resultType) { EntityProjection projection = operations.introspectProjection(resultType, entityType); @@ -2798,9 +2839,10 @@ CollectionPreparer> createCollectionPreparer(Query que * {@literal false} and {@link FindAndReplaceOptions#isUpsert() upsert} is {@literal false}. * @since 3.4 */ - private @Nullable T doFindAndReplace(CollectionPreparer collectionPreparer, String collectionName, Document mappedQuery, - Document mappedFields, Document mappedSort, com.mongodb.client.model.@Nullable Collation collation, - Class entityType, Document replacement, FindAndReplaceOptions options, EntityProjection projection) { + private @Nullable T doFindAndReplace(CollectionPreparer collectionPreparer, String collectionName, + Document mappedQuery, Document mappedFields, Document mappedSort, + com.mongodb.client.model.@Nullable Collation collation, Class entityType, Document replacement, + FindAndReplaceOptions options, EntityProjection projection) { if (LOGGER.isDebugEnabled()) { LOGGER @@ -3153,7 +3195,8 @@ private static class FindAndModifyCallback implements CollectionCallback> collectionPreparer, Document query, - @Nullable Document fields, @Nullable Document sort, Object update, List arrayFilters, FindAndModifyOptions options) { + @Nullable Document fields, @Nullable Document sort, Object update, List arrayFilters, + FindAndModifyOptions options) { this.collectionPreparer = collectionPreparer; this.query = query; @@ -3317,10 +3360,6 @@ private class ProjectingReadCallback implements DocumentCallback { @SuppressWarnings("unchecked") public T doWith(Document document) { -// if (document == null) { -// return null; -// } - maybeEmitEvent(new AfterLoadEvent<>(document, projection.getMappedType().getType(), collectionName)); Object entity = mongoConverter.project(projection, document); 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 04fd312847..89caf3273c 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 @@ -124,7 +124,7 @@ protected MongoClient createInstance() throws Exception { @Override protected void destroyInstance(@Nullable MongoClient instance) throws Exception { - if(instance != null) { + if (instance != null) { instance.close(); } } 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 ea4b15a856..c203e33a55 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 @@ -15,9 +15,8 @@ */ package org.springframework.data.mongodb.core; -import static org.springframework.data.mongodb.core.query.SerializationUtils.*; +import static org.springframework.data.mongodb.core.query.SerializationUtils.serializeToJsonSafely; -import org.springframework.lang.Contract; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -48,7 +47,6 @@ import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.reactivestreams.Subscriber; - import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -111,7 +109,18 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes; -import org.springframework.data.mongodb.core.mapping.event.*; +import org.springframework.data.mongodb.core.mapping.event.AfterConvertEvent; +import org.springframework.data.mongodb.core.mapping.event.AfterDeleteEvent; +import org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent; +import org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent; +import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent; +import org.springframework.data.mongodb.core.mapping.event.BeforeDeleteEvent; +import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent; +import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent; +import org.springframework.data.mongodb.core.mapping.event.ReactiveAfterConvertCallback; +import org.springframework.data.mongodb.core.mapping.event.ReactiveAfterSaveCallback; +import org.springframework.data.mongodb.core.mapping.event.ReactiveBeforeConvertCallback; +import org.springframework.data.mongodb.core.mapping.event.ReactiveBeforeSaveCallback; import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions; import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.core.query.Collation; @@ -123,6 +132,7 @@ import org.springframework.data.mongodb.util.MongoCompatibilityAdapter; import org.springframework.data.projection.EntityProjection; import org.springframework.data.util.Optionals; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -346,7 +356,8 @@ public void setWriteConcern(@Nullable WriteConcern writeConcern) { * @param writeConcernResolver can be {@literal null}. */ public void setWriteConcernResolver(@Nullable WriteConcernResolver writeConcernResolver) { - this.writeConcernResolver = writeConcernResolver != null ? writeConcernResolver : DefaultWriteConcernResolver.INSTANCE; + this.writeConcernResolver = writeConcernResolver != null ? writeConcernResolver + : DefaultWriteConcernResolver.INSTANCE; } /** @@ -740,10 +751,11 @@ public Mono collectionExists(Class entityClass) { @Override public Mono collectionExists(String collectionName) { - return createMono(db -> Flux.from(MongoCompatibilityAdapter.reactiveMongoDatabaseAdapter().forDb(db).listCollectionNames()) // - .filter(s -> s.equals(collectionName)) // - .map(s -> true) // - .single(false)); + return createMono( + db -> Flux.from(MongoCompatibilityAdapter.reactiveMongoDatabaseAdapter().forDb(db).listCollectionNames()) // + .filter(s -> s.equals(collectionName)) // + .map(s -> true) // + .single(false)); } @Override @@ -900,7 +912,7 @@ Mono> doScroll(Query query, Class sourceClass, Class targetC Mono> result = doFind(collectionName, ReactiveCollectionPreparerDelegate.of(query), keysetPaginationQuery.query(), keysetPaginationQuery.fields(), sourceClass, new QueryFindPublisherPreparer(query, keysetPaginationQuery.sort(), limit, 0, sourceClass), callback) - .collectList(); + .collectList(); return result.map(it -> ScrollUtils.createWindow(query, it, sourceClass, operations)); } @@ -908,7 +920,7 @@ Mono> doScroll(Query query, Class sourceClass, Class targetC Mono> result = doFind(collectionName, ReactiveCollectionPreparerDelegate.of(query), query.getQueryObject(), query.getFieldsObject(), sourceClass, new QueryFindPublisherPreparer(query, query.getSortObject(), limit, query.getSkip(), sourceClass), callback) - .collectList(); + .collectList(); return result.map( it -> ScrollUtils.createWindow(it, query.getLimit(), OffsetScrollPosition.positionFunction(query.getSkip()))); @@ -1818,7 +1830,8 @@ protected Mono doUpdate(String collectionName, Query query, Update Document updateObj = updateContext.getMappedUpdate(entity); if (containsVersionProperty(queryObj, entity)) - throw new OptimisticLockingFailureException("Optimistic lock exception on saving entity %s to collection %s".formatted(entity.getName(), collectionName)); + throw new OptimisticLockingFailureException("Optimistic lock exception on saving entity %s to collection %s" + .formatted(entity.getName(), collectionName)); } } }); @@ -2390,8 +2403,8 @@ protected Flux doFind(String collectionName, serializeToJsonSafely(mappedQuery), mappedFields, entityClass, collectionName)); } - return executeFindMultiInternal(new FindCallback(collectionPreparer, mappedQuery, mappedFields), preparer != null ? preparer : FindPublisherPreparer.NO_OP_PREPARER, - objectCallback, collectionName); + return executeFindMultiInternal(new FindCallback(collectionPreparer, mappedQuery, mappedFields), + preparer != null ? preparer : FindPublisherPreparer.NO_OP_PREPARER, objectCallback, collectionName); } CollectionPreparer> createCollectionPreparer(Query query) { @@ -2456,8 +2469,8 @@ protected CreateCollectionOptions convertToCreateCollectionOptions(@Nullable Col * @return the List of converted objects. */ protected Mono doFindAndRemove(String collectionName, - CollectionPreparer> collectionPreparer, Document query, Document fields, @Nullable Document sort, - @Nullable Collation collation, Class entityClass) { + CollectionPreparer> collectionPreparer, Document query, Document fields, + @Nullable Document sort, @Nullable Collation collation, Class entityClass) { if (LOGGER.isDebugEnabled()) { LOGGER.debug(String.format("findAndRemove using query: %s fields: %s sort: %s for class: %s in collection: %s", @@ -2473,8 +2486,7 @@ protected Mono doFindAndRemove(String collectionName, protected Mono doFindAndModify(String collectionName, CollectionPreparer> collectionPreparer, Document query, Document fields, - @Nullable Document sort, - Class entityClass, UpdateDefinition update, FindAndModifyOptions options) { + @Nullable Document sort, Class entityClass, UpdateDefinition update, FindAndModifyOptions options) { MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); UpdateContext updateContext = queryOperations.updateSingleContext(update, query, false); @@ -2490,8 +2502,7 @@ protected Mono doFindAndModify(String collectionName, LOGGER.debug(String.format( "findAndModify using query: %s fields: %s sort: %s for class: %s and update: %s " + "in collection: %s", serializeToJsonSafely(mappedQuery), fields, serializeToJsonSafely(sort), entityClass, - serializeToJsonSafely(mappedUpdate), - collectionName)); + serializeToJsonSafely(mappedUpdate), collectionName)); } return executeFindOneInternal( @@ -2687,7 +2698,7 @@ private WriteConcern potentiallyForceAcknowledgedWrite(@Nullable WriteConcern wc if (ObjectUtils.nullSafeEquals(WriteResultChecking.EXCEPTION, writeResultChecking)) { if (wc == null || wc.getWObject() == null - || (wc.getWObject()instanceof Number concern && concern.intValue() < 1)) { + || (wc.getWObject() instanceof Number concern && concern.intValue() < 1)) { return WriteConcern.ACKNOWLEDGED; } } @@ -2869,7 +2880,8 @@ private static class FindCallback implements ReactiveCollectionQueryCallback> collectionPreparer, @Nullable Document query, @Nullable Document fields) { + FindCallback(CollectionPreparer> collectionPreparer, @Nullable Document query, + @Nullable Document fields) { this.collectionPreparer = collectionPreparer; this.query = query; this.fields = fields; @@ -2942,7 +2954,8 @@ private static class FindAndModifyCallback implements ReactiveCollectionCallback private final FindAndModifyOptions options; FindAndModifyCallback(CollectionPreparer> collectionPreparer, Document query, - @Nullable Document fields, @Nullable Document sort, Object update, List arrayFilters, FindAndModifyOptions options) { + @Nullable Document fields, @Nullable Document sort, Object update, List arrayFilters, + FindAndModifyOptions options) { this.collectionPreparer = collectionPreparer; this.query = query; @@ -3056,7 +3069,8 @@ private FindOneAndReplaceOptions convertToFindOneAndReplaceOptions(FindAndReplac } } - private static FindOneAndDeleteOptions convertToFindOneAndDeleteOptions(@Nullable Document fields, @Nullable Document sort) { + private static FindOneAndDeleteOptions convertToFindOneAndDeleteOptions(@Nullable Document fields, + @Nullable Document sort) { FindOneAndDeleteOptions result = new FindOneAndDeleteOptions(); result = result.projection(fields).sort(sort); From 9f74c99ea71e465c92622e3c54989d3ed6ecc235 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 18 Mar 2025 16:32:08 +0100 Subject: [PATCH 17/17] Add a round of contract annotations --- .../data/mongodb/BindableMongoExpression.java | 3 + .../data/mongodb/MongoTransactionOptions.java | 2 + .../mongodb/core/ChangeStreamOptions.java | 12 +++ .../data/mongodb/core/CollectionOptions.java | 7 ++ .../mongodb/core/DefaultBulkOperations.java | 12 +++ .../core/DefaultReactiveBulkOperations.java | 9 ++ .../core/ExecutableFindOperationSupport.java | 8 ++ .../ExecutableInsertOperationSupport.java | 4 + .../ExecutableMapReduceOperationSupport.java | 2 + .../ExecutableRemoveOperationSupport.java | 7 +- .../ExecutableUpdateOperationSupport.java | 18 +++- .../mongodb/core/FindAndModifyOptions.java | 5 + .../mongodb/core/FindAndReplaceOptions.java | 4 + .../core/MappingMongoJsonSchemaCreator.java | 3 + .../core/MongoDatabaseFactorySupport.java | 2 + .../data/mongodb/core/MongoTemplate.java | 1 + .../data/mongodb/core/ReplaceOptions.java | 2 + .../data/mongodb/core/ViewOptions.java | 2 + .../aggregation/AccumulatorOperators.java | 32 ++++++- .../core/aggregation/AddFieldsOperation.java | 3 + .../core/aggregation/AggregationOptions.java | 17 ++++ .../core/aggregation/AggregationPipeline.java | 2 + .../core/aggregation/AggregationUpdate.java | 8 ++ .../core/aggregation/ArithmeticOperators.java | 96 ++++++++++--------- .../core/aggregation/ArrayOperators.java | 20 +++- .../core/aggregation/BooleanOperators.java | 7 ++ .../core/aggregation/BucketOperation.java | 3 + .../core/aggregation/ComparisonOperators.java | 22 +++++ .../aggregation/ConditionalOperators.java | 19 ++++ .../core/aggregation/DateOperators.java | 67 +++++++++++++ .../core/aggregation/DensifyOperation.java | 4 + .../core/aggregation/DocumentOperators.java | 4 + .../core/aggregation/FacetOperation.java | 1 + .../data/mongodb/core/aggregation/Fields.java | 4 + .../core/aggregation/GeoNearOperation.java | 2 + .../aggregation/GraphLookupOperation.java | 22 ++++- .../core/aggregation/LookupOperation.java | 7 ++ .../core/aggregation/MergeOperation.java | 15 +++ .../core/aggregation/ObjectOperators.java | 9 ++ .../core/aggregation/OutOperation.java | 8 ++ .../core/aggregation/ProjectionOperation.java | 9 ++ .../core/aggregation/RedactOperation.java | 16 +++- .../aggregation/ReplaceRootOperation.java | 1 + .../core/aggregation/ScriptOperators.java | 55 +++++------ .../core/aggregation/SelectionOperators.java | 26 +++++ .../core/aggregation/SetOperation.java | 2 + .../core/aggregation/SetOperators.java | 14 +++ .../aggregation/SetWindowFieldsOperation.java | 34 ++++++- .../core/aggregation/StringOperators.java | 58 +++++++++++ .../core/aggregation/UnsetOperation.java | 3 + .../core/aggregation/UnwindOperation.java | 4 + .../core/convert/MongoCustomConversions.java | 9 ++ .../data/mongodb/core/geo/GeoJsonPolygon.java | 4 + .../mongodb/core/index/GeospatialIndex.java | 10 ++ .../data/mongodb/core/index/Index.java | 13 ++- .../core/index/TextIndexDefinition.java | 11 +++ .../mongodb/core/index/WildcardIndex.java | 10 ++ .../data/mongodb/core/mapping/MongoField.java | 6 ++ .../core/mapreduce/MapReduceOptions.java | 14 +++ .../core/messaging/ChangeStreamRequest.java | 15 +++ .../data/mongodb/core/messaging/Message.java | 4 + .../core/messaging/TailableCursorRequest.java | 8 ++ .../data/mongodb/core/query/BasicQuery.java | 2 + .../data/mongodb/core/query/BasicUpdate.java | 10 ++ .../data/mongodb/core/query/Collation.java | 17 ++++ .../data/mongodb/core/query/Criteria.java | 45 +++++++++ .../data/mongodb/core/query/Field.java | 12 +++ .../data/mongodb/core/query/NearQuery.java | 22 ++++- .../data/mongodb/core/query/Query.java | 30 +++++- .../data/mongodb/core/query/Term.java | 2 + .../data/mongodb/core/query/TextCriteria.java | 9 ++ .../data/mongodb/core/query/TextQuery.java | 9 +- .../data/mongodb/core/query/Update.java | 27 ++++++ .../IdentifiableJsonSchemaProperty.java | 87 +++++++++++++++++ .../mongodb/core/schema/MongoJsonSchema.java | 16 ++++ .../core/schema/TypedJsonSchemaObject.java | 89 +++++++++++++++++ .../core/schema/UntypedJsonSchemaObject.java | 13 +++ .../data/mongodb/gridfs/GridFsObject.java | 4 + .../data/mongodb/gridfs/GridFsUpload.java | 10 ++ .../mongodb/gridfs/ReactiveGridFsUpload.java | 14 ++- .../data/mongodb/core/aggregation/Order.java | 2 + 81 files changed, 1122 insertions(+), 99 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java index d44da10431..3ae41aad35 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java @@ -23,6 +23,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec; import org.springframework.data.util.Lazy; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -92,6 +93,7 @@ public BindableMongoExpression(String expression, @Nullable CodecRegistryProvide * @param codecRegistry must not be {@literal null}. * @return new instance of {@link BindableMongoExpression}. */ + @Contract("_ -> new") public BindableMongoExpression withCodecRegistry(CodecRegistry codecRegistry) { return new BindableMongoExpression(expressionString, () -> codecRegistry, args); } @@ -102,6 +104,7 @@ public BindableMongoExpression withCodecRegistry(CodecRegistry codecRegistry) { * @param args must not be {@literal null}. * @return new instance of {@link BindableMongoExpression}. */ + @Contract("_ -> new") public BindableMongoExpression bind(Object... args) { return new BindableMongoExpression(expressionString, codecRegistryProvider, args); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java index 0fcaa19002..04bcd36e35 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java @@ -28,6 +28,7 @@ import com.mongodb.ReadPreference; import com.mongodb.TransactionOptions; import com.mongodb.WriteConcern; +import org.springframework.lang.Contract; /** * Options to be applied within a specific transaction scope. @@ -72,6 +73,7 @@ public interface MongoTransactionOptions * @return new instance of {@link MongoTransactionOptions} or this if {@literal fallbackOptions} is {@literal null} or * {@link #NONE}. */ + @Contract("null -> this") default MongoTransactionOptions mergeWith(@Nullable MongoTransactionOptions fallbackOptions) { if (fallbackOptions == null || MongoTransactionOptions.NONE.equals(fallbackOptions)) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java index 92cd09a66a..9c99b0e01f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java @@ -26,6 +26,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -248,6 +249,7 @@ private ChangeStreamOptionsBuilder() {} * @param collation must not be {@literal null} nor {@literal empty}. * @return this. */ + @Contract("_ -> this") public ChangeStreamOptionsBuilder collation(Collation collation) { Assert.notNull(collation, "Collation must not be null nor empty"); @@ -270,6 +272,7 @@ public ChangeStreamOptionsBuilder collation(Collation collation) { * {@literal null}. * @return this. */ + @Contract("_ -> this") public ChangeStreamOptionsBuilder filter(Aggregation filter) { Assert.notNull(filter, "Filter must not be null"); @@ -284,6 +287,7 @@ public ChangeStreamOptionsBuilder filter(Aggregation filter) { * @param filter must not be {@literal null} nor contain {@literal null} values. * @return this. */ + @Contract("_ -> this") public ChangeStreamOptionsBuilder filter(Document... filter) { Assert.noNullElements(filter, "Filter must not contain null values"); @@ -299,6 +303,7 @@ public ChangeStreamOptionsBuilder filter(Document... filter) { * @param resumeToken must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public ChangeStreamOptionsBuilder resumeToken(BsonValue resumeToken) { Assert.notNull(resumeToken, "ResumeToken must not be null"); @@ -328,6 +333,7 @@ public ChangeStreamOptionsBuilder returnFullDocumentOnUpdate() { * @param lookup must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public ChangeStreamOptionsBuilder fullDocumentLookup(FullDocument lookup) { Assert.notNull(lookup, "Lookup must not be null"); @@ -343,6 +349,7 @@ public ChangeStreamOptionsBuilder fullDocumentLookup(FullDocument lookup) { * @return this. * @since 4.0 */ + @Contract("_ -> this") public ChangeStreamOptionsBuilder fullDocumentBeforeChangeLookup(FullDocumentBeforeChange lookup) { Assert.notNull(lookup, "Lookup must not be null"); @@ -368,6 +375,7 @@ public ChangeStreamOptionsBuilder returnFullDocumentBeforeChange() { * @param resumeTimestamp must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public ChangeStreamOptionsBuilder resumeAt(Instant resumeTimestamp) { Assert.notNull(resumeTimestamp, "ResumeTimestamp must not be null"); @@ -383,6 +391,7 @@ public ChangeStreamOptionsBuilder resumeAt(Instant resumeTimestamp) { * @return this. * @since 2.2 */ + @Contract("_ -> this") public ChangeStreamOptionsBuilder resumeAt(BsonTimestamp resumeTimestamp) { Assert.notNull(resumeTimestamp, "ResumeTimestamp must not be null"); @@ -398,6 +407,7 @@ public ChangeStreamOptionsBuilder resumeAt(BsonTimestamp resumeTimestamp) { * @return this. * @since 2.2 */ + @Contract("_ -> this") public ChangeStreamOptionsBuilder resumeAfter(BsonValue resumeToken) { resumeToken(resumeToken); @@ -413,6 +423,7 @@ public ChangeStreamOptionsBuilder resumeAfter(BsonValue resumeToken) { * @return this. * @since 2.2 */ + @Contract("_ -> this") public ChangeStreamOptionsBuilder startAfter(BsonValue resumeToken) { resumeToken(resumeToken); @@ -424,6 +435,7 @@ public ChangeStreamOptionsBuilder startAfter(BsonValue resumeToken) { /** * @return the built {@link ChangeStreamOptions} */ + @Contract("-> new") public ChangeStreamOptions build() { ChangeStreamOptions options = new ChangeStreamOptions(); 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 92b90097d1..ff2c708aa9 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 @@ -27,6 +27,7 @@ import org.springframework.data.mongodb.core.timeseries.GranularityDefinition; import org.springframework.data.mongodb.core.validation.Validator; import org.springframework.data.util.Optionals; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -484,6 +485,7 @@ public static ValidationOptions none() { * @param validator can be {@literal null}. * @return new instance of {@link ValidationOptions}. */ + @Contract("_ -> new") public ValidationOptions validator(@Nullable Validator validator) { return new ValidationOptions(validator, validationLevel, validationAction); } @@ -494,6 +496,7 @@ public ValidationOptions validator(@Nullable Validator validator) { * @param validationLevel can be {@literal null}. * @return new instance of {@link ValidationOptions}. */ + @Contract("_ -> new") public ValidationOptions validationLevel(ValidationLevel validationLevel) { return new ValidationOptions(validator, validationLevel, validationAction); } @@ -504,6 +507,7 @@ public ValidationOptions validationLevel(ValidationLevel validationLevel) { * @param validationAction can be {@literal null}. * @return new instance of {@link ValidationOptions}. */ + @Contract("_ -> new") public ValidationOptions validationAction(ValidationAction validationAction) { return new ValidationOptions(validator, validationLevel, validationAction); } @@ -678,6 +682,7 @@ public static TimeSeriesOptions timeSeries(String timeField) { * @param metaField must not be {@literal null}. * @return new instance of {@link TimeSeriesOptions}. */ + @Contract("_ -> new") public TimeSeriesOptions metaField(String metaField) { return new TimeSeriesOptions(timeField, metaField, granularity, expireAfter); } @@ -689,6 +694,7 @@ public TimeSeriesOptions metaField(String metaField) { * @return new instance of {@link TimeSeriesOptions}. * @see Granularity */ + @Contract("_ -> new") public TimeSeriesOptions granularity(GranularityDefinition granularity) { return new TimeSeriesOptions(timeField, metaField, granularity, expireAfter); } @@ -701,6 +707,7 @@ public TimeSeriesOptions granularity(GranularityDefinition granularity) { * @see com.mongodb.client.model.CreateCollectionOptions#expireAfter(long, java.util.concurrent.TimeUnit) * @since 4.4 */ + @Contract("_ -> new") public TimeSeriesOptions expireAfter(Duration ttl) { return new TimeSeriesOptions(timeField, metaField, granularity, ttl); } 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 394dff4a9c..8bc5349e61 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 @@ -41,6 +41,7 @@ import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.data.util.Pair; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import com.mongodb.MongoBulkWriteException; @@ -115,6 +116,7 @@ void setDefaultWriteConcern(@Nullable WriteConcern defaultWriteConcern) { } @Override + @Contract("_ -> this") public BulkOperations insert(Object document) { Assert.notNull(document, "Document must not be null"); @@ -127,6 +129,7 @@ public BulkOperations insert(Object document) { } @Override + @Contract("_ -> this") public BulkOperations insert(List documents) { Assert.notNull(documents, "Documents must not be null"); @@ -137,6 +140,7 @@ public BulkOperations insert(List documents) { } @Override + @Contract("_, _ -> this") public BulkOperations updateOne(Query query, UpdateDefinition update) { Assert.notNull(query, "Query must not be null"); @@ -146,6 +150,7 @@ public BulkOperations updateOne(Query query, UpdateDefinition update) { } @Override + @Contract("_ -> this") public BulkOperations updateOne(List> updates) { Assert.notNull(updates, "Updates must not be null"); @@ -158,6 +163,7 @@ public BulkOperations updateOne(List> updates) { } @Override + @Contract("_, _ -> this") public BulkOperations updateMulti(Query query, UpdateDefinition update) { Assert.notNull(query, "Query must not be null"); @@ -169,6 +175,7 @@ public BulkOperations updateMulti(Query query, UpdateDefinition update) { } @Override + @Contract("_ -> this") public BulkOperations updateMulti(List> updates) { Assert.notNull(updates, "Updates must not be null"); @@ -181,11 +188,13 @@ public BulkOperations updateMulti(List> updates) { } @Override + @Contract("_, _ -> this") public BulkOperations upsert(Query query, UpdateDefinition update) { return update(query, update, true, true); } @Override + @Contract("_ -> this") public BulkOperations upsert(List> updates) { for (Pair update : updates) { @@ -196,6 +205,7 @@ public BulkOperations upsert(List> updates) { } @Override + @Contract("_ -> this") public BulkOperations remove(Query query) { Assert.notNull(query, "Query must not be null"); @@ -209,6 +219,7 @@ public BulkOperations remove(Query query) { } @Override + @Contract("_ -> this") public BulkOperations remove(List removes) { Assert.notNull(removes, "Removals must not be null"); @@ -221,6 +232,7 @@ public BulkOperations remove(List removes) { } @Override + @Contract("_, _, _ -> this") public BulkOperations replaceOne(Query query, Object replacement, FindAndReplaceOptions options) { Assert.notNull(query, "Query must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java index e2407dcff1..92c6a957dc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperations.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.core; +import org.springframework.lang.Contract; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -107,6 +108,7 @@ void setDefaultWriteConcern(@Nullable WriteConcern defaultWriteConcern) { } @Override + @Contract("_ -> this") public ReactiveBulkOperations insert(Object document) { Assert.notNull(document, "Document must not be null"); @@ -120,6 +122,7 @@ public ReactiveBulkOperations insert(Object document) { } @Override + @Contract("_ -> this") public ReactiveBulkOperations insert(List documents) { Assert.notNull(documents, "Documents must not be null"); @@ -130,6 +133,7 @@ public ReactiveBulkOperations insert(List documents) { } @Override + @Contract("_, _, _ -> this") public ReactiveBulkOperations updateOne(Query query, UpdateDefinition update) { Assert.notNull(query, "Query must not be null"); @@ -140,6 +144,7 @@ public ReactiveBulkOperations updateOne(Query query, UpdateDefinition update) { } @Override + @Contract("_, _ -> this") public ReactiveBulkOperations updateMulti(Query query, UpdateDefinition update) { Assert.notNull(query, "Query must not be null"); @@ -150,11 +155,13 @@ public ReactiveBulkOperations updateMulti(Query query, UpdateDefinition update) } @Override + @Contract("_, _ -> this") public ReactiveBulkOperations upsert(Query query, UpdateDefinition update) { return update(query, update, true, true); } @Override + @Contract("_ -> this") public ReactiveBulkOperations remove(Query query) { Assert.notNull(query, "Query must not be null"); @@ -169,6 +176,7 @@ public ReactiveBulkOperations remove(Query query) { } @Override + @Contract("_ -> this") public ReactiveBulkOperations remove(List removes) { Assert.notNull(removes, "Removals must not be null"); @@ -181,6 +189,7 @@ public ReactiveBulkOperations remove(List removes) { } @Override + @Contract("_, _, _ -> this") public ReactiveBulkOperations replaceOne(Query query, Object replacement, FindAndReplaceOptions options) { Assert.notNull(query, "Query must not be null"); 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 1bf880fb19..af8c80903a 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 @@ -26,6 +26,7 @@ import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.SerializationUtils; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -51,6 +52,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation { } @Override + @Contract("_ -> new") public ExecutableFind query(Class domainType) { Assert.notNull(domainType, "DomainType must not be null"); @@ -82,6 +84,7 @@ static class ExecutableFindSupport } @Override + @Contract("_ -> new") public FindWithProjection inCollection(String collection) { Assert.hasText(collection, "Collection name must not be null nor empty"); @@ -90,6 +93,7 @@ public FindWithProjection inCollection(String collection) { } @Override + @Contract("_ -> new") public FindWithQuery as(Class returnType) { Assert.notNull(returnType, "ReturnType must not be null"); @@ -98,6 +102,7 @@ public FindWithQuery as(Class returnType) { } @Override + @Contract("_ -> new") public TerminatingFind matching(Query query) { Assert.notNull(query, "Query must not be null"); @@ -223,6 +228,7 @@ public FindIterable prepare(FindIterable iterable) { return target; } + @Contract("_ -> this") CursorPreparer limit(int limit) { this.limit = limit; @@ -252,6 +258,7 @@ public DistinctOperationSupport(ExecutableFindSupport delegate, String field) @Override @SuppressWarnings("unchecked") + @Contract("_ -> new") public TerminatingDistinct as(Class resultType) { Assert.notNull(resultType, "ResultType must not be null"); @@ -260,6 +267,7 @@ public TerminatingDistinct as(Class resultType) { } @Override + @Contract("_ -> new") public TerminatingDistinct matching(Query query) { Assert.notNull(query, "Query must not be null"); 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 34e5e3f623..599a910035 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 @@ -20,6 +20,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.BulkOperations.BulkMode; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -41,6 +42,7 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation { } @Override + @Contract("_ -> new") public ExecutableInsert insert(Class domainType) { Assert.notNull(domainType, "DomainType must not be null"); @@ -94,6 +96,7 @@ public BulkWriteResult bulk(Collection objects) { } @Override + @Contract("_ -> new") public InsertWithBulkMode inCollection(String collection) { Assert.hasText(collection, "Collection must not be null nor empty"); @@ -102,6 +105,7 @@ public InsertWithBulkMode inCollection(String collection) { } @Override + @Contract("_ -> new") public TerminatingBulkInsert withBulkMode(BulkMode bulkMode) { Assert.notNull(bulkMode, "BulkMode must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java index a1f5ab4ef2..55864cbd8e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableMapReduceOperationSupport.java @@ -20,6 +20,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -46,6 +47,7 @@ class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperatio * @see in org.springframework.data.mongodb.core.ExecutableMapReduceOperation#mapReduce(java.lang.Class) */ @Override + @Contract("_ -> new") public ExecutableMapReduceSupport mapReduce(Class domainType) { Assert.notNull(domainType, "DomainType must not be null"); 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 37a975264d..e53e80b10f 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 @@ -19,6 +19,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -42,6 +43,7 @@ public ExecutableRemoveOperationSupport(MongoTemplate tempate) { } @Override + @Contract("_ -> new") public ExecutableRemove remove(Class domainType) { Assert.notNull(domainType, "DomainType must not be null"); @@ -60,7 +62,8 @@ static class ExecutableRemoveSupport implements ExecutableRemove, RemoveWi private final Query query; @Nullable private final String collection; - public ExecutableRemoveSupport(MongoTemplate template, Class domainType, Query query, @Nullable String collection) { + public ExecutableRemoveSupport(MongoTemplate template, Class domainType, Query query, + @Nullable String collection) { this.template = template; this.domainType = domainType; this.query = query; @@ -68,6 +71,7 @@ public ExecutableRemoveSupport(MongoTemplate template, Class domainType, Quer } @Override + @Contract("_ -> new") public RemoveWithQuery inCollection(String collection) { Assert.hasText(collection, "Collection must not be null nor empty"); @@ -76,6 +80,7 @@ public RemoveWithQuery inCollection(String collection) { } @Override + @Contract("_ -> new") public TerminatingRemove matching(Query query) { Assert.notNull(query, "Query must not be null"); 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 c1cc8d57ce..75756c6f1e 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 @@ -18,6 +18,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.UpdateDefinition; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -41,6 +42,7 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation { } @Override + @Contract("_ -> new") public ExecutableUpdate update(Class domainType) { Assert.notNull(domainType, "DomainType must not be null"); @@ -68,8 +70,8 @@ static class ExecutableUpdateSupport private final Class targetType; ExecutableUpdateSupport(MongoTemplate template, Class domainType, Query query, @Nullable UpdateDefinition update, - @Nullable String collection, @Nullable FindAndModifyOptions findAndModifyOptions, @Nullable FindAndReplaceOptions findAndReplaceOptions, - @Nullable Object replacement, Class targetType) { + @Nullable String collection, @Nullable FindAndModifyOptions findAndModifyOptions, + @Nullable FindAndReplaceOptions findAndReplaceOptions, @Nullable Object replacement, Class targetType) { this.template = template; this.domainType = domainType; @@ -83,6 +85,7 @@ static class ExecutableUpdateSupport } @Override + @Contract("_ -> new") public TerminatingUpdate apply(UpdateDefinition update) { Assert.notNull(update, "Update must not be null"); @@ -92,6 +95,7 @@ public TerminatingUpdate apply(UpdateDefinition update) { } @Override + @Contract("_ -> new") public UpdateWithQuery inCollection(String collection) { Assert.hasText(collection, "Collection must not be null nor empty"); @@ -101,6 +105,7 @@ public UpdateWithQuery inCollection(String collection) { } @Override + @Contract("_ -> new") public TerminatingFindAndModify withOptions(FindAndModifyOptions options) { Assert.notNull(options, "Options must not be null"); @@ -110,6 +115,7 @@ public TerminatingFindAndModify withOptions(FindAndModifyOptions options) { } @Override + @Contract("_ -> new") public FindAndReplaceWithProjection replaceWith(T replacement) { Assert.notNull(replacement, "Replacement must not be null"); @@ -119,6 +125,7 @@ public FindAndReplaceWithProjection replaceWith(T replacement) { } @Override + @Contract("_ -> new") public FindAndReplaceWithProjection withOptions(FindAndReplaceOptions options) { Assert.notNull(options, "Options must not be null"); @@ -128,6 +135,7 @@ public FindAndReplaceWithProjection withOptions(FindAndReplaceOptions options } @Override + @Contract("_ -> new") public TerminatingReplace withOptions(ReplaceOptions options) { FindAndReplaceOptions target = new FindAndReplaceOptions(); @@ -139,6 +147,7 @@ public TerminatingReplace withOptions(ReplaceOptions options) { } @Override + @Contract("_ -> new") public UpdateWithUpdate matching(Query query) { Assert.notNull(query, "Query must not be null"); @@ -148,6 +157,7 @@ public UpdateWithUpdate matching(Query query) { } @Override + @Contract("_ -> new") public FindAndReplaceWithOptions as(Class resultType) { Assert.notNull(resultType, "ResultType must not be null"); @@ -181,7 +191,7 @@ public UpdateResult upsert() { } @Override - @SuppressWarnings({"unchecked", "NullAway"}) + @SuppressWarnings({ "unchecked", "NullAway" }) public @Nullable T findAndReplaceValue() { return (T) template.findAndReplace(query, replacement, @@ -190,7 +200,7 @@ public UpdateResult upsert() { } @Override - @SuppressWarnings({"unchecked", "NullAway"}) + @SuppressWarnings({ "unchecked", "NullAway" }) public UpdateResult replaceFirst() { if (replacement != null) { 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 6497d156c4..6e9b775324 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 @@ -19,6 +19,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Contract; /** * @author Mark Pollak @@ -99,16 +100,19 @@ public static FindAndModifyOptions of(@Nullable FindAndModifyOptions source) { return options; } + @Contract("_ -> this") public FindAndModifyOptions returnNew(boolean returnNew) { this.returnNew = returnNew; return this; } + @Contract("_ -> this") public FindAndModifyOptions upsert(boolean upsert) { this.upsert = upsert; return this; } + @Contract("_ -> this") public FindAndModifyOptions remove(boolean remove) { this.remove = remove; return this; @@ -121,6 +125,7 @@ public FindAndModifyOptions remove(boolean remove) { * @return this. * @since 2.0 */ + @Contract("_ -> this") public FindAndModifyOptions collation(@Nullable Collation collation) { this.collation = collation; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndReplaceOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndReplaceOptions.java index 266a0742c2..2005ba3c6c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndReplaceOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndReplaceOptions.java @@ -15,6 +15,8 @@ */ package org.springframework.data.mongodb.core; +import org.springframework.lang.Contract; + /** * Options for * findOneAndReplace. @@ -95,6 +97,7 @@ public static FindAndReplaceOptions empty() { * * @return this. */ + @Contract("-> this") public FindAndReplaceOptions returnNew() { this.returnNew = true; @@ -106,6 +109,7 @@ public FindAndReplaceOptions returnNew() { * * @return this. */ + @Contract("-> this") public FindAndReplaceOptions upsert() { super.upsert(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java index d6239794e9..789b9a013e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java @@ -42,6 +42,7 @@ import org.springframework.data.mongodb.core.schema.MongoJsonSchema.MongoJsonSchemaBuilder; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -90,6 +91,7 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator { } @Override + @Contract("_ -> new") public MongoJsonSchemaCreator filter(Predicate filter) { return new MappingMongoJsonSchemaCreator(converter, mappingContext, filter, mergeProperties); } @@ -107,6 +109,7 @@ public PropertySpecifier property(String path) { * @return new instance of {@link MongoJsonSchemaCreator}. * @since 3.4 */ + @Contract("_, _ -> new") public MongoJsonSchemaCreator withTypesFor(String path, Class... types) { LinkedMultiValueMap> clone = mergeProperties.clone(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDatabaseFactorySupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDatabaseFactorySupport.java index 59651e7cca..0a62b7aa49 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDatabaseFactorySupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDatabaseFactorySupport.java @@ -21,6 +21,7 @@ import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.SessionAwareMethodInterceptor; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -132,6 +133,7 @@ public void destroy() throws Exception { } @Override + @Contract("_ -> new") public MongoDatabaseFactory withSession(ClientSession session) { return new MongoDatabaseFactorySupport.ClientSessionBoundMongoDbFactory(session, this); } 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 0e8bbb2ba3..6ec454cd93 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 @@ -650,6 +650,7 @@ public SessionScoped withSession(ClientSessionOptions options) { } @Override + @Contract("_ -> new") public MongoTemplate withSession(ClientSession session) { Assert.notNull(session, "ClientSession must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReplaceOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReplaceOptions.java index a2e2ba24c0..a487cde669 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReplaceOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReplaceOptions.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.lang.Contract; /** * Options for {@link org.springframework.data.mongodb.core.MongoOperations#replace(Query, Object) replace operations}. Defaults to @@ -69,6 +70,7 @@ public static ReplaceOptions none() { * * @return this. */ + @Contract("-> this") public ReplaceOptions upsert() { this.upsert = true; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ViewOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ViewOptions.java index a0f5e56034..b4b525fc97 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ViewOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ViewOptions.java @@ -19,6 +19,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Contract; /** * Immutable object holding additional options to be applied when creating a MongoDB @@ -59,6 +60,7 @@ public Optional getCollation() { * @param collation the {@link Collation} to use for language-specific string comparison. * @return new instance of {@link ViewOptions}. */ + @Contract("_ -> new") public ViewOptions collation(Collation collation) { return new ViewOptions(collation); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AccumulatorOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AccumulatorOperators.java index 9f8db95523..fa44656c99 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AccumulatorOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AccumulatorOperators.java @@ -23,6 +23,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -262,8 +263,8 @@ public ExpMovingAvg alpha(double exponentialDecayValue) { } /** - * Creates new {@link AggregationExpression} that calculates the requested percentile(s) of the - * associated numeric value expression. + * Creates new {@link AggregationExpression} that calculates the requested percentile(s) of the associated numeric + * value expression. * * @return new instance of {@link Percentile}. * @param percentages must not be {@literal null}. @@ -351,6 +352,7 @@ public static Sum sumOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Sum}. */ + @Contract("_ -> new") public static Sum sumOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -364,6 +366,7 @@ public static Sum sumOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Sum}. */ + @Contract("_ -> new") public Sum and(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -377,6 +380,7 @@ public Sum and(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Sum}. */ + @Contract("_ -> new") public Sum and(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -391,6 +395,7 @@ public Sum and(AggregationExpression expression) { * @return new instance of {@link Sum}. * @since 2.2 */ + @Contract("_ -> new") public Sum and(Number value) { Assert.notNull(value, "Value must not be null"); @@ -455,6 +460,7 @@ public static Avg avgOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Avg}. */ + @Contract("_ -> new") public Avg and(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -468,6 +474,7 @@ public Avg and(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Avg}. */ + @Contract("_ -> new") public Avg and(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -532,6 +539,7 @@ public static Max maxOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Max}. */ + @Contract("_ -> new") public Max and(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -545,6 +553,7 @@ public Max and(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Max}. */ + @Contract("_ -> new") public Max and(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -558,6 +567,7 @@ public Max and(AggregationExpression expression) { * @param numberOfResults * @return new instance of {@link Max}. */ + @Contract("_ -> new") public Max limit(int numberOfResults) { return new Max(append("n", numberOfResults)); } @@ -630,6 +640,7 @@ public static Min minOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Min}. */ + @Contract("_ -> new") public Min and(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -643,6 +654,7 @@ public Min and(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Min}. */ + @Contract("_ -> new") public Min and(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -656,6 +668,7 @@ public Min and(AggregationExpression expression) { * @param numberOfResults * @return new instance of {@link Min}. */ + @Contract("_ -> new") public Min limit(int numberOfResults) { return new Min(append("n", numberOfResults)); } @@ -728,6 +741,7 @@ public static StdDevPop stdDevPopOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link StdDevPop}. */ + @Contract("_ -> new") public StdDevPop and(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -741,6 +755,7 @@ public StdDevPop and(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link StdDevPop}. */ + @Contract("_ -> new") public StdDevPop and(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -805,6 +820,7 @@ public static StdDevSamp stdDevSampOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link StdDevSamp}. */ + @Contract("_ -> new") public StdDevSamp and(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -818,6 +834,7 @@ public StdDevSamp and(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link StdDevSamp}. */ + @Contract("_ -> new") public StdDevSamp and(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -875,6 +892,7 @@ public static CovariancePop covariancePopOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link CovariancePop}. */ + @Contract("_ -> new") public CovariancePop and(String fieldReference) { return new CovariancePop(append(asFields(fieldReference))); } @@ -885,6 +903,7 @@ public CovariancePop and(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link CovariancePop}. */ + @Contract("_ -> new") public CovariancePop and(AggregationExpression expression) { return new CovariancePop(append(expression)); } @@ -935,6 +954,7 @@ public static CovarianceSamp covarianceSampOf(AggregationExpression expression) * @param fieldReference must not be {@literal null}. * @return new instance of {@link CovarianceSamp}. */ + @Contract("_ -> new") public CovarianceSamp and(String fieldReference) { return new CovarianceSamp(append(asFields(fieldReference))); } @@ -945,6 +965,7 @@ public CovarianceSamp and(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link CovarianceSamp}. */ + @Contract("_ -> new") public CovarianceSamp and(AggregationExpression expression) { return new CovarianceSamp(append(expression)); } @@ -995,6 +1016,7 @@ public static ExpMovingAvg expMovingAvgOf(AggregationExpression expression) { * @param numberOfHistoricalDocuments * @return new instance of {@link ExpMovingAvg}. */ + @Contract("_ -> new") public ExpMovingAvg n/*umber of historical documents*/(int numberOfHistoricalDocuments) { return new ExpMovingAvg(append("N", numberOfHistoricalDocuments)); } @@ -1006,6 +1028,7 @@ public static ExpMovingAvg expMovingAvgOf(AggregationExpression expression) { * @param exponentialDecayValue * @return new instance of {@link ExpMovingAvg}. */ + @Contract("_ -> new") public ExpMovingAvg alpha(double exponentialDecayValue) { return new ExpMovingAvg(append("alpha", exponentialDecayValue)); } @@ -1064,6 +1087,7 @@ public static Percentile percentileOf(AggregationExpression expression) { * @param percentages must not be {@literal null}. * @return new instance of {@link Percentile}. */ + @Contract("_ -> new") public Percentile percentages(Double... percentages) { Assert.notEmpty(percentages, "Percentages must not be null or empty"); @@ -1077,6 +1101,7 @@ public Percentile percentages(Double... percentages) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Percentile}. */ + @Contract("_ -> new") public Percentile and(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1090,6 +1115,7 @@ public Percentile and(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Percentile}. */ + @Contract("_ -> new") public Percentile and(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1151,6 +1177,7 @@ public static Median medianOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Median}. */ + @Contract("_ -> new") public Median and(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1164,6 +1191,7 @@ public Median and(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Median}. */ + @Contract("_ -> new") public Median and(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java index a49971f8f7..e76ebb894d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java @@ -21,6 +21,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.AddFieldsOperation.AddFieldsOperationBuilder.ValueAppender; +import org.springframework.lang.Contract; /** * Adds new fields to documents. {@code $addFields} outputs documents that contain all existing fields from the input @@ -82,6 +83,7 @@ public static ValueAppender addField(String field) { * @param value the value to assign. * @return new instance of {@link AddFieldsOperation}. */ + @Contract("_ -> new") public AddFieldsOperation addField(Object field, Object value) { LinkedHashMap target = new LinkedHashMap<>(getValueMap()); @@ -95,6 +97,7 @@ public AddFieldsOperation addField(Object field, Object value) { * * @return new instance of {@link AddFieldsOperationBuilder}. */ + @Contract("-> new") public AddFieldsOperationBuilder and() { return new AddFieldsOperationBuilder(getValueMap()); } 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 a930b18244..278da408c6 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 @@ -24,6 +24,7 @@ import org.springframework.data.mongodb.core.ReadPreferenceAware; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.util.BsonUtils; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import com.mongodb.ReadConcern; @@ -444,6 +445,7 @@ public static class Builder { * @param allowDiskUse use {@literal true} to allow disk use during the aggregation. * @return this. */ + @Contract("_ -> this") public Builder allowDiskUse(boolean allowDiskUse) { this.allowDiskUse = allowDiskUse; @@ -456,6 +458,7 @@ public Builder allowDiskUse(boolean allowDiskUse) { * @param explain use {@literal true} to enable explain feature. * @return this. */ + @Contract("_ -> this") public Builder explain(boolean explain) { this.explain = explain; @@ -468,6 +471,7 @@ public Builder explain(boolean explain) { * @param cursor must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public Builder cursor(Document cursor) { this.cursor = cursor; @@ -481,6 +485,7 @@ public Builder cursor(Document cursor) { * @return this. * @since 2.0 */ + @Contract("_ -> this") public Builder cursorBatchSize(int batchSize) { this.cursor = createCursor(batchSize); @@ -494,6 +499,7 @@ public Builder cursorBatchSize(int batchSize) { * @return this. * @since 2.0 */ + @Contract("_ -> this") public Builder collation(@Nullable Collation collation) { this.collation = collation; @@ -507,6 +513,7 @@ public Builder collation(@Nullable Collation collation) { * @return this. * @since 2.2 */ + @Contract("_ -> this") public Builder comment(@Nullable String comment) { this.comment = comment; @@ -520,6 +527,7 @@ public Builder comment(@Nullable String comment) { * @return this. * @since 3.1 */ + @Contract("_ -> this") public Builder hint(@Nullable Document hint) { this.hint = hint; @@ -533,6 +541,7 @@ public Builder hint(@Nullable Document hint) { * @return this. * @since 4.1 */ + @Contract("_ -> this") public Builder hint(@Nullable String indexName) { this.hint = indexName; @@ -546,6 +555,7 @@ public Builder hint(@Nullable String indexName) { * @return this. * @since 4.1 */ + @Contract("_ -> this") public Builder readConcern(@Nullable ReadConcern readConcern) { this.readConcern = readConcern; @@ -559,6 +569,7 @@ public Builder readConcern(@Nullable ReadConcern readConcern) { * @return this. * @since 4.1 */ + @Contract("_ -> this") public Builder readPreference(@Nullable ReadPreference readPreference) { this.readPreference = readPreference; @@ -573,6 +584,7 @@ public Builder readPreference(@Nullable ReadPreference readPreference) { * @return this. * @since 3.0 */ + @Contract("_ -> this") public Builder maxTime(@Nullable Duration maxTime) { this.maxTime = maxTime; @@ -587,6 +599,7 @@ public Builder maxTime(@Nullable Duration maxTime) { * @return this. * @since 3.0.2 */ + @Contract("-> this") public Builder skipOutput() { this.resultOptions = ResultOptions.SKIP; @@ -600,6 +613,7 @@ public Builder skipOutput() { * @return this. * @since 3.2 */ + @Contract("-> this") public Builder strictMapping() { this.domainTypeMapping = DomainTypeMapping.STRICT; @@ -613,6 +627,7 @@ public Builder strictMapping() { * @return this. * @since 3.2 */ + @Contract("-> this") public Builder relaxedMapping() { this.domainTypeMapping = DomainTypeMapping.RELAXED; @@ -625,6 +640,7 @@ public Builder relaxedMapping() { * @return this. * @since 3.2 */ + @Contract("-> this") public Builder noMapping() { this.domainTypeMapping = DomainTypeMapping.NONE; @@ -636,6 +652,7 @@ public Builder noMapping() { * * @return new instance of {@link AggregationOptions}. */ + @Contract("-> new") public AggregationOptions build() { AggregationOptions options = new AggregationOptions(allowDiskUse, explain, cursor, collation, comment, hint); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationPipeline.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationPipeline.java index 68662ec0df..40966bcf3d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationPipeline.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationPipeline.java @@ -22,6 +22,7 @@ import java.util.function.Predicate; import org.bson.Document; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -63,6 +64,7 @@ public AggregationPipeline(List aggregationOperations) { * @param aggregationOperation must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public AggregationPipeline add(AggregationOperation aggregationOperation) { Assert.notNull(aggregationOperation, "AggregationOperation must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationUpdate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationUpdate.java index e3471178e6..9e8564c03e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationUpdate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationUpdate.java @@ -29,6 +29,7 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.SerializationUtils; import org.springframework.data.mongodb.core.query.UpdateDefinition; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -128,6 +129,7 @@ public static AggregationUpdate from(List pipeline) { * @return this. * @see $set Aggregation Reference */ + @Contract("_ -> this") public AggregationUpdate set(SetOperation setOperation) { Assert.notNull(setOperation, "SetOperation must not be null"); @@ -147,6 +149,7 @@ public AggregationUpdate set(SetOperation setOperation) { * @see $unset Aggregation * Reference */ + @Contract("_ -> this") public AggregationUpdate unset(UnsetOperation unsetOperation) { Assert.notNull(unsetOperation, "UnsetOperation must not be null"); @@ -165,6 +168,7 @@ public AggregationUpdate unset(UnsetOperation unsetOperation) { * @see $replaceWith Aggregation * Reference */ + @Contract("_ -> this") public AggregationUpdate replaceWith(ReplaceWithOperation replaceWithOperation) { Assert.notNull(replaceWithOperation, "ReplaceWithOperation must not be null"); @@ -178,6 +182,7 @@ public AggregationUpdate replaceWith(ReplaceWithOperation replaceWithOperation) * @param value must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public AggregationUpdate replaceWith(Object value) { Assert.notNull(value, "Value must not be null"); @@ -192,6 +197,7 @@ public AggregationUpdate replaceWith(Object value) { * @return new instance of {@link SetValueAppender}. * @see #set(SetOperation) */ + @Contract("_ -> new") public SetValueAppender set(String key) { Assert.notNull(key, "Key must not be null"); @@ -218,6 +224,7 @@ public AggregationUpdate toValueOf(Object value) { * @param keys the fields to remove. * @return this. */ + @Contract("_ -> this") public AggregationUpdate unset(String... keys) { Assert.notNull(keys, "Keys must not be null"); @@ -233,6 +240,7 @@ public AggregationUpdate unset(String... keys) { * * @return never {@literal null}. */ + @Contract("-> this") public AggregationUpdate isolated() { isolated = true; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java index b8350680c4..c7787b382c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java @@ -33,6 +33,7 @@ import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.Sum; import org.springframework.data.mongodb.core.aggregation.SetWindowFieldsOperation.WindowUnit; import org.springframework.data.mongodb.core.aggregation.SetWindowFieldsOperation.WindowUnits; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -975,8 +976,7 @@ public Tanh tanh(AngularUnit unit) { } /** - * Creates new {@link AggregationExpression} that calculates the requested percentile(s) of the - * numeric value. + * Creates new {@link AggregationExpression} that calculates the requested percentile(s) of the numeric value. * * @return new instance of {@link Percentile}. * @param percentages must not be {@literal null}. @@ -990,8 +990,7 @@ public Percentile percentile(Double... percentages) { } /** - * Creates new {@link AggregationExpression} that calculates the requested percentile(s) of the - * numeric value. + * Creates new {@link AggregationExpression} that calculates the requested percentile(s) of the numeric value. * * @return new instance of {@link Median}. * @since 4.2 @@ -1118,6 +1117,7 @@ public static Add valueOf(Number value) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Add}. */ + @Contract("_ -> new") public Add add(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1130,6 +1130,7 @@ public Add add(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Add}. */ + @Contract("_ -> new") public Add add(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1142,6 +1143,7 @@ public Add add(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Add}. */ + @Contract("_ -> new") public Add add(Number value) { return new Add(append(value)); } @@ -1258,6 +1260,7 @@ public static Divide valueOf(Number value) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Divide}. */ + @Contract("_ -> new") public Divide divideBy(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1270,6 +1273,7 @@ public Divide divideBy(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Divide}. */ + @Contract("_ -> new") public Divide divideBy(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1282,6 +1286,7 @@ public Divide divideBy(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Divide}. */ + @Contract("_ -> new") public Divide divideBy(Number value) { return new Divide(append(value)); } @@ -1504,6 +1509,7 @@ public static Log valueOf(Number value) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Log}. */ + @Contract("_ -> new") public Log log(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1516,6 +1522,7 @@ public Log log(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Log}. */ + @Contract("_ -> new") public Log log(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1528,6 +1535,7 @@ public Log log(AggregationExpression expression) { * @param base must not be {@literal null}. * @return new instance of {@link Log}. */ + @Contract("_ -> new") public Log log(Number base) { return new Log(append(base)); } @@ -1644,6 +1652,7 @@ public static Mod valueOf(Number value) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Mod}. */ + @Contract("_ -> new") public Mod mod(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1656,6 +1665,7 @@ public Mod mod(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Mod}. */ + @Contract("_ -> new") public Mod mod(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1668,6 +1678,7 @@ public Mod mod(AggregationExpression expression) { * @param base must not be {@literal null}. * @return new instance of {@link Mod}. */ + @Contract("_ -> new") public Mod mod(Number base) { return new Mod(append(base)); } @@ -1731,6 +1742,7 @@ public static Multiply valueOf(Number value) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Multiply}. */ + @Contract("_ -> new") public Multiply multiplyBy(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1743,6 +1755,7 @@ public Multiply multiplyBy(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Multiply}. */ + @Contract("_ -> new") public Multiply multiplyBy(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1755,6 +1768,7 @@ public Multiply multiplyBy(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Multiply}. */ + @Contract("_ -> new") public Multiply multiplyBy(Number value) { return new Multiply(append(value)); } @@ -1818,6 +1832,7 @@ public static Pow valueOf(Number value) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Pow}. */ + @Contract("_ -> new") public Pow pow(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1830,6 +1845,7 @@ public Pow pow(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Pow}. */ + @Contract("_ -> new") public Pow pow(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1842,6 +1858,7 @@ public Pow pow(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Pow}. */ + @Contract("_ -> new") public Pow pow(Number value) { return new Pow(append(value)); } @@ -1958,6 +1975,7 @@ public static Subtract valueOf(Number value) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Pow}. */ + @Contract("_ -> new") public Subtract subtract(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1970,6 +1988,7 @@ public Subtract subtract(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Pow}. */ + @Contract("_ -> new") public Subtract subtract(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1982,6 +2001,7 @@ public Subtract subtract(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Pow}. */ + @Contract("_ -> new") public Subtract subtract(Number value) { return new Subtract(append(value)); } @@ -2101,6 +2121,7 @@ public static Round round(Number value) { * @param place value between -20 and 100, exclusive. * @return new instance of {@link Round}. */ + @Contract("_ -> new") public Round place(int place) { return new Round(append(place)); } @@ -2111,6 +2132,7 @@ public Round place(int place) { * @param expression must not be {@literal null}. * @return new instance of {@link Round}. */ + @Contract("_ -> new") public Round placeOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -2124,6 +2146,7 @@ public Round placeOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Round}. */ + @Contract("_ -> new") public Round placeOf(String fieldReference) { Assert.notNull(fieldReference, "fieldReference must not be null"); @@ -2174,6 +2197,7 @@ public static Derivative derivativeOfValue(Number value) { return new Derivative(Collections.singletonMap("input", value)); } + @Contract("_ -> new") public Derivative unit(String unit) { return new Derivative(append("unit", unit)); } @@ -2224,6 +2248,7 @@ public static Integral integralOf(AggregationExpression expression) { * @param unit the unit of measure. * @return new instance of {@link Integral}. */ + @Contract("_ -> new") public Integral unit(String unit) { return new Integral(append("unit", unit)); } @@ -2258,8 +2283,7 @@ private Sin(Object value) { /** * Creates a new {@link AggregationExpression} that calculates the sine of a value that is measured in - * {@link AngularUnit#RADIANS radians}. - *
+ * {@link AngularUnit#RADIANS radians}.
* Use {@code sinhOf("angle", DEGREES)} as shortcut for * *
@@ -2371,8 +2395,7 @@ public static Sinh sinhOf(String fieldReference) {
 
 		/**
 		 * Creates a new {@link AggregationExpression} that calculates the hyperbolic sine of a value that is measured in
-		 * the given {@link AngularUnit unit}.
-		 * 
+ * the given {@link AngularUnit unit}.
* Use {@code sinhOf("angle", DEGREES)} as shortcut for * *
@@ -2391,8 +2414,7 @@ public static Sinh sinhOf(String fieldReference, AngularUnit unit) {
 
 		/**
 		 * Creates a new {@link AggregationExpression} that calculates the hyperbolic sine of a value that is measured in
-		 * {@link AngularUnit#RADIANS}.
-		 * 
+ * {@link AngularUnit#RADIANS}.
* Use {@code sinhOf("angle", DEGREES)} as shortcut for eg. * {@code sinhOf(ConvertOperators.valueOf("angle").degreesToRadians())}. * @@ -2475,8 +2497,7 @@ public static ASin asinOf(String fieldReference) { } /** - * Creates a new {@link AggregationExpression} that calculates the inverse sine of a value. - *
+ * Creates a new {@link AggregationExpression} that calculates the inverse sine of a value.
* * @param expression the {@link AggregationExpression expression} that resolves to a numeric value. * @return new instance of {@link ASin}. @@ -2525,8 +2546,7 @@ public static ASinh asinhOf(String fieldReference) { } /** - * Creates a new {@link AggregationExpression} that calculates the inverse hyperbolic sine of a value. - *
+ * Creates a new {@link AggregationExpression} that calculates the inverse hyperbolic sine of a value.
* * @param expression the {@link AggregationExpression expression} that resolves to a numeric value. * @return new instance of {@link ASinh}. @@ -2566,8 +2586,7 @@ private Cos(Object value) { /** * Creates a new {@link AggregationExpression} that calculates the cosine of a value that is measured in - * {@link AngularUnit#RADIANS radians}. - *
+ * {@link AngularUnit#RADIANS radians}.
* Use {@code cosOf("angle", DEGREES)} as shortcut for * *
@@ -2677,8 +2696,7 @@ public static Cosh coshOf(String fieldReference) {
 
 		/**
 		 * Creates a new {@link AggregationExpression} that calculates the hyperbolic cosine of a value that is measured in
-		 * the given {@link AngularUnit unit}.
-		 * 
+ * the given {@link AngularUnit unit}.
* Use {@code coshOf("angle", DEGREES)} as shortcut for * *
@@ -2695,8 +2713,7 @@ public static Cosh coshOf(String fieldReference, AngularUnit unit) {
 
 		/**
 		 * Creates a new {@link AggregationExpression} that calculates the hyperbolic cosine of a value that is measured in
-		 * {@link AngularUnit#RADIANS}.
-		 * 
+ * {@link AngularUnit#RADIANS}.
* Use {@code sinhOf("angle", DEGREES)} as shortcut for eg. * {@code sinhOf(ConvertOperators.valueOf("angle").degreesToRadians())}. * @@ -2779,8 +2796,7 @@ public static ACos acosOf(String fieldReference) { } /** - * Creates a new {@link AggregationExpression} that calculates the inverse cosine of a value. - *
+ * Creates a new {@link AggregationExpression} that calculates the inverse cosine of a value.
* * @param expression the {@link AggregationExpression expression} that resolves to a numeric value. * @return new instance of {@link ACos}. @@ -2829,8 +2845,7 @@ public static ACosh acoshOf(String fieldReference) { } /** - * Creates a new {@link AggregationExpression} that calculates the inverse hyperbolic cosine of a value. - *
+ * Creates a new {@link AggregationExpression} that calculates the inverse hyperbolic cosine of a value.
* * @param expression the {@link AggregationExpression expression} that resolves to a numeric value. * @return new instance of {@link ACosh}. @@ -2870,8 +2885,7 @@ private Tan(Object value) { /** * Creates a new {@link AggregationExpression} that calculates the tangent of a value that is measured in - * {@link AngularUnit#RADIANS radians}. - *
+ * {@link AngularUnit#RADIANS radians}.
* Use {@code tanOf("angle", DEGREES)} as shortcut for * *
@@ -3049,8 +3063,8 @@ public static ATan2 valueOf(AggregationExpression expression) {
 		 * Creates a new {@link AggregationExpression} that calculates the inverse tangent of of y / x, where y and x are
 		 * the first and second values passed to the expression respectively.
 		 *
-		 * @param fieldReference anything ({@link Field field}, {@link AggregationExpression expression}, ...) that resolves to a
-		 *          numeric value.
+		 * @param fieldReference anything ({@link Field field}, {@link AggregationExpression expression}, ...) that resolves
+		 *          to a numeric value.
 		 * @return new instance of {@link ATan2}.
 		 */
 		public ATan2 atan2of(String fieldReference) {
@@ -3063,8 +3077,8 @@ public ATan2 atan2of(String fieldReference) {
 		 * Creates a new {@link AggregationExpression} that calculates the hyperbolic tangent of a value that is measured in
 		 * {@link AngularUnit#RADIANS}.
 		 *
-		 * @param expression anything ({@link Field field}, {@link AggregationExpression expression}, ...) that resolves to a
-		 *          numeric value.
+		 * @param expression anything ({@link Field field}, {@link AggregationExpression expression}, ...) that resolves to
+		 *          a numeric value.
 		 * @return new instance of {@link ATan2}.
 		 */
 		public ATan2 atan2of(AggregationExpression expression) {
@@ -3116,8 +3130,7 @@ public static Tanh tanhOf(String fieldReference) {
 
 		/**
 		 * Creates a new {@link AggregationExpression} that calculates the hyperbolic tangent of a value that is measured in
-		 * the given {@link AngularUnit unit}.
-		 * 
+ * the given {@link AngularUnit unit}.
* Use {@code tanhOf("angle", DEGREES)} as shortcut for * *
@@ -3134,8 +3147,7 @@ public static Tanh tanhOf(String fieldReference, AngularUnit unit) {
 
 		/**
 		 * Creates a new {@link AggregationExpression} that calculates the hyperbolic tangent of a value that is measured in
-		 * {@link AngularUnit#RADIANS}.
-		 * 
+ * {@link AngularUnit#RADIANS}.
* Use {@code sinhOf("angle", DEGREES)} as shortcut for eg. * {@code sinhOf(ConvertOperators.valueOf("angle").degreesToRadians())}. * @@ -3206,11 +3218,9 @@ private ATanh(Object value) { } /** - * Creates a new {@link AggregationExpression} that calculates the inverse - * hyperbolic tangent of a value. + * Creates a new {@link AggregationExpression} that calculates the inverse hyperbolic tangent of a value. * - * @param fieldReference the name of the {@link Field field} that resolves to a - * numeric value. + * @param fieldReference the name of the {@link Field field} that resolves to a numeric value. * @return new instance of {@link ATanh}. */ public static ATanh atanhOf(String fieldReference) { @@ -3218,8 +3228,7 @@ public static ATanh atanhOf(String fieldReference) { } /** - * Creates a new {@link AggregationExpression} that calculates the inverse hyperbolic tangent of a value. - *
+ * Creates a new {@link AggregationExpression} that calculates the inverse hyperbolic tangent of a value.
* * @param expression the {@link AggregationExpression expression} that resolves to a numeric value. * @return new instance of {@link ATanh}. @@ -3229,11 +3238,10 @@ public static ATanh atanhOf(AggregationExpression expression) { } /** - * Creates a new {@link AggregationExpression} that calculates the inverse - * hyperbolic tangent of a value. + * Creates a new {@link AggregationExpression} that calculates the inverse hyperbolic tangent of a value. * - * @param value anything ({@link Field field}, {@link AggregationExpression - * expression}, ...) that resolves to a numeric value. + * @param value anything ({@link Field field}, {@link AggregationExpression expression}, ...) that resolves to a + * numeric value. * @return new instance of {@link ATanh}. */ public static ATanh atanhOf(Object value) { 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 fecd42d7e5..7770728fe3 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 @@ -28,6 +28,7 @@ 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.Contract; import org.springframework.util.Assert; /** @@ -522,6 +523,7 @@ public static ArrayElemAt arrayOf(Collection values) { * @param index the index number * @return new instance of {@link ArrayElemAt}. */ + @Contract("_ -> new") public ArrayElemAt elementAt(int index) { return new ArrayElemAt(append(index)); } @@ -532,6 +534,7 @@ public ArrayElemAt elementAt(int index) { * @param expression must not be {@literal null}. * @return new instance of {@link ArrayElemAt}. */ + @Contract("_ -> new") public ArrayElemAt elementAt(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -544,6 +547,7 @@ public ArrayElemAt elementAt(AggregationExpression expression) { * @param arrayFieldReference the field name. * @return new instance of {@link ArrayElemAt}. */ + @Contract("_ -> new") public ArrayElemAt elementAt(String arrayFieldReference) { Assert.notNull(arrayFieldReference, "ArrayReference must not be null"); @@ -610,6 +614,7 @@ public static ConcatArrays arrayOf(Collection values) { * @param arrayFieldReference must not be {@literal null}. * @return new instance of {@link ConcatArrays}. */ + @Contract("_ -> new") public ConcatArrays concat(String arrayFieldReference) { Assert.notNull(arrayFieldReference, "ArrayFieldReference must not be null"); @@ -622,6 +627,7 @@ public ConcatArrays concat(String arrayFieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link ConcatArrays}. */ + @Contract("_ -> new") public ConcatArrays concat(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -711,7 +717,6 @@ private Document toFilter(ExposedFields exposedFields, AggregationOperationConte filterExpression.putAll(context.getMappedObject(new Document("input", getMappedInput(context)))); filterExpression.put("as", as.getTarget()); - filterExpression.putAll(context.getMappedObject(new Document("cond", getMappedCondition(operationContext)))); return new Document("$filter", filterExpression); @@ -837,6 +842,7 @@ public static InputBuilder newBuilder() { } @Override + @Contract("_ -> this") public AsBuilder filter(List array) { Assert.notNull(array, "Array must not be null"); @@ -845,6 +851,7 @@ public AsBuilder filter(List array) { } @Override + @Contract("_ -> this") public AsBuilder filter(Field field) { Assert.notNull(field, "Field must not be null"); @@ -853,6 +860,7 @@ public AsBuilder filter(Field field) { } @Override + @Contract("_ -> this") public AsBuilder filter(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -861,6 +869,7 @@ public AsBuilder filter(AggregationExpression expression) { } @Override + @Contract("_ -> this") public ConditionBuilder as(String variableName) { Assert.notNull(variableName, "Variable name must not be null"); @@ -1048,6 +1057,7 @@ public static Slice sliceArrayOf(Collection values) { * @param count number of elements to slice. * @return new instance of {@link Slice}. */ + @Contract("_ -> new") public Slice itemCount(int count) { return new Slice(append(count)); } @@ -1060,6 +1070,7 @@ public Slice itemCount(int count) { * @return new instance of {@link Slice}. * @since 4.5 */ + @Contract("_ -> new") public Slice itemCount(AggregationExpression count) { return new Slice(append(count)); } @@ -1178,6 +1189,7 @@ public static IndexOfArrayBuilder arrayOf(Collection values) { * @param range the lookup range. * @return new instance of {@link IndexOfArray}. */ + @Contract("_ -> new") public IndexOfArray within(Range range) { return new IndexOfArray(append(AggregationUtils.toRangeValues(range))); } @@ -1253,6 +1265,7 @@ public static RangeOperatorBuilder rangeStartingAt(long value) { return new RangeOperatorBuilder(value); } + @Contract("_ -> new") public RangeOperator withStepSize(long stepSize) { return new RangeOperator(append(stepSize)); } @@ -1705,6 +1718,7 @@ public static ZipBuilder arrayOf(Collection values) { * * @return new instance of {@link Zip}. */ + @Contract("-> new") public Zip useLongestLength() { return new Zip(append("useLongestLength", true)); } @@ -1715,6 +1729,7 @@ public Zip useLongestLength() { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Zip}. */ + @Contract("_ -> new") public Zip defaultTo(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1727,6 +1742,7 @@ public Zip defaultTo(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Zip}. */ + @Contract("_ -> new") public Zip defaultTo(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1739,6 +1755,7 @@ public Zip defaultTo(AggregationExpression expression) { * @param array must not be {@literal null}. * @return new instance of {@link Zip}. */ + @Contract("_ -> new") public Zip defaultTo(Object[] array) { Assert.notNull(array, "Array must not be null"); @@ -2076,6 +2093,7 @@ public static SortArray sortArrayOf(AggregationExpression expression) { * @param sort must not be {@literal null}. * @return new instance of {@link SortArray}. */ + @Contract("_ -> new") public SortArray by(Sort sort) { return new SortArray(append("sortBy", sort)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BooleanOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BooleanOperators.java index ee4b4ff5ba..f3ffdb7ad1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BooleanOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BooleanOperators.java @@ -20,6 +20,7 @@ import java.util.List; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -215,6 +216,7 @@ public static And and(Object... expressions) { * @param expression must not be {@literal null}. * @return new instance of {@link And}. */ + @Contract("_ -> new") public And andExpression(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -227,6 +229,7 @@ public And andExpression(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link And}. */ + @Contract("_ -> new") public And andField(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -239,6 +242,7 @@ public And andField(String fieldReference) { * @param value must not be {@literal null}. * @return new instance of {@link And}. */ + @Contract("_ -> new") public And andValue(Object value) { Assert.notNull(value, "Value must not be null"); @@ -281,6 +285,7 @@ public static Or or(Object... expressions) { * @param expression must not be {@literal null}. * @return new instance of {@link Or}. */ + @Contract("_ -> new") public Or orExpression(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -293,6 +298,7 @@ public Or orExpression(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Or}. */ + @Contract("_ -> new") public Or orField(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -305,6 +311,7 @@ public Or orField(String fieldReference) { * @param value must not be {@literal null}. * @return new instance of {@link Or}. */ + @Contract("_ -> new") public Or orValue(Object value) { Assert.notNull(value, "Value must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketOperation.java index 6fb6f78e5d..6ed686c086 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/BucketOperation.java @@ -23,6 +23,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.BucketOperation.BucketOperationOutputBuilder; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -112,6 +113,7 @@ public String getOperator() { * @param literal must not be {@literal null}. * @return new instance of {@link BucketOperation}. */ + @Contract("_ -> new") public BucketOperation withDefaultBucket(Object literal) { Assert.notNull(literal, "Default bucket literal must not be null"); @@ -125,6 +127,7 @@ public BucketOperation withDefaultBucket(Object literal) { * @param boundaries must not be {@literal null}. * @return new instance of {@link BucketOperation}. */ + @Contract("_ -> new") public BucketOperation withBoundaries(Object... boundaries) { Assert.notNull(boundaries, "Boundaries must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ComparisonOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ComparisonOperators.java index 9acfac14bb..e2626c3a16 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ComparisonOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ComparisonOperators.java @@ -19,6 +19,7 @@ import java.util.List; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -392,6 +393,7 @@ public static Cmp valueOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Cmp}. */ + @Contract("_ -> new") public Cmp compareTo(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -404,6 +406,7 @@ public Cmp compareTo(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Cmp}. */ + @Contract("_ -> new") public Cmp compareTo(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -416,6 +419,7 @@ public Cmp compareTo(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Cmp}. */ + @Contract("_ -> new") public Cmp compareToValue(Object value) { Assert.notNull(value, "Value must not be null"); @@ -469,6 +473,7 @@ public static Eq valueOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Eq}. */ + @Contract("_ -> new") public Eq equalTo(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -481,6 +486,7 @@ public Eq equalTo(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Eq}. */ + @Contract("_ -> new") public Eq equalTo(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -493,6 +499,7 @@ public Eq equalTo(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Eq}. */ + @Contract("_ -> new") public Eq equalToValue(Object value) { Assert.notNull(value, "Value must not be null"); @@ -546,6 +553,7 @@ public static Gt valueOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Gt}. */ + @Contract("_ -> new") public Gt greaterThan(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -558,6 +566,7 @@ public Gt greaterThan(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Gt}. */ + @Contract("_ -> new") public Gt greaterThan(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -570,6 +579,7 @@ public Gt greaterThan(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Gt}. */ + @Contract("_ -> new") public Gt greaterThanValue(Object value) { Assert.notNull(value, "Value must not be null"); @@ -623,6 +633,7 @@ public static Lt valueOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Lt}. */ + @Contract("_ -> new") public Lt lessThan(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -635,6 +646,7 @@ public Lt lessThan(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Lt}. */ + @Contract("_ -> new") public Lt lessThan(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -647,6 +659,7 @@ public Lt lessThan(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Lt}. */ + @Contract("_ -> new") public Lt lessThanValue(Object value) { Assert.notNull(value, "Value must not be null"); @@ -700,6 +713,7 @@ public static Gte valueOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Gte}. */ + @Contract("_ -> new") public Gte greaterThanEqualTo(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -712,6 +726,7 @@ public Gte greaterThanEqualTo(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Gte}. */ + @Contract("_ -> new") public Gte greaterThanEqualTo(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -724,6 +739,7 @@ public Gte greaterThanEqualTo(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Gte}. */ + @Contract("_ -> new") public Gte greaterThanEqualToValue(Object value) { Assert.notNull(value, "Value must not be null"); @@ -777,6 +793,7 @@ public static Lte valueOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Lte}. */ + @Contract("_ -> new") public Lte lessThanEqualTo(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -789,6 +806,7 @@ public Lte lessThanEqualTo(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Lte}. */ + @Contract("_ -> new") public Lte lessThanEqualTo(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -801,6 +819,7 @@ public Lte lessThanEqualTo(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Lte}. */ + @Contract("_ -> new") public Lte lessThanEqualToValue(Object value) { Assert.notNull(value, "Value must not be null"); @@ -854,6 +873,7 @@ public static Ne valueOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Ne}. */ + @Contract("_ -> new") public Ne notEqualTo(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -866,6 +886,7 @@ public Ne notEqualTo(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Ne}. */ + @Contract("_ -> new") public Ne notEqualTo(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -878,6 +899,7 @@ public Ne notEqualTo(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Ne}. */ + @Contract("_ -> new") public Ne notEqualToValue(Object value) { Assert.notNull(value, "Value must not be null"); 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 5a7a02f47e..462d94d6f1 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 @@ -28,6 +28,7 @@ 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.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -406,6 +407,7 @@ public static IfNullOperatorBuilder newBuilder() { return new IfNullOperatorBuilder(); } + @Contract("_ -> this") public ThenBuilder ifNull(String fieldReference) { Assert.hasText(fieldReference, "FieldReference name must not be null or empty"); @@ -414,6 +416,7 @@ public ThenBuilder ifNull(String fieldReference) { } @Override + @Contract("_ -> this") public ThenBuilder ifNull(AggregationExpression expression) { Assert.notNull(expression, "AggregationExpression name must not be null or empty"); @@ -422,25 +425,30 @@ public ThenBuilder ifNull(AggregationExpression expression) { } @Override + @Contract("_ -> this") public ThenBuilder orIfNull(String fieldReference) { return ifNull(fieldReference); } @Override + @Contract("_ -> this") public ThenBuilder orIfNull(AggregationExpression expression) { return ifNull(expression); } + @Contract("_ -> new") public IfNull then(Object value) { return new IfNull(conditions, value); } + @Contract("_ -> new") public IfNull thenValueOf(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); return new IfNull(conditions, Fields.field(fieldReference)); } + @Contract("_ -> new") public IfNull thenValueOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -493,6 +501,7 @@ public static Switch switchCases(List conditions) { * @param value must not be {@literal null}. * @return new instance of {@link Switch}. */ + @Contract("_ -> new") public Switch defaultTo(Object value) { return new Switch(append("default", value)); } @@ -889,6 +898,7 @@ public static ConditionalExpressionBuilder newBuilder() { } @Override + @Contract("_ -> this") public ConditionalExpressionBuilder when(Document booleanExpression) { Assert.notNull(booleanExpression, "'Boolean expression' must not be null"); @@ -898,6 +908,7 @@ public ConditionalExpressionBuilder when(Document booleanExpression) { } @Override + @Contract("_ -> this") public ThenBuilder when(CriteriaDefinition criteria) { Assert.notNull(criteria, "Criteria must not be null"); @@ -906,6 +917,7 @@ public ThenBuilder when(CriteriaDefinition criteria) { } @Override + @Contract("_ -> this") public ThenBuilder when(AggregationExpression expression) { Assert.notNull(expression, "AggregationExpression field must not be null"); @@ -914,6 +926,7 @@ public ThenBuilder when(AggregationExpression expression) { } @Override + @Contract("_ -> this") public ThenBuilder when(String booleanField) { Assert.hasText(booleanField, "Boolean field name must not be null or empty"); @@ -922,6 +935,7 @@ public ThenBuilder when(String booleanField) { } @Override + @Contract("_ -> this") public OtherwiseBuilder then(Object thenValue) { Assert.notNull(thenValue, "Then-value must not be null"); @@ -930,6 +944,7 @@ public OtherwiseBuilder then(Object thenValue) { } @Override + @Contract("_ -> this") public OtherwiseBuilder thenValueOf(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -938,6 +953,7 @@ public OtherwiseBuilder thenValueOf(String fieldReference) { } @Override + @Contract("_ -> this") public OtherwiseBuilder thenValueOf(AggregationExpression expression) { Assert.notNull(expression, "AggregationExpression must not be null"); @@ -946,6 +962,7 @@ public OtherwiseBuilder thenValueOf(AggregationExpression expression) { } @Override + @Contract("_ -> new") public Cond otherwise(Object otherwiseValue) { Assert.notNull(otherwiseValue, "Value must not be null"); @@ -955,6 +972,7 @@ public Cond otherwise(Object otherwiseValue) { } @Override + @Contract("_ -> new") public Cond otherwiseValueOf(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -964,6 +982,7 @@ public Cond otherwiseValueOf(String fieldReference) { } @Override + @Contract("_ -> new") public Cond otherwiseValueOf(AggregationExpression expression) { Assert.notNull(expression, "AggregationExpression must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java index 6ee59a9bca..7bf8a231ff 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java @@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -1077,6 +1078,7 @@ public static DayOfYear dayOfYear(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public DayOfYear withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -1149,6 +1151,7 @@ public static DayOfMonth dayOfMonth(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public DayOfMonth withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -1221,6 +1224,7 @@ public static DayOfWeek dayOfWeek(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public DayOfWeek withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -1293,6 +1297,7 @@ public static Year yearOf(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public Year withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -1365,6 +1370,7 @@ public static Month monthOf(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public Month withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -1437,6 +1443,7 @@ public static Week weekOf(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public Week withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -1509,6 +1516,7 @@ public static Hour hourOf(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public Hour withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -1581,6 +1589,7 @@ public static Minute minuteOf(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public Minute withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -1653,6 +1662,7 @@ public static Second secondOf(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public Second withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -1725,6 +1735,7 @@ public static Millisecond millisecondOf(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public Millisecond withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -1811,6 +1822,7 @@ public static FormatBuilder dateOf(final AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public DateToString withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -1825,6 +1837,7 @@ public DateToString withTimezone(Timezone timezone) { * @return new instance of {@link DateToString}. * @since 2.1 */ + @Contract("_ -> new") public DateToString onNullReturn(Object value) { return new DateToString(append("onNull", value)); } @@ -1837,6 +1850,7 @@ public DateToString onNullReturn(Object value) { * @return new instance of {@link DateToString}. * @since 2.1 */ + @Contract("_ -> new") public DateToString onNullReturnValueOf(String fieldReference) { return onNullReturn(Fields.field(fieldReference)); } @@ -1849,6 +1863,7 @@ public DateToString onNullReturnValueOf(String fieldReference) { * @return new instance of {@link DateToString}. * @since 2.1 */ + @Contract("_ -> new") public DateToString onNullReturnValueOf(AggregationExpression expression) { return onNullReturn(expression); } @@ -1974,6 +1989,7 @@ public static IsoDayOfWeek isoDayOfWeek(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public IsoDayOfWeek withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -2046,6 +2062,7 @@ public static IsoWeek isoWeekOf(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public IsoWeek withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -2118,6 +2135,7 @@ public static IsoWeekYear isoWeekYearOf(AggregationExpression expression) { * @since 2.1 */ @Override + @Contract("_ -> new") public IsoWeekYear withTimezone(Timezone timezone) { Assert.notNull(timezone, "Timezone must not be null"); @@ -2302,6 +2320,7 @@ public static DateFromPartsWithYear dateFromParts() { * @return new instance. * @throws IllegalArgumentException if given {@literal month} is {@literal null}. */ + @Contract("_ -> new") public DateFromParts month(Object month) { return new DateFromParts(append("month", month)); } @@ -2313,6 +2332,7 @@ public DateFromParts month(Object month) { * @return new instance. * @throws IllegalArgumentException if given {@literal fieldReference} is {@literal null}. */ + @Contract("_ -> new") public DateFromParts monthOf(String fieldReference) { return month(Fields.field(fieldReference)); } @@ -2324,6 +2344,7 @@ public DateFromParts monthOf(String fieldReference) { * @return new instance. * @throws IllegalArgumentException if given {@literal expression} is {@literal null}. */ + @Contract("_ -> new") public DateFromParts monthOf(AggregationExpression expression) { return month(expression); } @@ -2336,6 +2357,7 @@ public DateFromParts monthOf(AggregationExpression expression) { * @return new instance. * @throws IllegalArgumentException if given {@literal day} is {@literal null}. */ + @Contract("_ -> new") public DateFromParts day(Object day) { return new DateFromParts(append("day", day)); } @@ -2347,6 +2369,7 @@ public DateFromParts day(Object day) { * @return new instance. * @throws IllegalArgumentException if given {@literal fieldReference} is {@literal null}. */ + @Contract("_ -> new") public DateFromParts dayOf(String fieldReference) { return day(Fields.field(fieldReference)); } @@ -2358,26 +2381,31 @@ public DateFromParts dayOf(String fieldReference) { * @return new instance. * @throws IllegalArgumentException if given {@literal expression} is {@literal null}. */ + @Contract("_ -> new") public DateFromParts dayOf(AggregationExpression expression) { return day(expression); } @Override + @Contract("_ -> new") public DateFromParts hour(Object hour) { return new DateFromParts(append("hour", hour)); } @Override + @Contract("_ -> new") public DateFromParts minute(Object minute) { return new DateFromParts(append("minute", minute)); } @Override + @Contract("_ -> new") public DateFromParts second(Object second) { return new DateFromParts(append("second", second)); } @Override + @Contract("_ -> new") public DateFromParts millisecond(Object millisecond) { return new DateFromParts(append("millisecond", millisecond)); } @@ -2391,6 +2419,7 @@ public DateFromParts millisecond(Object millisecond) { * @throws IllegalArgumentException if given {@literal timezone} is {@literal null}. */ @Override + @Contract("_ -> new") public DateFromParts withTimezone(Timezone timezone) { return new DateFromParts(appendTimezone(argumentMap(), timezone)); } @@ -2478,6 +2507,7 @@ public static IsoDateFromPartsWithYear dateFromParts() { * @return new instance. * @throws IllegalArgumentException if given {@literal isoWeek} is {@literal null}. */ + @Contract("_ -> new") public IsoDateFromParts isoWeek(Object isoWeek) { return new IsoDateFromParts(append("isoWeek", isoWeek)); } @@ -2489,6 +2519,7 @@ public IsoDateFromParts isoWeek(Object isoWeek) { * @return new instance. * @throws IllegalArgumentException if given {@literal fieldReference} is {@literal null}. */ + @Contract("_ -> new") public IsoDateFromParts isoWeekOf(String fieldReference) { return isoWeek(Fields.field(fieldReference)); } @@ -2500,6 +2531,7 @@ public IsoDateFromParts isoWeekOf(String fieldReference) { * @return new instance. * @throws IllegalArgumentException if given {@literal expression} is {@literal null}. */ + @Contract("_ -> new") public IsoDateFromParts isoWeekOf(AggregationExpression expression) { return isoWeek(expression); } @@ -2512,6 +2544,7 @@ public IsoDateFromParts isoWeekOf(AggregationExpression expression) { * @return new instance. * @throws IllegalArgumentException if given {@literal isoWeek} is {@literal null}. */ + @Contract("_ -> new") public IsoDateFromParts isoDayOfWeek(Object day) { return new IsoDateFromParts(append("isoDayOfWeek", day)); } @@ -2523,6 +2556,7 @@ public IsoDateFromParts isoDayOfWeek(Object day) { * @return new instance. * @throws IllegalArgumentException if given {@literal fieldReference} is {@literal null}. */ + @Contract("_ -> new") public IsoDateFromParts isoDayOfWeekOf(String fieldReference) { return isoDayOfWeek(Fields.field(fieldReference)); } @@ -2534,26 +2568,31 @@ public IsoDateFromParts isoDayOfWeekOf(String fieldReference) { * @return new instance. * @throws IllegalArgumentException if given {@literal expression} is {@literal null}. */ + @Contract("_ -> new") public IsoDateFromParts isoDayOfWeekOf(AggregationExpression expression) { return isoDayOfWeek(expression); } @Override + @Contract("_ -> new") public IsoDateFromParts hour(Object hour) { return new IsoDateFromParts(append("hour", hour)); } @Override + @Contract("_ -> new") public IsoDateFromParts minute(Object minute) { return new IsoDateFromParts(append("minute", minute)); } @Override + @Contract("_ -> new") public IsoDateFromParts second(Object second) { return new IsoDateFromParts(append("second", second)); } @Override + @Contract("_ -> new") public IsoDateFromParts millisecond(Object millisecond) { return new IsoDateFromParts(append("millisecond", millisecond)); } @@ -2567,6 +2606,7 @@ public IsoDateFromParts millisecond(Object millisecond) { * @throws IllegalArgumentException if given {@literal timezone} is {@literal null}. */ @Override + @Contract("_ -> new") public IsoDateFromParts withTimezone(Timezone timezone) { return new IsoDateFromParts(appendTimezone(argumentMap(), timezone)); } @@ -2677,6 +2717,7 @@ public static DateToParts datePartsOf(AggregationExpression expression) { * * @return new instance of {@link DateToParts}. */ + @Contract("_ -> new") public DateToParts iso8601() { return new DateToParts(append("iso8601", true)); } @@ -2690,6 +2731,7 @@ public DateToParts iso8601() { * @throws IllegalArgumentException if given {@literal timezone} is {@literal null}. */ @Override + @Contract("_ -> new") public DateToParts withTimezone(Timezone timezone) { return new DateToParts(appendTimezone(argumentMap(), timezone)); } @@ -2734,6 +2776,7 @@ public static DateFromString fromString(Object value) { * @return new instance of {@link DateFromString}. * @throws IllegalArgumentException if given {@literal fieldReference} is {@literal null}. */ + @Contract("_ -> new") public static DateFromString fromStringOf(String fieldReference) { return fromString(Fields.field(fieldReference)); } @@ -2745,6 +2788,7 @@ public static DateFromString fromStringOf(String fieldReference) { * @return new instance of {@link DateFromString}. * @throws IllegalArgumentException if given {@literal expression} is {@literal null}. */ + @Contract("_ -> new") public static DateFromString fromStringOf(AggregationExpression expression) { return fromString(expression); } @@ -2758,6 +2802,7 @@ public static DateFromString fromStringOf(AggregationExpression expression) { * @throws IllegalArgumentException if given {@literal timezone} is {@literal null}. */ @Override + @Contract("_ -> new") public DateFromString withTimezone(Timezone timezone) { return new DateFromString(appendTimezone(argumentMap(), timezone)); } @@ -2770,6 +2815,7 @@ public DateFromString withTimezone(Timezone timezone) { * @return new instance of {@link DateFromString}. * @throws IllegalArgumentException if given {@literal format} is {@literal null}. */ + @Contract("_ -> new") public DateFromString withFormat(String format) { Assert.notNull(format, "Format must not be null"); @@ -2839,6 +2885,7 @@ public static DateAdd addValue(Object value, String unit) { * @param expression must not be {@literal null}. * @return new instance of {@link DateAdd}. */ + @Contract("_ -> new") public DateAdd toDateOf(AggregationExpression expression) { return toDate(expression); } @@ -2849,6 +2896,7 @@ public DateAdd toDateOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link DateAdd}. */ + @Contract("_ -> new") public DateAdd toDateOf(String fieldReference) { return toDate(Fields.field(fieldReference)); } @@ -2859,6 +2907,7 @@ public DateAdd toDateOf(String fieldReference) { * @param dateExpression anything that evaluates to a valid date. Must not be {@literal null}. * @return new instance of {@link DateAdd}. */ + @Contract("_ -> new") public DateAdd toDate(Object dateExpression) { return new DateAdd(append("startDate", dateExpression)); } @@ -2869,6 +2918,7 @@ public DateAdd toDate(Object dateExpression) { * @param timezone must not be {@literal null}. Consider {@link Timezone#none()} instead. * @return new instance of {@link DateAdd}. */ + @Contract("_ -> new") public DateAdd withTimezone(Timezone timezone) { return new DateAdd(appendTimezone(argumentMap(), timezone)); } @@ -2936,6 +2986,7 @@ public static DateSubtract subtractValue(Object value, String unit) { * @param expression must not be {@literal null}. * @return new instance of {@link DateSubtract}. */ + @Contract("_ -> new") public DateSubtract fromDateOf(AggregationExpression expression) { return fromDate(expression); } @@ -2946,6 +2997,7 @@ public DateSubtract fromDateOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link DateSubtract}. */ + @Contract("_ -> new") public DateSubtract fromDateOf(String fieldReference) { return fromDate(Fields.field(fieldReference)); } @@ -2956,6 +3008,7 @@ public DateSubtract fromDateOf(String fieldReference) { * @param dateExpression anything that evaluates to a valid date. Must not be {@literal null}. * @return new instance of {@link DateSubtract}. */ + @Contract("_ -> new") public DateSubtract fromDate(Object dateExpression) { return new DateSubtract(append("startDate", dateExpression)); } @@ -2966,6 +3019,7 @@ public DateSubtract fromDate(Object dateExpression) { * @param timezone must not be {@literal null}. Consider {@link Timezone#none()} instead. * @return new instance of {@link DateSubtract}. */ + @Contract("_ -> new") public DateSubtract withTimezone(Timezone timezone) { return new DateSubtract(appendTimezone(argumentMap(), timezone)); } @@ -3033,6 +3087,7 @@ public static DateDiff diffValue(Object value, String unit) { * @param expression must not be {@literal null}. * @return new instance of {@link DateAdd}. */ + @Contract("_ -> new") public DateDiff toDateOf(AggregationExpression expression) { return toDate(expression); } @@ -3043,6 +3098,7 @@ public DateDiff toDateOf(AggregationExpression expression) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link DateAdd}. */ + @Contract("_ -> new") public DateDiff toDateOf(String fieldReference) { return toDate(Fields.field(fieldReference)); } @@ -3053,6 +3109,7 @@ public DateDiff toDateOf(String fieldReference) { * @param dateExpression anything that evaluates to a valid date. Must not be {@literal null}. * @return new instance of {@link DateAdd}. */ + @Contract("_ -> new") public DateDiff toDate(Object dateExpression) { return new DateDiff(append("startDate", dateExpression)); } @@ -3063,6 +3120,7 @@ public DateDiff toDate(Object dateExpression) { * @param timezone must not be {@literal null}. Consider {@link Timezone#none()} instead. * @return new instance of {@link DateAdd}. */ + @Contract("_ -> new") public DateDiff withTimezone(Timezone timezone) { return new DateDiff(appendTimezone(argumentMap(), timezone)); } @@ -3074,6 +3132,7 @@ public DateDiff withTimezone(Timezone timezone) { * @param day must not be {@literal null}. * @return new instance of {@link DateDiff}. */ + @Contract("_ -> new") public DateDiff startOfWeek(Object day) { return new DateDiff(append("startOfWeek", day)); } @@ -3133,6 +3192,7 @@ public static DateTrunc truncateValue(Object value) { * @param unit must not be {@literal null}. * @return new instance of {@link DateTrunc}. */ + @Contract("_ -> new") public DateTrunc to(String unit) { return new DateTrunc(append("unit", unit)); } @@ -3143,6 +3203,7 @@ public DateTrunc to(String unit) { * @param unit must not be {@literal null}. * @return new instance of {@link DateTrunc}. */ + @Contract("_ -> new") public DateTrunc to(AggregationExpression unit) { return new DateTrunc(append("unit", unit)); } @@ -3153,6 +3214,7 @@ public DateTrunc to(AggregationExpression unit) { * @param day must not be {@literal null}. * @return new instance of {@link DateTrunc}. */ + @Contract("_ -> new") public DateTrunc startOfWeek(java.time.DayOfWeek day) { return startOfWeek(day.name().toLowerCase(Locale.US)); } @@ -3163,6 +3225,7 @@ public DateTrunc startOfWeek(java.time.DayOfWeek day) { * @param day must not be {@literal null}. * @return new instance of {@link DateTrunc}. */ + @Contract("_ -> new") public DateTrunc startOfWeek(String day) { return new DateTrunc(append("startOfWeek", day)); } @@ -3173,6 +3236,7 @@ public DateTrunc startOfWeek(String day) { * @param binSize must not be {@literal null}. * @return new instance of {@link DateTrunc}. */ + @Contract("_ -> new") public DateTrunc binSize(int binSize) { return binSize((Object) binSize); } @@ -3183,6 +3247,7 @@ public DateTrunc binSize(int binSize) { * @param expression must not be {@literal null}. * @return new instance of {@link DateTrunc}. */ + @Contract("_ -> new") public DateTrunc binSize(AggregationExpression expression) { return binSize((Object) expression); } @@ -3193,6 +3258,7 @@ public DateTrunc binSize(AggregationExpression expression) { * @param binSize must not be {@literal null}. * @return new instance of {@link DateTrunc}. */ + @Contract("_ -> new") public DateTrunc binSize(Object binSize) { return new DateTrunc(append("binSize", binSize)); } @@ -3203,6 +3269,7 @@ public DateTrunc binSize(Object binSize) { * @param timezone must not be {@literal null}. Consider {@link Timezone#none()} instead. * @return new instance of {@link DateTrunc}. */ + @Contract("_ -> new") public DateTrunc withTimezone(Timezone timezone) { return new DateTrunc(appendTimezone(argumentMap(), timezone)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java index 45afd31775..1a559fd26e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DensifyOperation.java @@ -26,6 +26,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -175,6 +176,7 @@ public Document toDocument(AggregationOperationContext ctx) { * @param step must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public DensifyRange incrementBy(Number step) { this.step = step; return this; @@ -186,6 +188,7 @@ public DensifyRange incrementBy(Number step) { * @param step must not be {@literal null}. * @return this. */ + @Contract("_, _ -> this") public DensifyRange incrementBy(Number step, DensifyUnit unit) { this.step = step; return unit(unit); @@ -197,6 +200,7 @@ public DensifyRange incrementBy(Number step, DensifyUnit unit) { * @param unit * @return this. */ + @Contract("_ -> this") public DensifyRange unit(DensifyUnit unit) { this.unit = unit; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentOperators.java index ff63ad834d..a0cd1d056a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentOperators.java @@ -18,6 +18,7 @@ import java.util.Collections; import org.bson.Document; +import org.springframework.lang.Contract; /** * Gateway to {@literal document expressions} such as {@literal $rank, $documentNumber, etc.} @@ -190,6 +191,7 @@ public static Shift shift(AggregationExpression expression) { * @param shiftBy value to add to the current position. * @return new instance of {@link Shift}. */ + @Contract("_ -> new") public Shift by(int shiftBy) { return new Shift(append("by", shiftBy)); } @@ -200,6 +202,7 @@ public Shift by(int shiftBy) { * @param value must not be {@literal null}. * @return new instance of {@link Shift}. */ + @Contract("_ -> new") public Shift defaultTo(Object value) { return new Shift(append("default", value)); } @@ -210,6 +213,7 @@ public Shift defaultTo(Object value) { * @param expression must not be {@literal null}. * @return new instance of {@link Shift}. */ + @Contract("_ -> new") public Shift defaultToValueOf(AggregationExpression expression) { return defaultTo(expression); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/FacetOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/FacetOperation.java index f5c73dd09c..d1ca95f659 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/FacetOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/FacetOperation.java @@ -23,6 +23,7 @@ import org.bson.Document; import org.springframework.data.mongodb.core.aggregation.BucketOperationSupport.Output; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java index b23e923412..7f574a850e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Fields.java @@ -25,6 +25,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.FieldName; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -145,14 +146,17 @@ private Fields(Fields existing, Field tail) { * @param name must not be {@literal null}. * @return */ + @Contract("_ -> new") public Fields and(String name) { return and(new AggregationField(name)); } + @Contract("_ -> new") public Fields and(String name, String target) { return and(new AggregationField(name, target)); } + @Contract("_ -> new") public Fields and(Field field) { return new Fields(this, field); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java index c2a041deef..bcfc64f2b4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java @@ -21,6 +21,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.NearQuery; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -80,6 +81,7 @@ private GeoNearOperation(NearQuery nearQuery, String distanceField, @Nullable St * @return new instance of {@link GeoNearOperation}. * @since 2.1 */ + @Contract("_ -> new") public GeoNearOperation useIndex(String key) { return new GeoNearOperation(nearQuery, distanceField, key); } 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 3346bf2eb1..ad1f8ae643 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.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.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -35,14 +36,16 @@ * We recommend to use the static factory method {@link Aggregation#graphLookup(String)} instead of creating instances * of this class directly. * - * @see https://docs.mongodb.org/manual/reference/aggregation/graphLookup/ + * @see https://docs.mongodb.org/manual/reference/aggregation/graphLookup/ * @author Mark Paluch * @author Christoph Strobl * @since 1.10 */ public class GraphLookupOperation implements InheritsFieldsAggregationOperation { - private static final Set> ALLOWED_START_TYPES = Set.of(AggregationExpression.class, String.class, Field.class, Document.class); + private static final Set> ALLOWED_START_TYPES = Set.of(AggregationExpression.class, String.class, + Field.class, Document.class); private final String from; private final List startWith; @@ -126,7 +129,7 @@ public ExposedFields getFields() { List fields = new ArrayList<>(2); fields.add(new ExposedField(as, true)); - if(depthField != null) { + if (depthField != null) { fields.add(new ExposedField(depthField, true)); } return ExposedFields.from(fields.toArray(new ExposedField[0])); @@ -221,6 +224,7 @@ static final class GraphLookupOperationFromBuilder private @Nullable String connectFrom; @Override + @Contract("_ -> this") public StartWithBuilder from(String collectionName) { Assert.hasText(collectionName, "CollectionName must not be null or empty"); @@ -230,6 +234,7 @@ public StartWithBuilder from(String collectionName) { } @Override + @Contract("_ -> this") public ConnectFromBuilder startWith(String... fieldReferences) { Assert.notNull(fieldReferences, "FieldReferences must not be null"); @@ -246,6 +251,7 @@ public ConnectFromBuilder startWith(String... fieldReferences) { } @Override + @Contract("_ -> this") public ConnectFromBuilder startWith(AggregationExpression... expressions) { Assert.notNull(expressions, "AggregationExpressions must not be null"); @@ -256,6 +262,7 @@ public ConnectFromBuilder startWith(AggregationExpression... expressions) { } @Override + @Contract("_ -> this") public ConnectFromBuilder startWith(Object... expressions) { Assert.notNull(expressions, "Expressions must not be null"); @@ -297,6 +304,7 @@ private void assertStartWithType(Object expression) { } @Override + @Contract("_ -> this") public ConnectToBuilder connectFrom(String fieldName) { Assert.hasText(fieldName, "ConnectFrom must not be null or empty"); @@ -306,6 +314,7 @@ public ConnectToBuilder connectFrom(String fieldName) { } @Override + @Contract("_ -> new") public GraphLookupOperationBuilder connectTo(String fieldName) { Assert.hasText(fieldName, "ConnectTo must not be null or empty"); @@ -330,8 +339,7 @@ public static final class GraphLookupOperationBuilder { private @Nullable Field depthField; private @Nullable CriteriaDefinition restrictSearchWithMatch; - private GraphLookupOperationBuilder(String from, List startWith, String connectFrom, - String connectTo) { + private GraphLookupOperationBuilder(String from, List startWith, String connectFrom, String connectTo) { this.from = from; this.startWith = new ArrayList<>(startWith); @@ -345,6 +353,7 @@ private GraphLookupOperationBuilder(String from, List startWith, String conne * @param numberOfRecursions must be greater or equal to zero. * @return this. */ + @Contract("_ -> this") public GraphLookupOperationBuilder maxDepth(long numberOfRecursions) { Assert.isTrue(numberOfRecursions >= 0, "Max depth must be >= 0"); @@ -359,6 +368,7 @@ public GraphLookupOperationBuilder maxDepth(long numberOfRecursions) { * @param fieldName must not be {@literal null} or empty. * @return this. */ + @Contract("_ -> this") public GraphLookupOperationBuilder depthField(String fieldName) { Assert.hasText(fieldName, "Depth field name must not be null or empty"); @@ -373,6 +383,7 @@ public GraphLookupOperationBuilder depthField(String fieldName) { * @param criteriaDefinition must not be {@literal null}. * @return */ + @Contract("_ -> this") public GraphLookupOperationBuilder restrict(CriteriaDefinition criteriaDefinition) { Assert.notNull(criteriaDefinition, "CriteriaDefinition must not be null"); @@ -388,6 +399,7 @@ public GraphLookupOperationBuilder restrict(CriteriaDefinition criteriaDefinitio * @param fieldName must not be {@literal null} or empty. * @return the final {@link GraphLookupOperation}. */ + @Contract("_ -> new") public GraphLookupOperation as(String fieldName) { Assert.hasText(fieldName, "As field name must not be null or empty"); 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 436fd0c412..a0e0cc03cd 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 @@ -22,6 +22,7 @@ import org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation; import org.springframework.data.mongodb.core.aggregation.VariableOperators.Let; import org.springframework.data.mongodb.core.aggregation.VariableOperators.Let.ExpressionVariable; +import org.springframework.lang.Contract; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -281,6 +282,7 @@ public static FromBuilder newBuilder() { } @Override + @Contract("_ -> this") public LocalFieldBuilder from(String name) { Assert.hasText(name, "'From' must not be null or empty"); @@ -289,6 +291,7 @@ public LocalFieldBuilder from(String name) { } @Override + @Contract("_ -> this") public AsBuilder foreignField(String name) { Assert.hasText(name, "'ForeignField' must not be null or empty"); @@ -297,6 +300,7 @@ public AsBuilder foreignField(String name) { } @Override + @Contract("_ -> this") public ForeignFieldBuilder localField(String name) { Assert.hasText(name, "'LocalField' must not be null or empty"); @@ -305,6 +309,7 @@ public ForeignFieldBuilder localField(String name) { } @Override + @Contract("_ -> this") public PipelineBuilder let(Let let) { Assert.notNull(let, "Let must not be null"); @@ -313,6 +318,7 @@ public PipelineBuilder let(Let let) { } @Override + @Contract("_ -> this") public AsBuilder pipeline(AggregationPipeline pipeline) { Assert.notNull(pipeline, "Pipeline must not be null"); @@ -321,6 +327,7 @@ public AsBuilder pipeline(AggregationPipeline pipeline) { } @Override + @Contract("_ -> new") public LookupOperation as(String name) { Assert.hasText(name, "'As' must not be null or empty"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java index df785b1d32..bda9a3330d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MergeOperation.java @@ -26,6 +26,7 @@ import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; import org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation; import org.springframework.data.mongodb.core.aggregation.VariableOperators.Let; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -430,6 +431,7 @@ public MergeOperationBuilder() {} * @param collection must not be {@literal null} nor empty. * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder intoCollection(String collection) { Assert.hasText(collection, "Collection must not be null nor empty"); @@ -444,6 +446,7 @@ public MergeOperationBuilder intoCollection(String collection) { * @param database must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder inDatabase(String database) { this.database = database; @@ -456,6 +459,7 @@ public MergeOperationBuilder inDatabase(String database) { * @param into must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder into(MergeOperationTarget into) { this.database = into.database; @@ -469,6 +473,7 @@ public MergeOperationBuilder into(MergeOperationTarget into) { * @param target must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder target(MergeOperationTarget target) { return into(target); } @@ -482,6 +487,7 @@ public MergeOperationBuilder target(MergeOperationTarget target) { * @param fields must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder on(String... fields) { return id(UniqueMergeId.ofIdFields(fields)); } @@ -493,6 +499,7 @@ public MergeOperationBuilder on(String... fields) { * @param id must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder id(UniqueMergeId id) { this.id = id; @@ -506,6 +513,7 @@ public MergeOperationBuilder id(UniqueMergeId id) { * @param let the variable expressions * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder let(Let let) { this.let = let; @@ -519,6 +527,7 @@ public MergeOperationBuilder let(Let let) { * @param let the variable expressions * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder exposeVariablesOf(Let let) { return let(let); } @@ -529,6 +538,7 @@ public MergeOperationBuilder exposeVariablesOf(Let let) { * @param whenMatched must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder whenMatched(WhenDocumentsMatch whenMatched) { this.whenMatched = whenMatched; @@ -541,6 +551,7 @@ public MergeOperationBuilder whenMatched(WhenDocumentsMatch whenMatched) { * @param whenMatched must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder whenDocumentsMatch(WhenDocumentsMatch whenMatched) { return whenMatched(whenMatched); } @@ -551,6 +562,7 @@ public MergeOperationBuilder whenDocumentsMatch(WhenDocumentsMatch whenMatched) * @param aggregation must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder whenDocumentsMatchApply(Aggregation aggregation) { return whenMatched(WhenDocumentsMatch.updateWith(aggregation)); } @@ -561,6 +573,7 @@ public MergeOperationBuilder whenDocumentsMatchApply(Aggregation aggregation) { * @param whenNotMatched must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder whenNotMatched(WhenDocumentsDontMatch whenNotMatched) { this.whenNotMatched = whenNotMatched; @@ -573,6 +586,7 @@ public MergeOperationBuilder whenNotMatched(WhenDocumentsDontMatch whenNotMatche * @param whenNotMatched must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MergeOperationBuilder whenDocumentsDontMatch(WhenDocumentsDontMatch whenNotMatched) { return whenNotMatched(whenNotMatched); } @@ -580,6 +594,7 @@ public MergeOperationBuilder whenDocumentsDontMatch(WhenDocumentsDontMatch whenN /** * @return new instance of {@link MergeOperation}. */ + @Contract("-> new") public MergeOperation build() { Assert.notNull(collection, "Collection must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ObjectOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ObjectOperators.java index 4e5049c120..4e21ab7bde 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ObjectOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ObjectOperators.java @@ -20,6 +20,7 @@ import java.util.Collections; import org.bson.Document; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -385,6 +386,7 @@ public static GetField getField(Field field) { * @param fieldRef must not be {@literal null}. * @return new instance of {@link GetField}. */ + @Contract("_ -> new") public GetField of(String fieldRef) { return of(Fields.field(fieldRef)); } @@ -396,6 +398,7 @@ public GetField of(String fieldRef) { * @param expression must not be {@literal null}. * @return new instance of {@link GetField}. */ + @Contract("_ -> new") public GetField of(AggregationExpression expression) { return of((Object) expression); } @@ -459,6 +462,7 @@ public static SetField field(Field field) { * @param fieldRef must not be {@literal null}. * @return new instance of {@link GetField}. */ + @Contract("_ -> new") public SetField input(String fieldRef) { return input(Fields.field(fieldRef)); } @@ -470,6 +474,7 @@ public SetField input(String fieldRef) { * @param expression must not be {@literal null}. * @return new instance of {@link SetField}. */ + @Contract("_ -> new") public SetField input(AggregationExpression expression) { return input((Object) expression); } @@ -481,6 +486,7 @@ public SetField input(AggregationExpression expression) { * @param fieldRef must not be {@literal null}. * @return new instance of {@link SetField}. */ + @Contract("_ -> new") private SetField input(Object fieldRef) { return new SetField(append("input", fieldRef)); } @@ -491,6 +497,7 @@ private SetField input(Object fieldRef) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link SetField}. */ + @Contract("_ -> new") public SetField toValueOf(String fieldReference) { return toValue(Fields.field(fieldReference)); } @@ -502,6 +509,7 @@ public SetField toValueOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link SetField}. */ + @Contract("_ -> new") public SetField toValueOf(AggregationExpression expression) { return toValue(expression); } @@ -512,6 +520,7 @@ public SetField toValueOf(AggregationExpression expression) { * @param value * @return new instance of {@link SetField}. */ + @Contract("_ -> new") public SetField toValue(Object value) { return new SetField(append("value", value)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java index a46b2fde57..7dbed3a855 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java @@ -18,6 +18,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.util.BsonUtils; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -73,6 +74,7 @@ private OutOperation(@Nullable String databaseName, String collectionName, @Null * @return new instance of {@link OutOperation}. * @since 2.2 */ + @Contract("_ -> new") public OutOperation in(@Nullable String database) { return new OutOperation(database, collectionName, uniqueKey, mode); } @@ -102,6 +104,7 @@ public OutOperation in(@Nullable String database) { * @return new instance of {@link OutOperation}. * @since 2.2 */ + @Contract("_ -> new") public OutOperation uniqueKey(@Nullable String key) { Document uniqueKey = key == null ? null : BsonUtils.toDocumentOrElse(key, it -> new Document(it, 1)); @@ -126,6 +129,7 @@ public OutOperation uniqueKey(@Nullable String key) { * @return new instance of {@link OutOperation}. * @since 2.2 */ + @Contract("_ -> new") public OutOperation uniqueKeyOf(Iterable fields) { Assert.notNull(fields, "Fields must not be null"); @@ -144,6 +148,7 @@ public OutOperation uniqueKeyOf(Iterable fields) { * @return new instance of {@link OutOperation}. * @since 2.2 */ + @Contract("_ -> new") public OutOperation mode(OutMode mode) { Assert.notNull(mode, "Mode must not be null"); @@ -158,6 +163,7 @@ public OutOperation mode(OutMode mode) { * @see OutMode#REPLACE_COLLECTION * @since 2.2 */ + @Contract("-> new") public OutOperation replaceCollection() { return mode(OutMode.REPLACE_COLLECTION); } @@ -170,6 +176,7 @@ public OutOperation replaceCollection() { * @see OutMode#REPLACE * @since 2.2 */ + @Contract("-> new") public OutOperation replaceDocuments() { return mode(OutMode.REPLACE); } @@ -182,6 +189,7 @@ public OutOperation replaceDocuments() { * @see OutMode#INSERT * @since 2.2 */ + @Contract("-> new") public OutOperation insertDocuments() { return mode(OutMode.INSERT); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java index b6b370bff6..af7cf5bfb2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java @@ -30,6 +30,7 @@ import org.springframework.data.mongodb.core.aggregation.Fields.AggregationField; import org.springframework.data.mongodb.core.aggregation.ProjectionOperation.ProjectionOperationBuilder.FieldProjection; import org.springframework.data.mongodb.core.aggregation.VariableOperators.Let.ExpressionVariable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -149,6 +150,7 @@ public ProjectionOperationBuilder and(AggregationExpression expression) { * @param fieldNames must not be {@literal null}. * @return */ + @Contract("_ -> new") public ProjectionOperation andExclude(String... fieldNames) { List excludeProjections = FieldProjection.from(Fields.fields(fieldNames), false); @@ -161,6 +163,7 @@ public ProjectionOperation andExclude(String... fieldNames) { * @param fieldNames must not be {@literal null}. * @return */ + @Contract("_ -> new") public ProjectionOperation andInclude(String... fieldNames) { List projections = FieldProjection.from(Fields.fields(fieldNames), true); @@ -173,6 +176,7 @@ public ProjectionOperation andInclude(String... fieldNames) { * @param fields must not be {@literal null}. * @return */ + @Contract("_ -> new") public ProjectionOperation andInclude(Fields fields) { return new ProjectionOperation(this.projections, FieldProjection.from(fields, true)); } @@ -185,6 +189,7 @@ public ProjectionOperation andInclude(Fields fields) { * @return new instance of {@link ProjectionOperation}. * @since 2.2 */ + @Contract("_ -> new") public ProjectionOperation asArray(String name) { return new ProjectionOperation(Collections.emptyList(), @@ -1780,6 +1785,7 @@ public ArrayProjectionOperationBuilder(ProjectionOperation target) { * @param expression * @return */ + @Contract("_ -> this") public ArrayProjectionOperationBuilder and(AggregationExpression expression) { Assert.notNull(expression, "AggregationExpression must not be null"); @@ -1794,6 +1800,7 @@ public ArrayProjectionOperationBuilder and(AggregationExpression expression) { * @param field * @return */ + @Contract("_ -> this") public ArrayProjectionOperationBuilder and(Field field) { Assert.notNull(field, "Field must not be null"); @@ -1808,6 +1815,7 @@ public ArrayProjectionOperationBuilder and(Field field) { * @param value * @return */ + @Contract("_ -> this") public ArrayProjectionOperationBuilder and(Object value) { this.projections.add(value); @@ -1820,6 +1828,7 @@ public ArrayProjectionOperationBuilder and(Object value) { * @param name The target property name. Must not be {@literal null}. * @return new instance of {@link ArrayProjectionOperationBuilder}. */ + @Contract("_ -> new") public ProjectionOperation as(String name) { return new ProjectionOperation(target.projections, diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/RedactOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/RedactOperation.java index 13e68d40e7..5f16fcfc16 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/RedactOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/RedactOperation.java @@ -19,6 +19,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond.ThenBuilder; import org.springframework.data.mongodb.core.query.CriteriaDefinition; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -34,7 +35,8 @@ * * * @author Christoph Strobl - * @see https://docs.mongodb.com/manual/reference/operator/aggregation/redact/ + * @see https://docs.mongodb.com/manual/reference/operator/aggregation/redact/ * @since 3.0 */ public class RedactOperation implements AggregationOperation { @@ -109,6 +111,7 @@ private RedactOperationBuilder() { * @param criteria must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public RedactOperationBuilder when(CriteriaDefinition criteria) { this.when = criteria; @@ -121,6 +124,7 @@ public RedactOperationBuilder when(CriteriaDefinition criteria) { * @param condition must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public RedactOperationBuilder when(AggregationExpression condition) { this.when = condition; @@ -133,6 +137,7 @@ public RedactOperationBuilder when(AggregationExpression condition) { * @param condition must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public RedactOperationBuilder when(Document condition) { this.when = condition; @@ -144,6 +149,7 @@ public RedactOperationBuilder when(Document condition) { * * @return this. */ + @Contract("-> this") public RedactOperationBuilder thenDescend() { return then(DESCEND); } @@ -153,6 +159,7 @@ public RedactOperationBuilder thenDescend() { * * @return this. */ + @Contract("-> this") public RedactOperationBuilder thenKeep() { return then(KEEP); } @@ -162,6 +169,7 @@ public RedactOperationBuilder thenKeep() { * * @return this. */ + @Contract("-> this") public RedactOperationBuilder thenPrune() { return then(PRUNE); } @@ -173,6 +181,7 @@ public RedactOperationBuilder thenPrune() { * @param then must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public RedactOperationBuilder then(Object then) { this.then = then; @@ -184,6 +193,7 @@ public RedactOperationBuilder then(Object then) { * * @return this. */ + @Contract("-> this") public RedactOperationBuilder otherwiseDescend() { return otherwise(DESCEND); } @@ -193,6 +203,7 @@ public RedactOperationBuilder otherwiseDescend() { * * @return this. */ + @Contract("-> this") public RedactOperationBuilder otherwiseKeep() { return otherwise(KEEP); } @@ -202,6 +213,7 @@ public RedactOperationBuilder otherwiseKeep() { * * @return this. */ + @Contract("-> this") public RedactOperationBuilder otherwisePrune() { return otherwise(PRUNE); } @@ -213,6 +225,7 @@ public RedactOperationBuilder otherwisePrune() { * @param otherwise must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public RedactOperationBuilder otherwise(Object otherwise) { this.otherwise = otherwise; return this; @@ -221,6 +234,7 @@ public RedactOperationBuilder otherwise(Object otherwise) { /** * @return new instance of {@link RedactOperation}. */ + @Contract("-> new") public RedactOperation build() { Assert.notNull(then, "Then must be set first"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java index 4d3145e7f3..ec306eb6c5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java @@ -23,6 +23,7 @@ import org.bson.Document; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.expression.spel.ast.Projection; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java index b5c0ad8119..ed615d9863 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ScriptOperators.java @@ -25,12 +25,12 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ScriptOperators.Accumulator.AccumulatorBuilder; import org.springframework.data.mongodb.core.aggregation.ScriptOperators.Accumulator.AccumulatorInitBuilder; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; /** - * Gateway to {@literal $function} and {@literal $accumulator} aggregation operations. - *
+ * Gateway to {@literal $function} and {@literal $accumulator} aggregation operations.
* Using {@link ScriptOperators} as part of the {@link Aggregation} requires MongoDB server to have * server-side JavaScript execution * enabled. @@ -53,8 +53,8 @@ public static Function function(String body) { } /** - * Create a custom $accumulator operator - * in Javascript. + * Create a custom $accumulator + * operator in Javascript. * * @return new instance of {@link AccumulatorInitBuilder}. */ @@ -74,8 +74,7 @@ public static AccumulatorInitBuilder accumulatorBuilder() { * lang: "js" * } * } - * - *
+ *
* {@link Function} cannot be used as part of {@link org.springframework.data.mongodb.core.schema.MongoJsonSchema * schema} validation query expression.
* NOTE: Server-Side JavaScript @@ -180,8 +179,7 @@ public String toString() { * {@link Accumulator} defines a custom aggregation * $accumulator operator, * one that maintains its state (e.g. totals, maximums, minimums, and related data) as documents progress through the - * pipeline, in JavaScript. - *
+ * pipeline, in JavaScript.
* * { * $accumulator: { @@ -194,8 +192,7 @@ public String toString() { * lang: "js" * } * } - * - *
+ *
* {@link Accumulator} can be used as part of {@link GroupOperation $group}, {@link BucketOperation $bucket} and * {@link BucketAutoOperation $bucketAuto} pipeline stages.
* NOTE: Server-Side JavaScript @@ -242,8 +239,7 @@ public interface AccumulatorInitBuilder { /** * Define the {@code init} {@link Function} for the {@link Accumulator accumulators} initial state. The function - * receives its arguments from the {@link Function#args(Object...) initArgs} array expression. - *
+ * receives its arguments from the {@link Function#args(Object...) initArgs} array expression.
* * function(initArg1, initArg2, ...) { * ... @@ -264,8 +260,7 @@ default AccumulatorAccumulateBuilder init(Function function) { /** * Define the {@code init} function for the {@link Accumulator accumulators} initial state. The function receives - * its arguments from the {@link AccumulatorInitArgsBuilder#initArgs(Object...)} array expression. - *
+ * its arguments from the {@link AccumulatorInitArgsBuilder#initArgs(Object...)} array expression.
* * function(initArg1, initArg2, ...) { * ... @@ -313,8 +308,7 @@ public interface AccumulatorAccumulateBuilder { /** * Set the {@code accumulate} {@link Function} that updates the state for each document. The functions first * argument is the current {@code state}, additional arguments can be defined via {@link Function#args(Object...) - * accumulateArgs}. - *
+ * accumulateArgs}.
* * function(state, accumArg1, accumArg2, ...) { * ... @@ -336,8 +330,7 @@ default AccumulatorMergeBuilder accumulate(Function function) { /** * Set the {@code accumulate} function that updates the state for each document. The functions first argument is * the current {@code state}, additional arguments can be defined via - * {@link AccumulatorAccumulateArgsBuilder#accumulateArgs(Object...)}. - *
+ * {@link AccumulatorAccumulateArgsBuilder#accumulateArgs(Object...)}.
* * function(state, accumArg1, accumArg2, ...) { * ... @@ -379,8 +372,7 @@ public interface AccumulatorMergeBuilder { /** * Set the {@code merge} function used to merge two internal states.
* This might be required because the operation is run on a sharded cluster or when the operator exceeds its - * memory limit. - *
+ * memory limit.
* * function(state1, state2) { * ... @@ -398,8 +390,7 @@ public interface AccumulatorFinalizeBuilder { /** * Set the {@code finalize} function used to update the result of the accumulation when all documents have been - * processed. - *
+ * processed.
* * function(state) { * ... @@ -434,8 +425,7 @@ static class AccumulatorBuilder /** * Define the {@code init} function for the {@link Accumulator accumulators} initial state. The function receives - * its arguments from the {@link #initArgs(Object...)} array expression. - *
+ * its arguments from the {@link #initArgs(Object...)} array expression.
* * function(initArg1, initArg2, ...) { * ... @@ -447,6 +437,7 @@ static class AccumulatorBuilder * @return this. */ @Override + @Contract("_ -> this") public AccumulatorBuilder init(String function) { this.initFunction = function; @@ -460,6 +451,7 @@ public AccumulatorBuilder init(String function) { * @return this. */ @Override + @Contract("_ -> this") public AccumulatorBuilder initArgs(List args) { Assert.notNull(args, "Args must not be null"); @@ -470,8 +462,7 @@ public AccumulatorBuilder initArgs(List args) { /** * Set the {@code accumulate} function that updates the state for each document. The functions first argument is - * the current {@code state}, additional arguments can be defined via {@link #accumulateArgs(Object...)}. - *
+ * the current {@code state}, additional arguments can be defined via {@link #accumulateArgs(Object...)}.
* * function(state, accumArg1, accumArg2, ...) { * ... @@ -483,6 +474,7 @@ public AccumulatorBuilder initArgs(List args) { * @return this. */ @Override + @Contract("_ -> this") public AccumulatorBuilder accumulate(String function) { Assert.notNull(function, "Accumulate function must not be null"); @@ -498,6 +490,7 @@ public AccumulatorBuilder accumulate(String function) { * @return this. */ @Override + @Contract("_ -> this") public AccumulatorBuilder accumulateArgs(List args) { Assert.notNull(args, "Args must not be null"); @@ -509,8 +502,7 @@ public AccumulatorBuilder accumulateArgs(List args) { /** * Set the {@code merge} function used to merge two internal states.
* This might be required because the operation is run on a sharded cluster or when the operator exceeds its - * memory limit. - *
+ * memory limit.
* * function(state1, state2) { * ... @@ -522,6 +514,7 @@ public AccumulatorBuilder accumulateArgs(List args) { * @return this. */ @Override + @Contract("_ -> this") public AccumulatorBuilder merge(String function) { Assert.notNull(function, "Merge function must not be null"); @@ -536,6 +529,7 @@ public AccumulatorBuilder merge(String function) { * @param lang must not be {@literal null}. Default is {@literal js}. * @return this. */ + @Contract("_ -> this") public AccumulatorBuilder lang(String lang) { Assert.hasText(lang, "Lang must not be null nor empty; The default would be 'js'"); @@ -546,8 +540,7 @@ public AccumulatorBuilder lang(String lang) { /** * Set the {@code finalize} function used to update the result of the accumulation when all documents have been - * processed. - *
+ * processed.
* * function(state) { * ... @@ -559,6 +552,7 @@ public AccumulatorBuilder lang(String lang) { * @return new instance of {@link Accumulator}. */ @Override + @Contract("_ -> new") public Accumulator finalize(String function) { Assert.notNull(function, "Finalize function must not be null"); @@ -572,6 +566,7 @@ public Accumulator finalize(String function) { } @Override + @Contract("-> new") public Accumulator build() { return new Accumulator(createArgumentMap()); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SelectionOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SelectionOperators.java index 9da80c4668..4db0181d39 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SelectionOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SelectionOperators.java @@ -19,6 +19,7 @@ import java.util.Collections; import org.springframework.data.domain.Sort; +import org.springframework.lang.Contract; /** * Gateway to {@literal selection operators} such as {@literal $bottom}. @@ -69,6 +70,7 @@ public static Bottom bottom(int numberOfResults) { * @param numberOfResults * @return new instance of {@link Bottom}. */ + @Contract("_ -> new") public Bottom limit(int numberOfResults) { return limit((Object) numberOfResults); } @@ -80,10 +82,12 @@ public Bottom limit(int numberOfResults) { * @param expression must not be {@literal null}. * @return new instance of {@link Bottom}. */ + @Contract("_ -> new") public Bottom limit(AggregationExpression expression) { return limit((Object) expression); } + @Contract("_ -> new") private Bottom limit(Object value) { return new Bottom(append("n", value)); } @@ -94,6 +98,7 @@ private Bottom limit(Object value) { * @param sort must not be {@literal null}. * @return new instance of {@link Bottom}. */ + @Contract("_ -> new") public Bottom sortBy(Sort sort) { return new Bottom(append("sortBy", sort)); } @@ -104,6 +109,7 @@ public Bottom sortBy(Sort sort) { * @param out must not be {@literal null}. * @return new instance of {@link Bottom}. */ + @Contract("_ -> new") public Bottom output(Fields out) { return new Bottom(append("output", out)); } @@ -115,6 +121,7 @@ public Bottom output(Fields out) { * @return new instance of {@link Bottom}. * @see #output(Fields) */ + @Contract("_ -> new") public Bottom output(String... fieldNames) { return output(Fields.fields(fieldNames)); } @@ -126,6 +133,7 @@ public Bottom output(String... fieldNames) { * @return new instance of {@link Bottom}. * @see #output(Fields) */ + @Contract("_ -> new") public Bottom output(AggregationExpression... out) { return new Bottom(append("output", Arrays.asList(out))); } @@ -172,6 +180,7 @@ public static Top top(int numberOfResults) { * @param numberOfResults * @return new instance of {@link Top}. */ + @Contract("_ -> new") public Top limit(int numberOfResults) { return limit((Object) numberOfResults); } @@ -183,6 +192,7 @@ public Top limit(int numberOfResults) { * @param expression must not be {@literal null}. * @return new instance of {@link Top}. */ + @Contract("_ -> new") public Top limit(AggregationExpression expression) { return limit((Object) expression); } @@ -197,6 +207,7 @@ private Top limit(Object value) { * @param sort must not be {@literal null}. * @return new instance of {@link Top}. */ + @Contract("_ -> new") public Top sortBy(Sort sort) { return new Top(append("sortBy", sort)); } @@ -207,6 +218,7 @@ public Top sortBy(Sort sort) { * @param out must not be {@literal null}. * @return new instance of {@link Top}. */ + @Contract("_ -> new") public Top output(Fields out) { return new Top(append("output", out)); } @@ -218,6 +230,7 @@ public Top output(Fields out) { * @return new instance of {@link Top}. * @see #output(Fields) */ + @Contract("_ -> new") public Top output(String... fieldNames) { return output(Fields.fields(fieldNames)); } @@ -229,6 +242,7 @@ public Top output(String... fieldNames) { * @return new instance of {@link Top}. * @see #output(Fields) */ + @Contract("_ -> new") public Top output(AggregationExpression... out) { return new Top(append("output", Arrays.asList(out))); } @@ -263,6 +277,7 @@ public static First first(int numberOfResults) { * @param numberOfResults * @return new instance of {@link First}. */ + @Contract("_ -> new") public First limit(int numberOfResults) { return limit((Object) numberOfResults); } @@ -274,6 +289,7 @@ public First limit(int numberOfResults) { * @param expression must not be {@literal null}. * @return new instance of {@link First}. */ + @Contract("_ -> new") public First limit(AggregationExpression expression) { return limit((Object) expression); } @@ -288,6 +304,7 @@ private First limit(Object value) { * @param fieldName must not be {@literal null}. * @return new instance of {@link First}. */ + @Contract("_ -> new") public First of(String fieldName) { return input(fieldName); } @@ -298,6 +315,7 @@ public First of(String fieldName) { * @param expression must not be {@literal null}. * @return new instance of {@link First}. */ + @Contract("_ -> new") public First of(AggregationExpression expression) { return input(expression); } @@ -308,6 +326,7 @@ public First of(AggregationExpression expression) { * @param fieldName must not be {@literal null}. * @return new instance of {@link First}. */ + @Contract("_ -> new") public First input(String fieldName) { return new First(append("input", Fields.field(fieldName))); } @@ -318,6 +337,7 @@ public First input(String fieldName) { * @param expression must not be {@literal null}. * @return new instance of {@link First}. */ + @Contract("_ -> new") public First input(AggregationExpression expression) { return new First(append("input", expression)); } @@ -357,6 +377,7 @@ public static Last last(int numberOfResults) { * @param numberOfResults * @return new instance of {@link Last}. */ + @Contract("_ -> new") public Last limit(int numberOfResults) { return limit((Object) numberOfResults); } @@ -368,6 +389,7 @@ public Last limit(int numberOfResults) { * @param expression must not be {@literal null}. * @return new instance of {@link Last}. */ + @Contract("_ -> new") public Last limit(AggregationExpression expression) { return limit((Object) expression); } @@ -382,6 +404,7 @@ private Last limit(Object value) { * @param fieldName must not be {@literal null}. * @return new instance of {@link Last}. */ + @Contract("_ -> new") public Last of(String fieldName) { return input(fieldName); } @@ -392,6 +415,7 @@ public Last of(String fieldName) { * @param expression must not be {@literal null}. * @return new instance of {@link Last}. */ + @Contract("_ -> new") public Last of(AggregationExpression expression) { return input(expression); } @@ -402,6 +426,7 @@ public Last of(AggregationExpression expression) { * @param fieldName must not be {@literal null}. * @return new instance of {@link Last}. */ + @Contract("_ -> new") public Last input(String fieldName) { return new Last(append("input", Fields.field(fieldName))); } @@ -412,6 +437,7 @@ public Last input(String fieldName) { * @param expression must not be {@literal null}. * @return new instance of {@link Last}. */ + @Contract("_ -> new") public Last input(AggregationExpression expression) { return new Last(append("input", expression)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java index 50c21e25e4..6ef4f1323f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java @@ -21,6 +21,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.SetOperation.FieldAppender.ValueAppender; +import org.springframework.lang.Contract; /** * Adds new fields to documents. {@code $set} outputs documents that contain all existing fields from the input @@ -82,6 +83,7 @@ public static ValueAppender set(String field) { * @param value the value to assign. * @return new instance of {@link SetOperation}. */ + @Contract("_, _ -> new") public SetOperation set(Object field, Object value) { LinkedHashMap target = new LinkedHashMap<>(getValueMap()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperators.java index 3b44b4d8b0..a99c0926f4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperators.java @@ -21,6 +21,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.Sum; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -291,6 +292,7 @@ public static SetEquals arrayAsSet(AggregationExpression expression) { * @param arrayReferences must not be {@literal null}. * @return new instance of {@link SetEquals}. */ + @Contract("_ -> new") public SetEquals isEqualTo(String... arrayReferences) { Assert.notNull(arrayReferences, "ArrayReferences must not be null"); @@ -303,6 +305,7 @@ public SetEquals isEqualTo(String... arrayReferences) { * @param expressions must not be {@literal null}. * @return new instance of {@link SetEquals}. */ + @Contract("_ -> new") public SetEquals isEqualTo(AggregationExpression... expressions) { Assert.notNull(expressions, "Expressions must not be null"); @@ -315,6 +318,7 @@ public SetEquals isEqualTo(AggregationExpression... expressions) { * @param array must not be {@literal null}. * @return new instance of {@link SetEquals}. */ + @Contract("_ -> new") public SetEquals isEqualTo(Object[] array) { Assert.notNull(array, "Array must not be null"); @@ -368,6 +372,7 @@ public static SetIntersection arrayAsSet(AggregationExpression expression) { * @param arrayReferences must not be {@literal null}. * @return new instance of {@link SetIntersection}. */ + @Contract("_ -> new") public SetIntersection intersects(String... arrayReferences) { Assert.notNull(arrayReferences, "ArrayReferences must not be null"); @@ -380,6 +385,7 @@ public SetIntersection intersects(String... arrayReferences) { * @param expressions must not be {@literal null}. * @return new instance of {@link SetIntersection}. */ + @Contract("_ -> new") public SetIntersection intersects(AggregationExpression... expressions) { Assert.notNull(expressions, "Expressions must not be null"); @@ -433,6 +439,7 @@ public static SetUnion arrayAsSet(AggregationExpression expression) { * @param arrayReferences must not be {@literal null}. * @return new instance of {@link SetUnion}. */ + @Contract("_ -> new") public SetUnion union(String... arrayReferences) { Assert.notNull(arrayReferences, "ArrayReferences must not be null"); @@ -445,6 +452,7 @@ public SetUnion union(String... arrayReferences) { * @param expressions must not be {@literal null}. * @return new instance of {@link SetUnion}. */ + @Contract("_ -> new") public SetUnion union(AggregationExpression... expressions) { Assert.notNull(expressions, "Expressions must not be null"); @@ -498,6 +506,7 @@ public static SetDifference arrayAsSet(AggregationExpression expression) { * @param arrayReference must not be {@literal null}. * @return new instance of {@link SetDifference}. */ + @Contract("_ -> new") public SetDifference differenceTo(String arrayReference) { Assert.notNull(arrayReference, "ArrayReference must not be null"); @@ -510,6 +519,7 @@ public SetDifference differenceTo(String arrayReference) { * @param expression must not be {@literal null}. * @return new instance of {@link SetDifference}. */ + @Contract("_ -> new") public SetDifference differenceTo(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -563,6 +573,7 @@ public static SetIsSubset arrayAsSet(AggregationExpression expression) { * @param arrayReference must not be {@literal null}. * @return new instance of {@link SetIsSubset}. */ + @Contract("_ -> new") public SetIsSubset isSubsetOf(String arrayReference) { Assert.notNull(arrayReference, "ArrayReference must not be null"); @@ -575,6 +586,7 @@ public SetIsSubset isSubsetOf(String arrayReference) { * @param expression must not be {@literal null}. * @return new instance of {@link SetIsSubset}. */ + @Contract("_ -> new") public SetIsSubset isSubsetOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -622,6 +634,7 @@ public static AnyElementTrue arrayAsSet(AggregationExpression expression) { return new AnyElementTrue(Collections.singletonList(expression)); } + @Contract("-> this") public AnyElementTrue anyElementTrue() { return this; } @@ -667,6 +680,7 @@ public static AllElementsTrue arrayAsSet(AggregationExpression expression) { return new AllElementsTrue(Collections.singletonList(expression)); } + @Contract("-> this") public AllElementsTrue allElementsTrue() { return this; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java index c353d0525a..e1fec17811 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java @@ -24,6 +24,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Sort; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -31,7 +32,8 @@ * * @author Christoph Strobl * @since 3.3 - * @see https://docs.mongodb.com/manual/reference/operator/aggregation/setWindowFields/ + * @see https://docs.mongodb.com/manual/reference/operator/aggregation/setWindowFields/ */ public class SetWindowFieldsOperation implements AggregationOperation, FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation { @@ -137,6 +139,7 @@ public WindowOutput(ComputedField outputField) { * @param field must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public WindowOutput append(ComputedField field) { Assert.notNull(field, "Field must not be null"); @@ -152,6 +155,7 @@ public WindowOutput append(ComputedField field) { * @return new instance of {@link ComputedFieldAppender}. * @see #append(ComputedField) */ + @Contract("_ -> new") public ComputedFieldAppender append(AggregationExpression expression) { return new ComputedFieldAppender() { @@ -359,6 +363,7 @@ public static class RangeWindowBuilder { * @param lower eg. {@literal current} or {@literal unbounded}. * @return this. */ + @Contract("_ -> this") public RangeWindowBuilder from(String lower) { this.lower = lower; @@ -371,6 +376,7 @@ public RangeWindowBuilder from(String lower) { * @param upper eg. {@literal current} or {@literal unbounded}. * @return this. */ + @Contract("_ -> this") public RangeWindowBuilder to(String upper) { this.upper = upper; @@ -385,6 +391,7 @@ public RangeWindowBuilder to(String upper) { * @param lower * @return this. */ + @Contract("_ -> this") public RangeWindowBuilder from(Number lower) { this.lower = lower; @@ -399,6 +406,7 @@ public RangeWindowBuilder from(Number lower) { * @param upper * @return this. */ + @Contract("_ -> this") public RangeWindowBuilder to(Number upper) { this.upper = upper; @@ -410,6 +418,7 @@ public RangeWindowBuilder to(Number upper) { * * @return this. */ + @Contract("-> this") public RangeWindowBuilder fromCurrent() { return from(CURRENT); } @@ -419,6 +428,7 @@ public RangeWindowBuilder fromCurrent() { * * @return this. */ + @Contract("-> this") public RangeWindowBuilder fromUnbounded() { return from(UNBOUNDED); } @@ -428,6 +438,7 @@ public RangeWindowBuilder fromUnbounded() { * * @return this. */ + @Contract("-> this") public RangeWindowBuilder toCurrent() { return to(CURRENT); } @@ -437,6 +448,7 @@ public RangeWindowBuilder toCurrent() { * * @return this. */ + @Contract("-> this") public RangeWindowBuilder toUnbounded() { return to(UNBOUNDED); } @@ -447,6 +459,7 @@ public RangeWindowBuilder toUnbounded() { * @param windowUnit must not be {@literal null}. Can be on of {@link Windows}. * @return this. */ + @Contract("_ -> this") public RangeWindowBuilder unit(WindowUnit windowUnit) { Assert.notNull(windowUnit, "WindowUnit must not be null"); @@ -459,6 +472,7 @@ public RangeWindowBuilder unit(WindowUnit windowUnit) { * * @return new instance of {@link RangeWindow}. */ + @Contract("-> new") public RangeWindow build() { Assert.notNull(lower, "Lower bound must not be null"); @@ -487,20 +501,24 @@ public static class DocumentWindowBuilder { * @param lower * @return this. */ + @Contract("_ -> this") public DocumentWindowBuilder from(Number lower) { this.lower = lower; return this; } + @Contract("-> this") public DocumentWindowBuilder fromCurrent() { return from(CURRENT); } + @Contract("-> this") public DocumentWindowBuilder fromUnbounded() { return from(UNBOUNDED); } + @Contract("-> this") public DocumentWindowBuilder to(String upper) { this.upper = upper; @@ -513,6 +531,7 @@ public DocumentWindowBuilder to(String upper) { * @param lower eg. {@literal current} or {@literal unbounded}. * @return this. */ + @Contract("_ -> this") public DocumentWindowBuilder from(String lower) { this.lower = lower; @@ -527,20 +546,24 @@ public DocumentWindowBuilder from(String lower) { * @param upper * @return this. */ + @Contract("_ -> this") public DocumentWindowBuilder to(Number upper) { this.upper = upper; return this; } + @Contract("-> this") public DocumentWindowBuilder toCurrent() { return to(CURRENT); } + @Contract("-> this") public DocumentWindowBuilder toUnbounded() { return to(UNBOUNDED); } + @Contract("-> new") public DocumentWindow build() { Assert.notNull(lower, "Lower bound must not be null"); @@ -698,6 +721,7 @@ public static class SetWindowFieldsOperationBuilder { * @param fieldName must not be {@literal null} or null. * @return this. */ + @Contract("_ -> this") public SetWindowFieldsOperationBuilder partitionByField(String fieldName) { Assert.hasText(fieldName, "Field name must not be empty or null"); @@ -710,6 +734,7 @@ public SetWindowFieldsOperationBuilder partitionByField(String fieldName) { * @param expression must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public SetWindowFieldsOperationBuilder partitionByExpression(AggregationExpression expression) { return partitionBy(expression); } @@ -720,6 +745,7 @@ public SetWindowFieldsOperationBuilder partitionByExpression(AggregationExpressi * @param fields must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public SetWindowFieldsOperationBuilder sortBy(String... fields) { return sortBy(Sort.by(fields)); } @@ -730,6 +756,7 @@ public SetWindowFieldsOperationBuilder sortBy(String... fields) { * @param sort must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public SetWindowFieldsOperationBuilder sortBy(Sort sort) { return sortBy(new SortOperation(sort)); } @@ -740,6 +767,7 @@ public SetWindowFieldsOperationBuilder sortBy(Sort sort) { * @param sort must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public SetWindowFieldsOperationBuilder sortBy(SortOperation sort) { Assert.notNull(sort, "SortOperation must not be null"); @@ -754,6 +782,7 @@ public SetWindowFieldsOperationBuilder sortBy(SortOperation sort) { * @param output must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public SetWindowFieldsOperationBuilder output(WindowOutput output) { Assert.notNull(output, "WindowOutput must not be null"); @@ -768,6 +797,7 @@ public SetWindowFieldsOperationBuilder output(WindowOutput output) { * @param expression must not be {@literal null}. * @return new instance of {@link WindowChoice}. */ + @Contract("_ -> new") public WindowChoice output(AggregationExpression expression) { return new WindowChoice() { @@ -836,6 +866,7 @@ public interface WindowChoice extends As { * @param value must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public SetWindowFieldsOperationBuilder partitionBy(Object value) { Assert.notNull(value, "Partition By must not be null"); @@ -849,6 +880,7 @@ public SetWindowFieldsOperationBuilder partitionBy(Object value) { * * @return new instance of {@link SetWindowFieldsOperation}. */ + @Contract("-> new") public SetWindowFieldsOperation build() { Assert.notNull(output, "Output must be set first"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java index 40f88b1339..0f3447a476 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java @@ -24,6 +24,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.mongodb.util.RegexFlags; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -830,6 +831,7 @@ public static Concat stringValue(String value) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Concat}. */ + @Contract("_ -> new") public Concat concatValueOf(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -842,6 +844,7 @@ public Concat concatValueOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Concat}. */ + @Contract("_ -> new") public Concat concatValueOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -854,6 +857,7 @@ public Concat concatValueOf(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link Concat}. */ + @Contract("_ -> new") public Concat concat(String value) { return new Concat(append(value)); } @@ -903,6 +907,7 @@ public static Substr valueOf(AggregationExpression expression) { * @param start start index (including) * @return new instance of {@link Substr}. */ + @Contract("_ -> new") public Substr substring(int start) { return substring(start, -1); } @@ -912,6 +917,7 @@ public Substr substring(int start) { * @param nrOfChars * @return new instance of {@link Substr}. */ + @Contract("_, _ -> new") public Substr substring(int start, int nrOfChars) { return new Substr(append(Arrays.asList(start, nrOfChars))); } @@ -1075,16 +1081,19 @@ public static StrCaseCmp stringValue(String value) { return new StrCaseCmp(Collections.singletonList(value)); } + @Contract("_ -> new") public StrCaseCmp strcasecmp(String value) { return new StrCaseCmp(append(value)); } + @Contract("_ -> new") public StrCaseCmp strcasecmpValueOf(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); return new StrCaseCmp(append(Fields.field(fieldReference))); } + @Contract("_ -> new") public StrCaseCmp strcasecmpValueOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1138,6 +1147,7 @@ public static SubstringBuilder valueOf(AggregationExpression expression) { * @param range must not be {@literal null}. * @return new instance of {@link IndexOfBytes}. */ + @Contract("_ -> new") public IndexOfBytes within(Range range) { return new IndexOfBytes(append(AggregationUtils.toRangeValues(range))); } @@ -1228,6 +1238,7 @@ public static SubstringBuilder valueOf(AggregationExpression expression) { * @param range must not be {@literal null}. * @return new instance of {@link IndexOfCP}. */ + @Contract("_ -> new") public IndexOfCP within(Range range) { return new IndexOfCP(append(AggregationUtils.toRangeValues(range))); } @@ -1318,6 +1329,7 @@ public static Split valueOf(AggregationExpression expression) { * @param delimiter must not be {@literal null}. * @return new instance of {@link Split}. */ + @Contract("_ -> new") public Split split(String delimiter) { Assert.notNull(delimiter, "Delimiter must not be null"); @@ -1330,6 +1342,7 @@ public Split split(String delimiter) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Split}. */ + @Contract("_ -> new") public Split split(Field fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1342,6 +1355,7 @@ public Split split(Field fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Split}. */ + @Contract("_ -> new") public Split split(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1467,10 +1481,12 @@ public static SubstrCP valueOf(AggregationExpression expression) { return new SubstrCP(Collections.singletonList(expression)); } + @Contract("_ -> new") public SubstrCP substringCP(int start) { return substringCP(start, -1); } + @Contract("_, _ -> new") public SubstrCP substringCP(int start, int nrOfChars) { return new SubstrCP(append(Arrays.asList(start, nrOfChars))); } @@ -1521,6 +1537,7 @@ public static Trim valueOf(AggregationExpression expression) { * @param chars must not be {@literal null}. * @return new instance of {@link Trim}. */ + @Contract("_ -> new") public Trim chars(String chars) { Assert.notNull(chars, "Chars must not be null"); @@ -1534,6 +1551,7 @@ public Trim chars(String chars) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link Trim}. */ + @Contract("_ -> new") public Trim charsOf(String fieldReference) { return new Trim(append("chars", Fields.field(fieldReference))); } @@ -1545,6 +1563,7 @@ public Trim charsOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link Trim}. */ + @Contract("_ -> new") public Trim charsOf(AggregationExpression expression) { return new Trim(append("chars", expression)); } @@ -1618,6 +1637,7 @@ public static LTrim valueOf(AggregationExpression expression) { * @param chars must not be {@literal null}. * @return new instance of {@link LTrim}. */ + @Contract("_ -> new") public LTrim chars(String chars) { Assert.notNull(chars, "Chars must not be null"); @@ -1631,6 +1651,7 @@ public LTrim chars(String chars) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link LTrim}. */ + @Contract("_ -> new") public LTrim charsOf(String fieldReference) { return new LTrim(append("chars", Fields.field(fieldReference))); } @@ -1642,6 +1663,7 @@ public LTrim charsOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link LTrim}. */ + @Contract("_ -> new") public LTrim charsOf(AggregationExpression expression) { return new LTrim(append("chars", expression)); } @@ -1697,6 +1719,7 @@ public static RTrim valueOf(AggregationExpression expression) { * @param chars must not be {@literal null}. * @return new instance of {@link RTrim}. */ + @Contract("_ -> new") public RTrim chars(String chars) { Assert.notNull(chars, "Chars must not be null"); @@ -1709,6 +1732,7 @@ public RTrim chars(String chars) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link RTrim}. */ + @Contract("_ -> new") public RTrim charsOf(String fieldReference) { return new RTrim(append("chars", Fields.field(fieldReference))); } @@ -1719,6 +1743,7 @@ public RTrim charsOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link RTrim}. */ + @Contract("_ -> new") public RTrim charsOf(AggregationExpression expression) { return new RTrim(append("chars", expression)); } @@ -1777,6 +1802,7 @@ public static RegexFind valueOf(AggregationExpression expression) { * @param options must not be {@literal null}. * @return new instance of {@link RegexFind}. */ + @Contract("_ -> new") public RegexFind options(String options) { Assert.notNull(options, "Options must not be null"); @@ -1791,6 +1817,7 @@ public RegexFind options(String options) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link RegexFind}. */ + @Contract("_ -> new") public RegexFind optionsOf(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -1805,6 +1832,7 @@ public RegexFind optionsOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link RegexFind}. */ + @Contract("_ -> new") public RegexFind optionsOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1818,6 +1846,7 @@ public RegexFind optionsOf(AggregationExpression expression) { * @param regex must not be {@literal null}. * @return new instance of {@link RegexFind}. */ + @Contract("_ -> new") public RegexFind regex(String regex) { Assert.notNull(regex, "Regex must not be null"); @@ -1831,6 +1860,7 @@ public RegexFind regex(String regex) { * @param pattern must not be {@literal null}. * @return new instance of {@link RegexFind}. */ + @Contract("_ -> new") public RegexFind pattern(Pattern pattern) { Assert.notNull(pattern, "Pattern must not be null"); @@ -1847,6 +1877,7 @@ public RegexFind pattern(Pattern pattern) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link RegexFind}. */ + @Contract("_ -> new") public RegexFind regexOf(String fieldReference) { Assert.notNull(fieldReference, "fieldReference must not be null"); @@ -1860,6 +1891,7 @@ public RegexFind regexOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link RegexFind}. */ + @Contract("_ -> new") public RegexFind regexOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1919,6 +1951,7 @@ public static RegexFindAll valueOf(AggregationExpression expression) { * @param options must not be {@literal null}. * @return new instance of {@link RegexFindAll}. */ + @Contract("_ -> new") public RegexFindAll options(String options) { Assert.notNull(options, "Options must not be null"); @@ -1933,6 +1966,7 @@ public RegexFindAll options(String options) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link RegexFindAll}. */ + @Contract("_ -> new") public RegexFindAll optionsOf(String fieldReference) { Assert.notNull(fieldReference, "fieldReference must not be null"); @@ -1947,6 +1981,7 @@ public RegexFindAll optionsOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link RegexFindAll}. */ + @Contract("_ -> new") public RegexFindAll optionsOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -1960,6 +1995,7 @@ public RegexFindAll optionsOf(AggregationExpression expression) { * @param pattern must not be {@literal null}. * @return new instance of {@link RegexFindAll}. */ + @Contract("_ -> new") public RegexFindAll pattern(Pattern pattern) { Assert.notNull(pattern, "Pattern must not be null"); @@ -1976,6 +2012,7 @@ public RegexFindAll pattern(Pattern pattern) { * @param regex must not be {@literal null}. * @return new instance of {@link RegexFindAll}. */ + @Contract("_ -> new") public RegexFindAll regex(String regex) { Assert.notNull(regex, "Regex must not be null"); @@ -1989,6 +2026,7 @@ public RegexFindAll regex(String regex) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link RegexFindAll}. */ + @Contract("_ -> new") public RegexFindAll regexOf(String fieldReference) { Assert.notNull(fieldReference, "fieldReference must not be null"); @@ -2002,6 +2040,7 @@ public RegexFindAll regexOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link RegexFindAll}. */ + @Contract("_ -> new") public RegexFindAll regexOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -2063,6 +2102,7 @@ public static RegexMatch valueOf(AggregationExpression expression) { * @param options must not be {@literal null}. * @return new instance of {@link RegexMatch}. */ + @Contract("_ -> new") public RegexMatch options(String options) { Assert.notNull(options, "Options must not be null"); @@ -2077,6 +2117,7 @@ public RegexMatch options(String options) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link RegexMatch}. */ + @Contract("_ -> new") public RegexMatch optionsOf(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -2091,6 +2132,7 @@ public RegexMatch optionsOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link RegexMatch}. */ + @Contract("_ -> new") public RegexMatch optionsOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -2104,6 +2146,7 @@ public RegexMatch optionsOf(AggregationExpression expression) { * @param pattern must not be {@literal null}. * @return new instance of {@link RegexMatch}. */ + @Contract("_ -> new") public RegexMatch pattern(Pattern pattern) { Assert.notNull(pattern, "Pattern must not be null"); @@ -2120,6 +2163,7 @@ public RegexMatch pattern(Pattern pattern) { * @param regex must not be {@literal null}. * @return new instance of {@link RegexMatch}. */ + @Contract("_ -> new") public RegexMatch regex(String regex) { Assert.notNull(regex, "Regex must not be null"); @@ -2133,6 +2177,7 @@ public RegexMatch regex(String regex) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link RegexMatch}. */ + @Contract("_ -> new") public RegexMatch regexOf(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -2146,6 +2191,7 @@ public RegexMatch regexOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link RegexMatch}. */ + @Contract("_ -> new") public RegexMatch regexOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -2221,6 +2267,7 @@ public static ReplaceOne valueOf(AggregationExpression expression) { * @param replacement must not be {@literal null}. * @return new instance of {@link ReplaceOne}. */ + @Contract("_ -> new") public ReplaceOne replacement(String replacement) { Assert.notNull(replacement, "Replacement must not be null"); @@ -2235,6 +2282,7 @@ public ReplaceOne replacement(String replacement) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link ReplaceOne}. */ + @Contract("_ -> new") public ReplaceOne replacementOf(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -2249,6 +2297,7 @@ public ReplaceOne replacementOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link ReplaceOne}. */ + @Contract("_ -> new") public ReplaceOne replacementOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -2262,6 +2311,7 @@ public ReplaceOne replacementOf(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link ReplaceOne}. */ + @Contract("_ -> new") public ReplaceOne find(String value) { Assert.notNull(value, "Search string must not be null"); @@ -2275,6 +2325,7 @@ public ReplaceOne find(String value) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link ReplaceOne}. */ + @Contract("_ -> new") public ReplaceOne findValueOf(String fieldReference) { Assert.notNull(fieldReference, "fieldReference must not be null"); @@ -2289,6 +2340,7 @@ public ReplaceOne findValueOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link ReplaceOne}. */ + @Contract("_ -> new") public ReplaceOne findValueOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -2364,6 +2416,7 @@ public static ReplaceAll valueOf(AggregationExpression expression) { * @param replacement must not be {@literal null}. * @return new instance of {@link ReplaceAll}. */ + @Contract("_ -> new") public ReplaceAll replacement(String replacement) { Assert.notNull(replacement, "Replacement must not be null"); @@ -2378,6 +2431,7 @@ public ReplaceAll replacement(String replacement) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link ReplaceAll}. */ + @Contract("_ -> new") public ReplaceAll replacementValueOf(String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null"); @@ -2392,6 +2446,7 @@ public ReplaceAll replacementValueOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link ReplaceAll}. */ + @Contract("_ -> new") public ReplaceAll replacementValueOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); @@ -2405,6 +2460,7 @@ public ReplaceAll replacementValueOf(AggregationExpression expression) { * @param value must not be {@literal null}. * @return new instance of {@link ReplaceAll}. */ + @Contract("_ -> new") public ReplaceAll find(String value) { Assert.notNull(value, "Search string must not be null"); @@ -2418,6 +2474,7 @@ public ReplaceAll find(String value) { * @param fieldReference must not be {@literal null}. * @return new instance of {@link ReplaceAll}. */ + @Contract("_ -> new") public ReplaceAll findValueOf(String fieldReference) { Assert.notNull(fieldReference, "fieldReference must not be null"); @@ -2431,6 +2488,7 @@ public ReplaceAll findValueOf(String fieldReference) { * @param expression must not be {@literal null}. * @return new instance of {@link ReplaceAll}. */ + @Contract("_ -> new") public ReplaceAll findValueOf(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnsetOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnsetOperation.java index ff765c37f7..0bcc192ded 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnsetOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnsetOperation.java @@ -23,6 +23,7 @@ import org.bson.Document; import org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -67,6 +68,7 @@ public static UnsetOperation unset(String... fields) { * @param fields must not be {@literal null}. * @return new instance of {@link UnsetOperation}. */ + @Contract("_ -> new") public UnsetOperation and(String... fields) { List target = new ArrayList<>(this.fields); @@ -80,6 +82,7 @@ public UnsetOperation and(String... fields) { * @param fields must not be {@literal null}. * @return new instance of {@link UnsetOperation}. */ + @Contract("_ -> new") public UnsetOperation and(Field... fields) { List target = new ArrayList<>(this.fields); 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 623af471d3..cc0552cd1c 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 @@ -18,6 +18,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -223,6 +224,7 @@ public UnwindOperation skipNullAndEmptyArrays() { } @Override + @Contract("_ -> this") public EmptyArraysBuilder arrayIndex(String field) { Assert.hasText(field, "'ArrayIndex' must not be null or empty"); @@ -231,6 +233,7 @@ public EmptyArraysBuilder arrayIndex(String field) { } @Override + @Contract("-> this") public EmptyArraysBuilder noArrayIndex() { arrayIndex = null; @@ -238,6 +241,7 @@ public EmptyArraysBuilder noArrayIndex() { } @Override + @Contract("_ -> this") public UnwindOperationBuilder path(String path) { Assert.hasText(path, "'Path' must not be null or empty"); 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 fa57f2cab4..8dccced380 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 @@ -52,6 +52,7 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -188,6 +189,7 @@ public static MongoConverterConfigurationAdapter from(List converters) { * @param converter must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MongoConverterConfigurationAdapter registerConverter(Converter converter) { Assert.notNull(converter, "Converter must not be null"); @@ -202,6 +204,7 @@ public MongoConverterConfigurationAdapter registerConverter(Converter conv * @param converters must not be {@literal null} nor contain {@literal null} values. * @return this. */ + @Contract("_ -> this") public MongoConverterConfigurationAdapter registerConverters(Collection converters) { Assert.notNull(converters, "Converters must not be null"); @@ -217,6 +220,7 @@ public MongoConverterConfigurationAdapter registerConverters(Collection conve * @param converterFactory must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MongoConverterConfigurationAdapter registerConverterFactory(ConverterFactory converterFactory) { Assert.notNull(converterFactory, "ConverterFactory must not be null"); @@ -232,6 +236,7 @@ public MongoConverterConfigurationAdapter registerConverterFactory(ConverterFact * @return this. * @since 3.4 */ + @Contract("_ -> this") public MongoConverterConfigurationAdapter registerPropertyValueConverterFactory( PropertyValueConverterFactory converterFactory) { @@ -249,6 +254,7 @@ public MongoConverterConfigurationAdapter registerPropertyValueConverterFactory( * @return this. * @since 3.4 */ + @Contract("_ -> this") public MongoConverterConfigurationAdapter configurePropertyConversions( Consumer> configurationAdapter) { @@ -271,6 +277,7 @@ public MongoConverterConfigurationAdapter configurePropertyConversions( * @param useNativeDriverJavaTimeCodecs * @return this. */ + @Contract("_ -> this") public MongoConverterConfigurationAdapter useNativeDriverJavaTimeCodecs(boolean useNativeDriverJavaTimeCodecs) { this.useNativeDriverJavaTimeCodecs = useNativeDriverJavaTimeCodecs; @@ -285,6 +292,7 @@ public MongoConverterConfigurationAdapter useNativeDriverJavaTimeCodecs(boolean * @return this. * @see #useNativeDriverJavaTimeCodecs(boolean) */ + @Contract("-> this") public MongoConverterConfigurationAdapter useNativeDriverJavaTimeCodecs() { return useNativeDriverJavaTimeCodecs(true); } @@ -299,6 +307,7 @@ public MongoConverterConfigurationAdapter useNativeDriverJavaTimeCodecs() { * @return this. * @see #useNativeDriverJavaTimeCodecs(boolean) */ + @Contract("-> this") public MongoConverterConfigurationAdapter useSpringDataJavaTimeCodecs() { return useNativeDriverJavaTimeCodecs(false); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonPolygon.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonPolygon.java index ad3300ee1c..990be290cd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonPolygon.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/geo/GeoJsonPolygon.java @@ -24,6 +24,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; import org.springframework.data.geo.Polygon; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -78,6 +79,7 @@ public GeoJsonPolygon(List points) { * @return new {@link GeoJsonPolygon}. * @since 1.10 */ + @Contract("_, _, _, _, _ -> new") public GeoJsonPolygon withInnerRing(Point first, Point second, Point third, Point fourth, Point... others) { return withInnerRing(asList(first, second, third, fourth, others)); } @@ -88,6 +90,7 @@ public GeoJsonPolygon withInnerRing(Point first, Point second, Point third, Poin * @param points must not be {@literal null}. * @return new {@link GeoJsonPolygon}. */ + @Contract("_ -> new") public GeoJsonPolygon withInnerRing(List points) { return withInnerRing(new GeoJsonLineString(points)); } @@ -99,6 +102,7 @@ public GeoJsonPolygon withInnerRing(List points) { * @return new {@link GeoJsonPolygon}. * @since 1.10 */ + @Contract("_ -> new") public GeoJsonPolygon withInnerRing(GeoJsonLineString lineString) { Assert.notNull(lineString, "LineString must not be null"); 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 30b9b49ce7..7188da6972 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 @@ -21,6 +21,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.util.MongoClientVersion; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -62,6 +63,7 @@ public GeospatialIndex(String field) { * @param name must not be {@literal null} or empty. * @return this. */ + @Contract("_ -> this") public GeospatialIndex named(String name) { this.name = name; @@ -72,6 +74,7 @@ public GeospatialIndex named(String name) { * @param min * @return this. */ + @Contract("_ -> this") public GeospatialIndex withMin(int min) { this.min = min; return this; @@ -81,6 +84,7 @@ public GeospatialIndex withMin(int min) { * @param max * @return this. */ + @Contract("_ -> this") public GeospatialIndex withMax(int max) { this.max = max; return this; @@ -90,6 +94,7 @@ public GeospatialIndex withMax(int max) { * @param bits * @return this. */ + @Contract("_ -> this") public GeospatialIndex withBits(int bits) { this.bits = bits; return this; @@ -99,6 +104,7 @@ public GeospatialIndex withBits(int bits) { * @param type must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public GeospatialIndex typed(GeoSpatialIndexType type) { Assert.notNull(type, "Type must not be null"); @@ -113,6 +119,7 @@ public GeospatialIndex typed(GeoSpatialIndexType type) { * @deprecated since MongoDB server version 4.4 */ @Deprecated + @Contract("_ -> this") public GeospatialIndex withBucketSize(double bucketSize) { this.bucketSize = bucketSize; return this; @@ -122,6 +129,7 @@ public GeospatialIndex withBucketSize(double bucketSize) { * @param fieldName * @return this. */ + @Contract("_ -> this") public GeospatialIndex withAdditionalField(String fieldName) { this.additionalField = fieldName; return this; @@ -136,6 +144,7 @@ public GeospatialIndex withAdditionalField(String fieldName) { * "https://docs.mongodb.com/manual/core/index-partial/">https://docs.mongodb.com/manual/core/index-partial/ * @since 1.10 */ + @Contract("_ -> this") public GeospatialIndex partial(@Nullable IndexFilter filter) { this.filter = Optional.ofNullable(filter); @@ -152,6 +161,7 @@ public GeospatialIndex partial(@Nullable IndexFilter filter) { * @return this. * @since 2.0 */ + @Contract("_ -> this") public GeospatialIndex collation(@Nullable Collation collation) { this.collation = Optional.ofNullable(collation); 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 66d2eccb66..91195a40f4 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 @@ -27,6 +27,7 @@ import org.springframework.data.domain.Sort.Direction; import org.springframework.data.mongodb.core.index.IndexOptions.Unique; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -52,11 +53,13 @@ public Index(String key, Direction direction) { fieldSpec.put(key, direction); } + @Contract("_, _ -> this") public Index on(String key, Direction direction) { fieldSpec.put(key, direction); return this; } + @Contract("_ -> this") public Index named(String name) { this.name = name; return this; @@ -69,6 +72,7 @@ public Index named(String name) { * @see https://docs.mongodb.org/manual/core/index-unique/ */ + @Contract("-> this") public Index unique() { this.options.setUnique(Unique.YES); @@ -82,6 +86,7 @@ public Index unique() { * @see https://docs.mongodb.org/manual/core/index-sparse/ */ + @Contract("-> this") public Index sparse() { this.sparse = true; return this; @@ -92,7 +97,7 @@ public Index sparse() { * * @return this. * @since 1.5 - */ + */@Contract("-> this") public Index background() { this.background = true; @@ -107,6 +112,7 @@ public Index background() { * "https://www.mongodb.com/docs/manual/core/index-hidden/">https://www.mongodb.com/docs/manual/core/index-hidden/ * @since 4.1 */ + @Contract("-> this") public Index hidden() { options.setHidden(true); @@ -120,6 +126,7 @@ public Index hidden() { * @return this. * @since 1.5 */ + @Contract("_ -> this") public Index expire(long value) { return expire(value, TimeUnit.SECONDS); } @@ -132,6 +139,7 @@ public Index expire(long value) { * @throws IllegalArgumentException if given {@literal timeout} is {@literal null}. * @since 2.2 */ + @Contract("_ -> this") public Index expire(Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); @@ -146,6 +154,7 @@ public Index expire(Duration timeout) { * @return this. * @since 1.5 */ + @Contract("_, _ -> this") public Index expire(long value, TimeUnit unit) { Assert.notNull(unit, "TimeUnit for expiration must not be null"); @@ -162,6 +171,7 @@ public Index expire(long value, TimeUnit unit) { * "https://docs.mongodb.com/manual/core/index-partial/">https://docs.mongodb.com/manual/core/index-partial/ * @since 1.10 */ + @Contract("_ -> this") public Index partial(@Nullable IndexFilter filter) { this.filter = Optional.ofNullable(filter); @@ -178,6 +188,7 @@ public Index partial(@Nullable IndexFilter filter) { * @return this. * @since 2.0 */ + @Contract("_ -> this") public Index collation(@Nullable Collation collation) { this.collation = Optional.ofNullable(collation); 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 f8d24414f7..0b473388fb 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 @@ -23,6 +23,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -235,6 +236,7 @@ public TextIndexDefinitionBuilder() { * @param name * @return */ + @Contract("_ -> this") public TextIndexDefinitionBuilder named(String name) { this.instance.name = name; return this; @@ -246,6 +248,7 @@ public TextIndexDefinitionBuilder named(String name) { * * @return */ + @Contract("-> this") public TextIndexDefinitionBuilder onAllFields() { if (!instance.fieldSpecs.isEmpty()) { @@ -262,6 +265,7 @@ public TextIndexDefinitionBuilder onAllFields() { * @param fieldnames * @return */ + @Contract("_ -> this") public TextIndexDefinitionBuilder onFields(String... fieldnames) { for (String fieldname : fieldnames) { @@ -276,6 +280,7 @@ public TextIndexDefinitionBuilder onFields(String... fieldnames) { * @param fieldname * @return */ + @Contract("_ -> this") public TextIndexDefinitionBuilder onField(String fieldname) { return onField(fieldname, 1F); } @@ -286,6 +291,7 @@ public TextIndexDefinitionBuilder onField(String fieldname) { * @param fieldname * @return */ + @Contract("_, _ -> this") public TextIndexDefinitionBuilder onField(String fieldname, Float weight) { if (this.instance.fieldSpecs.contains(ALL_FIELDS)) { @@ -305,6 +311,7 @@ public TextIndexDefinitionBuilder onField(String fieldname, Float weight) { * @see https://docs.mongodb.org/manual/tutorial/specify-language-for-text-index/#specify-default-language-text-index */ + @Contract("_ -> this") public TextIndexDefinitionBuilder withDefaultLanguage(String language) { this.instance.defaultLanguage = language; @@ -317,6 +324,7 @@ public TextIndexDefinitionBuilder withDefaultLanguage(String language) { * @param fieldname * @return */ + @Contract("_ -> this") public TextIndexDefinitionBuilder withLanguageOverride(String fieldname) { if (StringUtils.hasText(this.instance.languageOverride)) { @@ -338,6 +346,7 @@ public TextIndexDefinitionBuilder withLanguageOverride(String fieldname) { * "https://docs.mongodb.com/manual/core/index-partial/">https://docs.mongodb.com/manual/core/index-partial/ * @since 1.10 */ + @Contract("_ -> this") public TextIndexDefinitionBuilder partial(@Nullable IndexFilter filter) { this.instance.filter = filter; @@ -349,12 +358,14 @@ public TextIndexDefinitionBuilder partial(@Nullable IndexFilter filter) { * * @since 2.2 */ + @Contract("-> this") public TextIndexDefinitionBuilder withSimpleCollation() { this.instance.collation = Collation.simple(); return this; } + @Contract("-> new") public TextIndexDefinition build() { return this.instance; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/WildcardIndex.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/WildcardIndex.java index 3780798b01..ff0a92ada1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/WildcardIndex.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/WildcardIndex.java @@ -23,6 +23,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.FieldName; +import org.springframework.lang.Contract; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -76,6 +77,7 @@ public WildcardIndex(@Nullable String path) { * * @return this. */ + @Contract("-> this") public WildcardIndex includeId() { wildcardProjection.put(FieldName.ID.name(), 1); @@ -89,6 +91,7 @@ public WildcardIndex includeId() { * @return this. */ @Override + @Contract("_ -> this") public WildcardIndex named(String name) { super.named(name); @@ -101,6 +104,7 @@ public WildcardIndex named(String name) { * @throws UnsupportedOperationException not supported for wildcard indexes. */ @Override + @Contract("-> fail") public Index unique() { throw new UnsupportedOperationException("Wildcard Index does not support 'unique'"); } @@ -111,6 +115,7 @@ public Index unique() { * @throws UnsupportedOperationException not supported for wildcard indexes. */ @Override + @Contract("-> fail") public Index expire(long seconds) { throw new UnsupportedOperationException("Wildcard Index does not support 'ttl'"); } @@ -121,6 +126,7 @@ public Index expire(long seconds) { * @throws UnsupportedOperationException not supported for wildcard indexes. */ @Override + @Contract("_, _ -> fail") public Index expire(long value, TimeUnit timeUnit) { throw new UnsupportedOperationException("Wildcard Index does not support 'ttl'"); } @@ -131,6 +137,7 @@ public Index expire(long value, TimeUnit timeUnit) { * @throws UnsupportedOperationException not supported for wildcard indexes. */ @Override + @Contract("_ -> fail") public Index expire(Duration duration) { throw new UnsupportedOperationException("Wildcard Index does not support 'ttl'"); } @@ -142,6 +149,7 @@ public Index expire(Duration duration) { * @param paths must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public WildcardIndex wildcardProjectionInclude(String... paths) { for (String path : paths) { @@ -157,6 +165,7 @@ public WildcardIndex wildcardProjectionInclude(String... paths) { * @param paths must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public WildcardIndex wildcardProjectionExclude(String... paths) { for (String path : paths) { @@ -172,6 +181,7 @@ public WildcardIndex wildcardProjectionExclude(String... paths) { * @param includeExclude must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public WildcardIndex wildcardProjection(Map includeExclude) { wildcardProjection.putAll(includeExclude); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoField.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoField.java index 80d7c120f7..881d741ee4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoField.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoField.java @@ -17,6 +17,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.mapping.FieldName.Type; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -151,6 +152,7 @@ public static class MongoFieldBuilder { * @param fieldType * @return */ + @Contract("_ -> this") public MongoFieldBuilder fieldType(FieldType fieldType) { this.type = fieldType; @@ -164,6 +166,7 @@ public MongoFieldBuilder fieldType(FieldType fieldType) { * @param fieldName * @return */ + @Contract("_ -> this") public MongoFieldBuilder name(String fieldName) { Assert.hasText(fieldName, "Field name must not be empty"); @@ -179,6 +182,7 @@ public MongoFieldBuilder name(String fieldName) { * @param path * @return */ + @Contract("_ -> this") public MongoFieldBuilder path(String path) { Assert.hasText(path, "Field path (name) must not be empty"); @@ -194,6 +198,7 @@ public MongoFieldBuilder path(String path) { * @param order * @return */ + @Contract("_ -> this") public MongoFieldBuilder order(int order) { this.order = order; @@ -205,6 +210,7 @@ public MongoFieldBuilder order(int order) { * * @return a new {@link MongoField}. */ + @Contract("-> new") public MongoField build() { Assert.notNull(name, "Name of Field must not be null"); 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 de00554240..2e5f543534 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 @@ -24,6 +24,7 @@ import org.springframework.data.mongodb.core.query.Collation; import com.mongodb.client.model.MapReduceAction; +import org.springframework.lang.Contract; /** * @author Mark Pollack @@ -65,6 +66,7 @@ public static MapReduceOptions options() { * @param limit Limit the number of objects to process * @return MapReduceOptions so that methods can be chained in a fluent API style */ + @Contract("_ -> this") public MapReduceOptions limit(int limit) { this.limit = limit; @@ -78,6 +80,7 @@ public MapReduceOptions limit(int limit) { * @param collectionName The name of the collection where the results of the map-reduce operation will be stored. * @return MapReduceOptions so that methods can be chained in a fluent API style */ + @Contract("_ -> this") public MapReduceOptions outputCollection(String collectionName) { this.outputCollection = collectionName; @@ -91,6 +94,7 @@ public MapReduceOptions outputCollection(String collectionName) { * @param outputDatabase The name of the database where the results of the map-reduce operation will be stored. * @return MapReduceOptions so that methods can be chained in a fluent API style */ + @Contract("_ -> this") public MapReduceOptions outputDatabase(@Nullable String outputDatabase) { this.outputDatabase = Optional.ofNullable(outputDatabase); @@ -105,6 +109,7 @@ public MapReduceOptions outputDatabase(@Nullable String outputDatabase) { * @return this. * @since 3.0 */ + @Contract("-> this") public MapReduceOptions actionInline() { this.mapReduceAction = null; @@ -119,6 +124,7 @@ public MapReduceOptions actionInline() { * @return this. * @since 3.0 */ + @Contract("-> this") public MapReduceOptions actionMerge() { this.mapReduceAction = MapReduceAction.MERGE; @@ -133,6 +139,7 @@ public MapReduceOptions actionMerge() { * @return this. * @since 3.0 */ + @Contract("-> this") public MapReduceOptions actionReduce() { this.mapReduceAction = MapReduceAction.REDUCE; @@ -146,6 +153,7 @@ public MapReduceOptions actionReduce() { * @return MapReduceOptions so that methods can be chained in a fluent API style * @since 3.0 */ + @Contract("-> this") public MapReduceOptions actionReplace() { this.mapReduceAction = MapReduceAction.REPLACE; @@ -159,6 +167,7 @@ public MapReduceOptions actionReplace() { * @param outputShared if true, output will be sharded based on _id key. * @return MapReduceOptions so that methods can be chained in a fluent API style */ + @Contract("_ -> this") public MapReduceOptions outputSharded(boolean outputShared) { this.outputSharded = Optional.of(outputShared); @@ -171,6 +180,7 @@ public MapReduceOptions outputSharded(boolean outputShared) { * @param finalizeFunction The finalize function. Can be a JSON string or a Spring Resource URL * @return MapReduceOptions so that methods can be chained in a fluent API style */ + @Contract("_ -> this") public MapReduceOptions finalizeFunction(@Nullable String finalizeFunction) { this.finalizeFunction = Optional.ofNullable(finalizeFunction); @@ -184,6 +194,7 @@ public MapReduceOptions finalizeFunction(@Nullable String finalizeFunction) { * @param scopeVariables variables that can be accessed from map, reduce, and finalize scripts * @return MapReduceOptions so that methods can be chained in a fluent API style */ + @Contract("_ -> this") public MapReduceOptions scopeVariables(Map scopeVariables) { this.scopeVariables = scopeVariables; @@ -197,6 +208,7 @@ public MapReduceOptions scopeVariables(Map scopeVariables) { * @param javaScriptMode if true, have the execution of map-reduce stay in JavaScript * @return MapReduceOptions so that methods can be chained in a fluent API style */ + @Contract("_ -> this") public MapReduceOptions javaScriptMode(boolean javaScriptMode) { this.jsMode = javaScriptMode; @@ -208,6 +220,7 @@ public MapReduceOptions javaScriptMode(boolean javaScriptMode) { * * @return MapReduceOptions so that methods can be chained in a fluent API style */ + @Contract("_ -> this") public MapReduceOptions verbose(boolean verbose) { this.verbose = verbose; @@ -221,6 +234,7 @@ public MapReduceOptions verbose(boolean verbose) { * @return * @since 2.0 */ + @Contract("_ -> this") public MapReduceOptions collation(@Nullable Collation collation) { this.collation = Optional.ofNullable(collation); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java index 64146bb076..e1da0b33ce 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/ChangeStreamRequest.java @@ -26,6 +26,7 @@ import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.messaging.ChangeStreamRequest.ChangeStreamRequestOptions; import org.springframework.data.mongodb.core.query.Collation; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import com.mongodb.client.model.changestream.ChangeStreamDocument; @@ -253,6 +254,7 @@ private ChangeStreamRequestBuilder() {} * @param databaseName must not be {@literal null} nor empty. * @return this. */ + @Contract("_ -> this") public ChangeStreamRequestBuilder database(String databaseName) { Assert.hasText(databaseName, "DatabaseName must not be null"); @@ -267,6 +269,7 @@ public ChangeStreamRequestBuilder database(String databaseName) { * @param collectionName must not be {@literal null} nor empty. * @return this. */ + @Contract("_ -> this") public ChangeStreamRequestBuilder collection(String collectionName) { Assert.hasText(collectionName, "CollectionName must not be null"); @@ -281,6 +284,7 @@ public ChangeStreamRequestBuilder collection(String collectionName) { * @param messageListener must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public ChangeStreamRequestBuilder publishTo( MessageListener, ? super T> messageListener) { @@ -308,6 +312,7 @@ public ChangeStreamRequestBuilder publishTo( * @see ChangeStreamOptions#getFilter() * @see ChangeStreamOptionsBuilder#filter(Aggregation) */ + @Contract("_ -> this") public ChangeStreamRequestBuilder filter(Aggregation aggregation) { Assert.notNull(aggregation, "Aggregation must not be null"); @@ -323,6 +328,7 @@ public ChangeStreamRequestBuilder filter(Aggregation aggregation) { * @return this. * @see ChangeStreamOptions#getFilter() */ + @Contract("_ -> this") public ChangeStreamRequestBuilder filter(Document... pipeline) { Assert.notNull(pipeline, "Aggregation pipeline must not be null"); @@ -340,6 +346,7 @@ public ChangeStreamRequestBuilder filter(Document... pipeline) { * @see ChangeStreamOptions#getCollation() * @see ChangeStreamOptionsBuilder#collation(Collation) */ + @Contract("_ -> this") public ChangeStreamRequestBuilder collation(Collation collation) { Assert.notNull(collation, "Collation must not be null"); @@ -357,6 +364,7 @@ public ChangeStreamRequestBuilder collation(Collation collation) { * @see ChangeStreamOptions#getResumeToken() * @see ChangeStreamOptionsBuilder#resumeToken(org.bson.BsonValue) */ + @Contract("_ -> this") public ChangeStreamRequestBuilder resumeToken(BsonValue resumeToken) { Assert.notNull(resumeToken, "Resume token not be null"); @@ -373,6 +381,7 @@ public ChangeStreamRequestBuilder resumeToken(BsonValue resumeToken) { * @see ChangeStreamOptions#getResumeTimestamp() * @see ChangeStreamOptionsBuilder#resumeAt(java.time.Instant) */ + @Contract("_ -> this") public ChangeStreamRequestBuilder resumeAt(Instant clusterTime) { Assert.notNull(clusterTime, "ClusterTime must not be null"); @@ -388,6 +397,7 @@ public ChangeStreamRequestBuilder resumeAt(Instant clusterTime) { * @return this. * @since 2.2 */ + @Contract("_ -> this") public ChangeStreamRequestBuilder resumeAfter(BsonValue resumeToken) { Assert.notNull(resumeToken, "ResumeToken must not be null"); @@ -403,6 +413,7 @@ public ChangeStreamRequestBuilder resumeAfter(BsonValue resumeToken) { * @return this. * @since 2.2 */ + @Contract("_ -> this") public ChangeStreamRequestBuilder startAfter(BsonValue resumeToken) { Assert.notNull(resumeToken, "ResumeToken must not be null"); @@ -418,6 +429,7 @@ public ChangeStreamRequestBuilder startAfter(BsonValue resumeToken) { * @see ChangeStreamOptions#getFullDocumentLookup() * @see ChangeStreamOptionsBuilder#fullDocumentLookup(FullDocument) */ + @Contract("_ -> this") public ChangeStreamRequestBuilder fullDocumentLookup(FullDocument lookup) { Assert.notNull(lookup, "FullDocument not be null"); @@ -434,6 +446,7 @@ public ChangeStreamRequestBuilder fullDocumentLookup(FullDocument lookup) { * @see ChangeStreamOptions#getFullDocumentBeforeChangeLookup() * @see ChangeStreamOptionsBuilder#fullDocumentBeforeChangeLookup(FullDocumentBeforeChange) */ + @Contract("_ -> this") public ChangeStreamRequestBuilder fullDocumentBeforeChangeLookup(FullDocumentBeforeChange lookup) { Assert.notNull(lookup, "FullDocumentBeforeChange not be null"); @@ -448,6 +461,7 @@ public ChangeStreamRequestBuilder fullDocumentBeforeChangeLookup(FullDocument * @param timeout must not be {@literal null}. * @since 3.0 */ + @Contract("_ -> this") public ChangeStreamRequestBuilder maxAwaitTime(Duration timeout) { Assert.notNull(timeout, "timeout not be null"); @@ -459,6 +473,7 @@ public ChangeStreamRequestBuilder maxAwaitTime(Duration timeout) { /** * @return the build {@link ChangeStreamRequest}. */ + @Contract("-> new") public ChangeStreamRequest build() { Assert.notNull(listener, "MessageListener must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/Message.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/Message.java index 125045c5e0..e7aa5b036d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/Message.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/Message.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core.messaging; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -159,6 +160,7 @@ public static class MessagePropertiesBuilder { * @param dbName must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public MessagePropertiesBuilder databaseName(String dbName) { Assert.notNull(dbName, "Database name must not be null"); @@ -171,6 +173,7 @@ public MessagePropertiesBuilder databaseName(String dbName) { * @param collectionName must not be {@literal null}. * @return this */ + @Contract("_ -> this") public MessagePropertiesBuilder collectionName(String collectionName) { Assert.notNull(collectionName, "Collection name must not be null"); @@ -182,6 +185,7 @@ public MessagePropertiesBuilder collectionName(String collectionName) { /** * @return the built {@link MessageProperties}. */ + @Contract("-> new") public MessageProperties build() { MessageProperties properties = new MessageProperties(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java index 3fffcad894..92e23ff847 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/TailableCursorRequest.java @@ -22,6 +22,7 @@ import org.springframework.data.mongodb.core.messaging.SubscriptionRequest.RequestOptions; import org.springframework.data.mongodb.core.messaging.TailableCursorRequest.TailableCursorRequestOptions.TailableCursorRequestOptionsBuilder; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -164,6 +165,7 @@ private TailableCursorRequestOptionsBuilder() {} * @param collection must not be {@literal null} nor {@literal empty}. * @return this. */ + @Contract("_ -> this") public TailableCursorRequestOptionsBuilder collection(String collection) { Assert.hasText(collection, "Collection must not be null nor empty"); @@ -178,6 +180,7 @@ public TailableCursorRequestOptionsBuilder collection(String collection) { * @param filter the {@link Query } to apply for filtering events. Must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public TailableCursorRequestOptionsBuilder filter(Query filter) { Assert.notNull(filter, "Filter must not be null"); @@ -189,6 +192,7 @@ public TailableCursorRequestOptionsBuilder filter(Query filter) { /** * @return the built {@link TailableCursorRequestOptions}. */ + @Contract("-> new") public TailableCursorRequestOptions build() { TailableCursorRequestOptions options = new TailableCursorRequestOptions(); @@ -221,6 +225,7 @@ private TailableCursorRequestBuilder() {} * @param collectionName must not be {@literal null} nor empty. * @return this. */ + @Contract("_ -> this") public TailableCursorRequestBuilder collection(String collectionName) { Assert.hasText(collectionName, "CollectionName must not be null"); @@ -235,6 +240,7 @@ public TailableCursorRequestBuilder collection(String collectionName) { * @param messageListener must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public TailableCursorRequestBuilder publishTo(MessageListener messageListener) { Assert.notNull(messageListener, "MessageListener must not be null"); @@ -249,6 +255,7 @@ public TailableCursorRequestBuilder publishTo(MessageListener this") public TailableCursorRequestBuilder filter(Query filter) { Assert.notNull(filter, "Filter must not be null"); @@ -260,6 +267,7 @@ public TailableCursorRequestBuilder filter(Query filter) { /** * @return the build {@link ChangeStreamRequest}. */ + @Contract("_ -> new") public TailableCursorRequest build() { Assert.notNull(listener, "MessageListener must not be null"); 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 b7d3455677..fd81030275 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 @@ -19,6 +19,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -102,6 +103,7 @@ public BasicQuery(Query query) { } @Override + @Contract("_ -> this") public Query addCriteria(CriteriaDefinition criteria) { this.queryObject.putAll(criteria.getCriteriaObject()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java index 6fd9edcf64..9ca1e1f1b8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java @@ -20,6 +20,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; /** * @author Thomas Risberg @@ -43,48 +44,56 @@ public BasicUpdate(Document updateObject) { } @Override + @Contract("_, _ -> this") public Update set(String key, @Nullable Object value) { updateObject.put("$set", Collections.singletonMap(key, value)); return this; } @Override + @Contract("_ -> this") public Update unset(String key) { updateObject.put("$unset", Collections.singletonMap(key, 1)); return this; } @Override + @Contract("_, _ -> this") public Update inc(String key, Number inc) { updateObject.put("$inc", Collections.singletonMap(key, inc)); return this; } @Override + @Contract("_, _ -> this") public Update push(String key, @Nullable Object value) { updateObject.put("$push", Collections.singletonMap(key, value)); return this; } @Override + @Contract("_, _ -> this") public Update addToSet(String key, @Nullable Object value) { updateObject.put("$addToSet", Collections.singletonMap(key, value)); return this; } @Override + @Contract("_, _ -> this") public Update pop(String key, Position pos) { updateObject.put("$pop", Collections.singletonMap(key, (pos == Position.FIRST ? -1 : 1))); return this; } @Override + @Contract("_, _ -> this") public Update pull(String key, @Nullable Object value) { updateObject.put("$pull", Collections.singletonMap(key, value)); return this; } @Override + @Contract("_, _ -> this") public Update pullAll(String key, Object[] values) { Document keyValue = new Document(); keyValue.put(key, Arrays.copyOf(values, values.length)); @@ -93,6 +102,7 @@ public Update pullAll(String key, Object[] values) { } @Override + @Contract("_, _ -> this") public Update rename(String oldName, String newName) { updateObject.put("$rename", Collections.singletonMap(oldName, newName)); return this; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java index 9ca6ce9099..217e669883 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Collation.java @@ -181,6 +181,7 @@ public static Collation from(Document source) { * @param strength comparison level. * @return new {@link Collation}. */ + @Contract("_ -> new") public Collation strength(int strength) { ComparisonLevel current = this.strength.orElseGet(() -> new ICUComparisonLevel(strength)); @@ -193,6 +194,7 @@ public Collation strength(int strength) { * @param comparisonLevel must not be {@literal null}. * @return new {@link Collation} */ + @Contract("_ -> new") public Collation strength(ComparisonLevel comparisonLevel) { Collation newInstance = copy(); @@ -206,6 +208,7 @@ public Collation strength(ComparisonLevel comparisonLevel) { * @param caseLevel use {@literal true} to enable {@code caseLevel} comparison. * @return new {@link Collation}. */ + @Contract("_ -> new") public Collation caseLevel(boolean caseLevel) { ComparisonLevel strengthValue = strength.orElseGet(ComparisonLevel::primary); @@ -219,6 +222,7 @@ public Collation caseLevel(boolean caseLevel) { * @param caseFirst must not be {@literal null}. * @return new instance of {@link Collation}. */ + @Contract("_ -> new") public Collation caseFirst(String caseFirst) { return caseFirst(new CaseFirst(caseFirst)); } @@ -229,6 +233,7 @@ public Collation caseFirst(String caseFirst) { * @param sort must not be {@literal null}. * @return new instance of {@link Collation}. */ + @Contract("_ -> new") public Collation caseFirst(CaseFirst sort) { ComparisonLevel strengthValue = strength.orElseGet(ComparisonLevel::tertiary); @@ -240,6 +245,7 @@ public Collation caseFirst(CaseFirst sort) { * * @return new {@link Collation}. */ + @Contract("-> new") public Collation numericOrderingEnabled() { return numericOrdering(true); } @@ -249,6 +255,7 @@ public Collation numericOrderingEnabled() { * * @return new {@link Collation}. */ + @Contract("-> new") public Collation numericOrderingDisabled() { return numericOrdering(false); } @@ -258,6 +265,7 @@ public Collation numericOrderingDisabled() { * * @return new {@link Collation}. */ + @Contract("_ -> new") public Collation numericOrdering(boolean flag) { Collation newInstance = copy(); @@ -272,6 +280,7 @@ public Collation numericOrdering(boolean flag) { * @param alternate must not be {@literal null}. * @return new {@link Collation}. */ + @Contract("_ -> new") public Collation alternate(String alternate) { Alternate instance = this.alternate.orElseGet(() -> new Alternate(alternate, Optional.empty())); @@ -285,6 +294,7 @@ public Collation alternate(String alternate) { * @param alternate must not be {@literal null}. * @return new {@link Collation}. */ + @Contract("_ -> new") public Collation alternate(Alternate alternate) { Collation newInstance = copy(); @@ -297,6 +307,7 @@ public Collation alternate(Alternate alternate) { * * @return new {@link Collation}. */ + @Contract("_ -> new") public Collation backwardDiacriticSort() { return backwards(true); } @@ -306,6 +317,7 @@ public Collation backwardDiacriticSort() { * * @return new {@link Collation}. */ + @Contract("-> new") public Collation forwardDiacriticSort() { return backwards(false); } @@ -316,6 +328,7 @@ public Collation forwardDiacriticSort() { * @param backwards must not be {@literal null}. * @return new {@link Collation}. */ + @Contract("_ -> new") public Collation backwards(boolean backwards) { Collation newInstance = copy(); @@ -328,6 +341,7 @@ public Collation backwards(boolean backwards) { * * @return new {@link Collation}. */ + @Contract("-> new") public Collation normalizationEnabled() { return normalization(true); } @@ -337,6 +351,7 @@ public Collation normalizationEnabled() { * * @return new {@link Collation}. */ + @Contract("-> new") public Collation normalizationDisabled() { return normalization(false); } @@ -347,6 +362,7 @@ public Collation normalizationDisabled() { * @param normalization must not be {@literal null}. * @return new {@link Collation}. */ + @Contract("_ -> new") public Collation normalization(boolean normalization) { Collation newInstance = copy(); @@ -360,6 +376,7 @@ public Collation normalization(boolean normalization) { * @param maxVariable must not be {@literal null}. * @return new {@link Collation}. */ + @Contract("_ -> new") public Collation maxVariable(String maxVariable) { Alternate alternateValue = alternate.orElseGet(Alternate::shifted); 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 aa1068ca5b..547c6965ce 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 @@ -46,6 +46,7 @@ import org.springframework.data.mongodb.core.schema.JsonSchemaProperty; import org.springframework.data.mongodb.core.schema.MongoJsonSchema; import org.springframework.data.mongodb.util.RegexFlags; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -184,6 +185,7 @@ public static Criteria expr(MongoExpression expression) { * * @return new instance of {@link Criteria}. */ + @Contract("_ -> new") public Criteria and(String key) { return new Criteria(this.criteriaChain, key); } @@ -194,6 +196,7 @@ public Criteria and(String key) { * @param value can be {@literal null}. * @return this. */ + @Contract("_ -> this") public Criteria is(@Nullable Object value) { if (!NOT_SET.equals(isValue)) { @@ -221,6 +224,7 @@ public Criteria is(@Nullable Object value) { * Missing Fields: Equality Filter * @since 3.3 */ + @Contract("_ -> this") public Criteria isNull() { return is(null); } @@ -237,6 +241,7 @@ public Criteria isNull() { * Fields: Type Check * @since 3.3 */ + @Contract("_ -> this") public Criteria isNullValue() { criteria.put("$type", BsonType.NULL.getValue()); @@ -254,6 +259,7 @@ private boolean lastOperatorWasNot() { * @return this. * @see MongoDB Query operator: $ne */ + @Contract("_ -> this") public Criteria ne(@Nullable Object value) { criteria.put("$ne", value); return this; @@ -266,6 +272,7 @@ public Criteria ne(@Nullable Object value) { * @return this. * @see MongoDB Query operator: $lt */ + @Contract("_ -> this") public Criteria lt(Object value) { criteria.put("$lt", value); return this; @@ -278,6 +285,7 @@ public Criteria lt(Object value) { * @return this. * @see MongoDB Query operator: $lte */ + @Contract("_ -> this") public Criteria lte(Object value) { criteria.put("$lte", value); return this; @@ -290,6 +298,7 @@ public Criteria lte(Object value) { * @return this. * @see MongoDB Query operator: $gt */ + @Contract("_ -> this") public Criteria gt(Object value) { criteria.put("$gt", value); return this; @@ -302,6 +311,7 @@ public Criteria gt(Object value) { * @return this. * @see MongoDB Query operator: $gte */ + @Contract("_ -> this") public Criteria gte(Object value) { criteria.put("$gte", value); return this; @@ -314,6 +324,7 @@ public Criteria gte(Object value) { * @return this. * @see MongoDB Query operator: $in */ + @Contract("_ -> this") public Criteria in(@Nullable Object ... values) { if (values.length > 1 && values[1] instanceof Collection) { throw new InvalidMongoDbApiUsageException( @@ -330,6 +341,7 @@ public Criteria in(@Nullable Object ... values) { * @return this. * @see MongoDB Query operator: $in */ + @Contract("_ -> this") public Criteria in(Collection values) { criteria.put("$in", values); return this; @@ -342,6 +354,7 @@ public Criteria in(Collection values) { * @return this. * @see MongoDB Query operator: $nin */ + @Contract("_ -> this") public Criteria nin(Object... values) { return nin(Arrays.asList(values)); } @@ -353,6 +366,7 @@ public Criteria nin(Object... values) { * @return this. * @see MongoDB Query operator: $nin */ + @Contract("_ -> this") public Criteria nin(Collection values) { criteria.put("$nin", values); return this; @@ -366,6 +380,7 @@ public Criteria nin(Collection values) { * @return this. * @see MongoDB Query operator: $mod */ + @Contract("_ -> this") public Criteria mod(Number value, Number remainder) { List l = new ArrayList<>(2); l.add(value); @@ -381,6 +396,7 @@ public Criteria mod(Number value, Number remainder) { * @return this. * @see MongoDB Query operator: $all */ + @Contract("_ -> this") public Criteria all(Object... values) { return all(Arrays.asList(values)); } @@ -392,6 +408,7 @@ public Criteria all(Object... values) { * @return this. * @see MongoDB Query operator: $all */ + @Contract("_ -> this") public Criteria all(Collection values) { criteria.put("$all", values); return this; @@ -404,6 +421,7 @@ public Criteria all(Collection values) { * @return this. * @see MongoDB Query operator: $size */ + @Contract("_ -> this") public Criteria size(int size) { criteria.put("$size", size); return this; @@ -416,6 +434,7 @@ public Criteria size(int size) { * @return this. * @see MongoDB Query operator: $exists */ + @Contract("_ -> this") public Criteria exists(boolean value) { criteria.put("$exists", value); return this; @@ -431,6 +450,7 @@ public Criteria exists(boolean value) { * $sampleRate * @since 3.3 */ + @Contract("_ -> this") public Criteria sampleRate(double sampleRate) { Assert.isTrue(sampleRate >= 0, "The sample rate must be greater than zero"); @@ -447,6 +467,7 @@ public Criteria sampleRate(double sampleRate) { * @return this. * @see MongoDB Query operator: $type */ + @Contract("_ -> this") public Criteria type(int typeNumber) { criteria.put("$type", typeNumber); return this; @@ -460,6 +481,7 @@ public Criteria type(int typeNumber) { * @since 2.1 * @see MongoDB Query operator: $type */ + @Contract("_ -> this") public Criteria type(Type... types) { Assert.notNull(types, "Types must not be null"); @@ -476,6 +498,7 @@ public Criteria type(Type... types) { * @since 3.2 * @see MongoDB Query operator: $type */ + @Contract("_ -> this") public Criteria type(Collection types) { Assert.notNull(types, "Types must not be null"); @@ -490,6 +513,7 @@ public Criteria type(Collection types) { * @return this. * @see MongoDB Query operator: $not */ + @Contract("-> this") public Criteria not() { return not(null); } @@ -501,6 +525,7 @@ public Criteria not() { * @return this. * @see MongoDB Query operator: $not */ + @Contract("_ -> this") private Criteria not(@Nullable Object value) { criteria.put("$not", value); return this; @@ -513,6 +538,7 @@ private Criteria not(@Nullable Object value) { * @return this. * @see MongoDB Query operator: $regex */ + @Contract("_ -> this") public Criteria regex(String regex) { return regex(regex, null); } @@ -525,6 +551,7 @@ public Criteria regex(String regex) { * @return this. * @see MongoDB Query operator: $regex */ + @Contract("_, _ -> this") public Criteria regex(String regex, @Nullable String options) { return regex(toPattern(regex, options)); } @@ -535,6 +562,7 @@ public Criteria regex(String regex, @Nullable String options) { * @param pattern must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public Criteria regex(Pattern pattern) { Assert.notNull(pattern, "Pattern must not be null"); @@ -553,6 +581,7 @@ public Criteria regex(Pattern pattern) { * @param regex must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public Criteria regex(BsonRegularExpression regex) { if (lastOperatorWasNot()) { @@ -581,6 +610,7 @@ private Pattern toPattern(String regex, @Nullable String options) { * @see MongoDB Query operator: * $centerSphere */ + @Contract("_ -> this") public Criteria withinSphere(Circle circle) { Assert.notNull(circle, "Circle must not be null"); @@ -597,6 +627,7 @@ public Criteria withinSphere(Circle circle) { * @see MongoDB Query operator: * $geoWithin */ + @Contract("_ -> this") public Criteria within(Shape shape) { Assert.notNull(shape, "Shape must not be null"); @@ -612,6 +643,7 @@ public Criteria within(Shape shape) { * @return this. * @see MongoDB Query operator: $near */ + @Contract("_ -> this") public Criteria near(Point point) { Assert.notNull(point, "Point must not be null"); @@ -629,6 +661,7 @@ public Criteria near(Point point) { * @see MongoDB Query operator: * $nearSphere */ + @Contract("_ -> this") public Criteria nearSphere(Point point) { Assert.notNull(point, "Point must not be null"); @@ -646,6 +679,7 @@ public Criteria nearSphere(Point point) { * @since 1.8 */ @SuppressWarnings("rawtypes") + @Contract("_ -> this") public Criteria intersects(GeoJson geoJson) { Assert.notNull(geoJson, "GeoJson must not be null"); @@ -665,6 +699,7 @@ public Criteria intersects(GeoJson geoJson) { * @see MongoDB Query operator: * $maxDistance */ + @Contract("_ -> this") public Criteria maxDistance(double maxDistance) { if (createNearCriteriaForCommand("$near", "$maxDistance", maxDistance) @@ -687,6 +722,7 @@ public Criteria maxDistance(double maxDistance) { * @return this. * @since 1.7 */ + @Contract("_ -> this") public Criteria minDistance(double minDistance) { if (createNearCriteriaForCommand("$near", "$minDistance", minDistance) @@ -706,6 +742,7 @@ public Criteria minDistance(double minDistance) { * @see MongoDB Query operator: * $elemMatch */ + @Contract("_ -> this") public Criteria elemMatch(Criteria criteria) { this.criteria.put("$elemMatch", criteria.getCriteriaObject()); return this; @@ -718,6 +755,7 @@ public Criteria elemMatch(Criteria criteria) { * @return this. * @since 1.8 */ + @Contract("_ -> this") public Criteria alike(Example sample) { if (StringUtils.hasText(this.getKey())) { @@ -745,6 +783,7 @@ public Criteria alike(Example sample) { * @see MongoDB Query operator: * $jsonSchema */ + @Contract("_ -> this") public Criteria andDocumentStructureMatches(MongoJsonSchema schema) { Assert.notNull(schema, "Schema must not be null"); @@ -776,6 +815,7 @@ public BitwiseCriteriaOperators bits() { * @param criteria must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public Criteria orOperator(Criteria... criteria) { Assert.notNull(criteria, "Criteria must not be null"); @@ -793,6 +833,7 @@ public Criteria orOperator(Criteria... criteria) { * @return this. * @since 3.2 */ + @Contract("_ -> this") public Criteria orOperator(Collection criteria) { Assert.notNull(criteria, "Criteria must not be null"); @@ -810,6 +851,7 @@ public Criteria orOperator(Collection criteria) { * @param criteria must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public Criteria norOperator(Criteria... criteria) { Assert.notNull(criteria, "Criteria must not be null"); @@ -827,6 +869,7 @@ public Criteria norOperator(Criteria... criteria) { * @return this. * @since 3.2 */ + @Contract("_ -> this") public Criteria norOperator(Collection criteria) { Assert.notNull(criteria, "Criteria must not be null"); @@ -844,6 +887,7 @@ public Criteria norOperator(Collection criteria) { * @param criteria must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public Criteria andOperator(Criteria... criteria) { Assert.notNull(criteria, "Criteria must not be null"); @@ -861,6 +905,7 @@ public Criteria andOperator(Criteria... criteria) { * @return this. * @since 3.2 */ + @Contract("_ -> this") public Criteria andOperator(Collection criteria) { Assert.notNull(criteria, "Criteria must not be null"); 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 f8bd8fa897..9775fefdb0 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 @@ -24,6 +24,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.MongoExpression; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -52,6 +53,7 @@ public class Field { * @param field the document field name to be included. * @return {@code this} field projection instance. */ + @Contract("_ -> this") public Field include(String field) { Assert.notNull(field, "Key must not be null"); @@ -111,6 +113,7 @@ public FieldProjectionExpression project(MongoExpression expression) { * @return new instance of {@link FieldProjectionExpression}. * @since 3.2 */ + @Contract("_, _ -> this") public Field projectAs(MongoExpression expression, String field) { criteria.put(field, expression); @@ -124,6 +127,7 @@ public Field projectAs(MongoExpression expression, String field) { * @return {@code this} field projection instance. * @since 3.1 */ + @Contract("_ -> this") public Field include(String... fields) { return include(Arrays.asList(fields)); } @@ -135,6 +139,7 @@ public Field include(String... fields) { * @return {@code this} field projection instance. * @since 4.4 */ + @Contract("_ -> this") public Field include(Collection fields) { Assert.notNull(fields, "Keys must not be null"); @@ -149,6 +154,7 @@ public Field include(Collection fields) { * @param field the document field name to be excluded. * @return {@code this} field projection instance. */ + @Contract("_ -> this") public Field exclude(String field) { Assert.notNull(field, "Key must not be null"); @@ -165,6 +171,7 @@ public Field exclude(String field) { * @return {@code this} field projection instance. * @since 3.1 */ + @Contract("_ -> this") public Field exclude(String... fields) { return exclude(Arrays.asList(fields)); } @@ -176,6 +183,7 @@ public Field exclude(String... fields) { * @return {@code this} field projection instance. * @since 4.4 */ + @Contract("_ -> this") public Field exclude(Collection fields) { Assert.notNull(fields, "Keys must not be null"); @@ -191,6 +199,7 @@ public Field exclude(Collection fields) { * @param size the number of elements to include. * @return {@code this} field projection instance. */ + @Contract("_, _ -> this") public Field slice(String field, int size) { Assert.notNull(field, "Key must not be null"); @@ -209,12 +218,14 @@ public Field slice(String field, int size) { * @param size the number of elements to include. * @return {@code this} field projection instance. */ + @Contract("_, _, _ -> this") public Field slice(String field, int offset, int size) { slices.put(field, Arrays.asList(offset, size)); return this; } + @Contract("_, _ -> this") public Field elemMatch(String field, Criteria elemMatchCriteria) { elemMatches.put(field, elemMatchCriteria); @@ -229,6 +240,7 @@ public Field elemMatch(String field, Criteria elemMatchCriteria) { * @param value * @return {@code this} field projection instance. */ + @Contract("_, _ -> this") public Field position(String field, int value) { Assert.hasText(field, "DocumentField must not be null or empty"); 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 b9ccec1067..6dad07b8cb 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 @@ -28,6 +28,7 @@ import org.springframework.data.mongodb.core.ReadConcernAware; import org.springframework.data.mongodb.core.ReadPreferenceAware; import org.springframework.data.mongodb.core.geo.GeoJsonPoint; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -278,6 +279,7 @@ public Metric getMetric() { * @return * @since 2.2 */ + @Contract("_ -> this") public NearQuery limit(long limit) { this.limit = limit; return this; @@ -289,6 +291,7 @@ public NearQuery limit(long limit) { * @param skip * @return */ + @Contract("_ -> this") public NearQuery skip(long skip) { this.skip = skip; return this; @@ -300,6 +303,7 @@ public NearQuery skip(long skip) { * @param pageable must not be {@literal null} * @return */ + @Contract("_ -> this") public NearQuery with(Pageable pageable) { Assert.notNull(pageable, "Pageable must not be 'null'"); @@ -323,6 +327,7 @@ public NearQuery with(Pageable pageable) { * @param maxDistance * @return */ + @Contract("_ -> this") public NearQuery maxDistance(double maxDistance) { return maxDistance(new Distance(maxDistance, getMetric())); } @@ -335,6 +340,7 @@ public NearQuery maxDistance(double maxDistance) { * @param metric must not be {@literal null}. * @return */ + @Contract("_, _ -> this") public NearQuery maxDistance(double maxDistance, Metric metric) { Assert.notNull(metric, "Metric must not be null"); @@ -349,6 +355,7 @@ public NearQuery maxDistance(double maxDistance, Metric metric) { * @param distance must not be {@literal null}. * @return */ + @Contract("_ -> this") public NearQuery maxDistance(Distance distance) { Assert.notNull(distance, "Distance must not be null"); @@ -379,6 +386,7 @@ public NearQuery maxDistance(Distance distance) { * @return * @since 1.7 */ + @Contract("_ -> this") public NearQuery minDistance(double minDistance) { return minDistance(new Distance(minDistance, getMetric())); } @@ -392,6 +400,7 @@ public NearQuery minDistance(double minDistance) { * @return * @since 1.7 */ + @Contract("_, _ -> this") public NearQuery minDistance(double minDistance, Metric metric) { Assert.notNull(metric, "Metric must not be null"); @@ -407,6 +416,7 @@ public NearQuery minDistance(double minDistance, Metric metric) { * @return * @since 1.7 */ + @Contract("_ -> this") public NearQuery minDistance(Distance distance) { Assert.notNull(distance, "Distance must not be null"); @@ -448,6 +458,7 @@ public NearQuery minDistance(Distance distance) { * @param distanceMultiplier * @return */ + @Contract("_ -> this") public NearQuery distanceMultiplier(double distanceMultiplier) { this.metric = new CustomMetric(distanceMultiplier); @@ -460,6 +471,7 @@ public NearQuery distanceMultiplier(double distanceMultiplier) { * @param spherical * @return */ + @Contract("_ -> this") public NearQuery spherical(boolean spherical) { this.spherical = spherical; return this; @@ -480,6 +492,7 @@ public boolean isSpherical() { * * @return */ + @Contract("-> this") public NearQuery inKilometers() { return adaptMetric(Metrics.KILOMETERS); } @@ -490,6 +503,7 @@ public NearQuery inKilometers() { * * @return */ + @Contract("-> this") public NearQuery inMiles() { return adaptMetric(Metrics.MILES); } @@ -502,6 +516,7 @@ public NearQuery inMiles() { * passed. * @return */ + @Contract("_ -> this") public NearQuery in(@Nullable Metric metric) { return adaptMetric(metric == null ? Metrics.NEUTRAL : metric); } @@ -512,6 +527,7 @@ public NearQuery in(@Nullable Metric metric) { * * @param metric */ + @Contract("_ -> this") private NearQuery adaptMetric(Metric metric) { if (metric != Metrics.NEUTRAL) { @@ -528,6 +544,7 @@ private NearQuery adaptMetric(Metric metric) { * @param query must not be {@literal null}. * @return */ + @Contract("_ -> this") public NearQuery query(Query query) { Assert.notNull(query, "Cannot apply 'null' query on NearQuery"); @@ -566,6 +583,7 @@ public NearQuery query(Query query) { * @return this. * @since 4.1 */ + @Contract("_ -> this") public NearQuery withReadConcern(ReadConcern readConcern) { Assert.notNull(readConcern, "ReadConcern must not be null"); @@ -581,6 +599,7 @@ public NearQuery withReadConcern(ReadConcern readConcern) { * @return this. * @since 4.1 */ + @Contract("_ -> this") public NearQuery withReadPreference(ReadPreference readPreference) { Assert.notNull(readPreference, "ReadPreference must not be null"); @@ -597,9 +616,8 @@ public NearQuery withReadPreference(ReadPreference readPreference) { * @since 4.1 * @see ReadConcernAware */ - @Nullable @Override - public ReadConcern getReadConcern() { + public @Nullable ReadConcern getReadConcern() { if (query != null && query.hasReadConcern()) { return query.getReadConcern(); 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 6adb1afdde..47ce615fe3 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 @@ -15,8 +15,9 @@ */ package org.springframework.data.mongodb.core.query; -import static org.springframework.data.mongodb.core.query.SerializationUtils.*; -import static org.springframework.util.ObjectUtils.*; +import static org.springframework.data.mongodb.core.query.SerializationUtils.serializeToJsonSafely; +import static org.springframework.util.ObjectUtils.nullSafeEquals; +import static org.springframework.util.ObjectUtils.nullSafeHashCode; import java.time.Duration; import java.util.ArrayList; @@ -43,6 +44,7 @@ import org.springframework.data.mongodb.core.ReadPreferenceAware; import org.springframework.data.mongodb.core.query.Meta.CursorOption; import org.springframework.data.mongodb.util.BsonUtils; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import com.mongodb.ReadConcern; @@ -123,6 +125,7 @@ public Query(CriteriaDefinition criteriaDefinition) { * @return this. * @since 1.6 */ + @Contract("_ -> this") public Query addCriteria(CriteriaDefinition criteriaDefinition) { Assert.notNull(criteriaDefinition, "CriteriaDefinition must not be null"); @@ -157,6 +160,7 @@ public Field fields() { * @param skip number of documents to skip. Use {@literal zero} or a {@literal negative} value to avoid skipping. * @return this. */ + @Contract("_ -> this") public Query skip(long skip) { this.skip = skip; return this; @@ -169,6 +173,7 @@ public Query skip(long skip) { * @param limit number of documents to return. Use {@literal zero} or {@literal negative} for unlimited. * @return this. */ + @Contract("_ -> this") public Query limit(int limit) { this.limit = limit > 0 ? Limit.of(limit) : Limit.unlimited(); return this; @@ -181,6 +186,7 @@ public Query limit(int limit) { * @return this. * @since 4.2 */ + @Contract("_ -> this") public Query limit(Limit limit) { Assert.notNull(limit, "Limit must not be null"); @@ -202,6 +208,7 @@ public Query limit(Limit limit) { * @return this. * @see Document#parse(String) */ + @Contract("_ -> this") public Query withHint(String hint) { Assert.hasText(hint, "Hint must not be empty or null"); @@ -216,6 +223,7 @@ public Query withHint(String hint) { * @return this. * @since 3.1 */ + @Contract("_ -> this") public Query withReadConcern(ReadConcern readConcern) { Assert.notNull(readConcern, "ReadConcern must not be null"); @@ -230,6 +238,7 @@ public Query withReadConcern(ReadConcern readConcern) { * @return this. * @since 4.1 */ + @Contract("_ -> this") public Query withReadPreference(ReadPreference readPreference) { Assert.notNull(readPreference, "ReadPreference must not be null"); @@ -269,6 +278,7 @@ public boolean hasReadPreference() { * @return this. * @since 2.2 */ + @Contract("_ -> this") public Query withHint(Document hint) { Assert.notNull(hint, "Hint must not be null"); @@ -283,6 +293,7 @@ public Query withHint(Document hint) { * @param pageable must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public Query with(Pageable pageable) { if (pageable.isPaged()) { @@ -299,6 +310,7 @@ public Query with(Pageable pageable) { * @param position must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public Query with(ScrollPosition position) { Assert.notNull(position, "ScrollPosition must not be null"); @@ -320,6 +332,7 @@ public Query with(ScrollPosition position) { * @param position must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public Query with(OffsetScrollPosition position) { Assert.notNull(position, "ScrollPosition must not be null"); @@ -335,6 +348,7 @@ public Query with(OffsetScrollPosition position) { * @param position must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public Query with(KeysetScrollPosition position) { Assert.notNull(position, "ScrollPosition must not be null"); @@ -359,6 +373,7 @@ public boolean hasKeyset() { * @param sort must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public Query with(Sort sort) { Assert.notNull(sort, "Sort must not be null"); @@ -392,6 +407,7 @@ public Set> getRestrictedTypes() { * @param additionalTypes may not be {@literal null} * @return this. */ + @Contract("_, _ -> this") public Query restrict(Class type, Class... additionalTypes) { Assert.notNull(type, "Type must not be null"); @@ -517,6 +533,7 @@ public String getHint() { * @see Meta#setMaxTimeMsec(long) * @since 1.6 */ + @Contract("_ -> this") public Query maxTimeMsec(long maxTimeMsec) { meta.setMaxTimeMsec(maxTimeMsec); @@ -529,6 +546,7 @@ public Query maxTimeMsec(long maxTimeMsec) { * @see Meta#setMaxTime(Duration) * @since 2.1 */ + @Contract("_ -> this") public Query maxTime(Duration timeout) { meta.setMaxTime(timeout); @@ -543,6 +561,7 @@ public Query maxTime(Duration timeout) { * @see Meta#setComment(String) * @since 1.6 */ + @Contract("_ -> this") public Query comment(String comment) { meta.setComment(comment); @@ -561,6 +580,7 @@ public Query comment(String comment) { * @see Meta#setAllowDiskUse(Boolean) * @since 3.2 */ + @Contract("_ -> this") public Query allowDiskUse(boolean allowDiskUse) { meta.setAllowDiskUse(allowDiskUse); @@ -577,6 +597,7 @@ public Query allowDiskUse(boolean allowDiskUse) { * @see Meta#setCursorBatchSize(int) * @since 2.1 */ + @Contract("_ -> this") public Query cursorBatchSize(int batchSize) { meta.setCursorBatchSize(batchSize); @@ -588,6 +609,7 @@ public Query cursorBatchSize(int batchSize) { * @see org.springframework.data.mongodb.core.query.Meta.CursorOption#NO_TIMEOUT * @since 1.10 */ + @Contract("-> this") public Query noCursorTimeout() { meta.addFlag(Meta.CursorOption.NO_TIMEOUT); @@ -599,6 +621,7 @@ public Query noCursorTimeout() { * @see org.springframework.data.mongodb.core.query.Meta.CursorOption#EXHAUST * @since 1.10 */ + @Contract("-> this") public Query exhaust() { meta.addFlag(Meta.CursorOption.EXHAUST); @@ -612,6 +635,7 @@ public Query exhaust() { * @see org.springframework.data.mongodb.core.query.Meta.CursorOption#SECONDARY_READS * @since 3.0.2 */ + @Contract("-> this") public Query allowSecondaryReads() { meta.addFlag(Meta.CursorOption.SECONDARY_READS); @@ -623,6 +647,7 @@ public Query allowSecondaryReads() { * @see org.springframework.data.mongodb.core.query.Meta.CursorOption#PARTIAL * @since 1.10 */ + @Contract("-> this") public Query partialResults() { meta.addFlag(Meta.CursorOption.PARTIAL); @@ -654,6 +679,7 @@ public void setMeta(Meta meta) { * @return this. * @since 2.0 */ + @Contract("_ -> this") public Query collation(@Nullable Collation collation) { this.collation = Optional.ofNullable(collation); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Term.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Term.java index d8d7157182..cc87434178 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Term.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Term.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core.query; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.ObjectUtils; /** @@ -61,6 +62,7 @@ public Term(String raw, @Nullable Type type) { * * @return */ + @Contract("-> this") public Term negate() { this.negated = true; return this; 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 660abb9f65..5cedc2e476 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 @@ -85,6 +85,7 @@ public static TextCriteria forLanguage(@Nullable String language) { * @param words the words to match. * @return */ + @Contract("_ -> this") public TextCriteria matchingAny(String... words) { for (String word : words) { @@ -99,6 +100,7 @@ public TextCriteria matchingAny(String... words) { * * @param term must not be {@literal null}. */ + @Contract("_ -> this") public TextCriteria matching(Term term) { Assert.notNull(term, "Term to add must not be null"); @@ -111,6 +113,7 @@ public TextCriteria matching(Term term) { * @param term * @return */ + @Contract("_ -> this") public TextCriteria matching(String term) { if (StringUtils.hasText(term)) { @@ -123,6 +126,7 @@ public TextCriteria matching(String term) { * @param term * @return */ + @Contract("_ -> this") public TextCriteria notMatching(String term) { if (StringUtils.hasText(term)) { @@ -135,6 +139,7 @@ public TextCriteria notMatching(String term) { * @param words * @return */ + @Contract("_ -> this") public TextCriteria notMatchingAny(String... words) { for (String word : words) { @@ -149,6 +154,7 @@ public TextCriteria notMatchingAny(String... words) { * @param phrase * @return */ + @Contract("_ -> this") public TextCriteria notMatchingPhrase(String phrase) { if (StringUtils.hasText(phrase)) { @@ -163,6 +169,7 @@ public TextCriteria notMatchingPhrase(String phrase) { * @param phrase * @return */ + @Contract("_ -> this") public TextCriteria matchingPhrase(String phrase) { if (StringUtils.hasText(phrase)) { @@ -178,6 +185,7 @@ public TextCriteria matchingPhrase(String phrase) { * @return never {@literal null}. * @since 1.10 */ + @Contract("_ -> this") public TextCriteria caseSensitive(boolean caseSensitive) { this.caseSensitive = caseSensitive; @@ -191,6 +199,7 @@ public TextCriteria caseSensitive(boolean caseSensitive) { * @return never {@literal null}. * @since 1.10 */ + @Contract("_ -> this") public TextCriteria diacriticSensitive(boolean diacriticSensitive) { this.diacriticSensitive = diacriticSensitive; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextQuery.java index 6d99fbb624..a9f82a857f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextQuery.java @@ -21,6 +21,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.util.BsonUtils; +import org.springframework.lang.Contract; /** * {@link Query} implementation to be used to for performing full text searches. @@ -100,6 +101,7 @@ public static TextQuery queryText(TextCriteria criteria) { * @see TextQuery#includeScore() * @return this. */ + @Contract("-> this") public TextQuery sortByScore() { this.sortByScoreIndex = getSortObject().size(); @@ -113,6 +115,7 @@ public TextQuery sortByScore() { * * @return this. */ + @Contract("-> this") public TextQuery includeScore() { this.includeScore = true; @@ -125,6 +128,7 @@ public TextQuery includeScore() { * @param fieldname must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public TextQuery includeScore(String fieldname) { setScoreFieldName(fieldname); @@ -170,9 +174,8 @@ public Document getSortObject() { int sortByScoreIndex = this.sortByScoreIndex; - return sortByScoreIndex != 0 - ? sortByScoreAtPosition(super.getSortObject(), sortByScoreIndex) - : sortByScoreAtPositionZero(); + return sortByScoreIndex != 0 ? sortByScoreAtPosition(super.getSortObject(), sortByScoreIndex) + : sortByScoreAtPositionZero(); } return super.getSortObject(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java index 83163ddbae..cfb214a5a3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java @@ -32,6 +32,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.domain.Sort.Order; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -114,6 +115,7 @@ public static Update fromDocument(Document object, String... exclude) { * @return this. * @see MongoDB Update operator: $set */ + @Contract("_, _ -> this") public Update set(String key, @Nullable Object value) { addMultiFieldOperation("$set", key, value); return this; @@ -128,6 +130,7 @@ public Update set(String key, @Nullable Object value) { * @see MongoDB Update operator: * $setOnInsert */ + @Contract("_, _ -> this") public Update setOnInsert(String key, @Nullable Object value) { addMultiFieldOperation("$setOnInsert", key, value); return this; @@ -140,6 +143,7 @@ public Update setOnInsert(String key, @Nullable Object value) { * @return this. * @see MongoDB Update operator: $unset */ + @Contract("_ -> this") public Update unset(String key) { addMultiFieldOperation("$unset", key, 1); return this; @@ -153,12 +157,14 @@ public Update unset(String key) { * @return this. * @see MongoDB Update operator: $inc */ + @Contract("_, _ -> this") public Update inc(String key, Number inc) { addMultiFieldOperation("$inc", key, inc); return this; } @Override + @Contract("_ -> this") public void inc(String key) { inc(key, 1L); } @@ -171,6 +177,7 @@ public void inc(String key) { * @return this. * @see MongoDB Update operator: $push */ + @Contract("_, _ -> this") public Update push(String key, @Nullable Object value) { addMultiFieldOperation("$push", key, value); return this; @@ -207,6 +214,7 @@ public PushOperatorBuilder push(String key) { * @return new instance of {@link AddToSetBuilder}. * @since 1.5 */ + @Contract("_ -> new") public AddToSetBuilder addToSet(String key) { return new AddToSetBuilder(key); } @@ -220,6 +228,7 @@ public AddToSetBuilder addToSet(String key) { * @see MongoDB Update operator: * $addToSet */ + @Contract("_, _ -> this") public Update addToSet(String key, @Nullable Object value) { addMultiFieldOperation("$addToSet", key, value); return this; @@ -233,6 +242,7 @@ public Update addToSet(String key, @Nullable Object value) { * @return this. * @see MongoDB Update operator: $pop */ + @Contract("_, _ -> this") public Update pop(String key, Position pos) { addMultiFieldOperation("$pop", key, pos == Position.FIRST ? -1 : 1); return this; @@ -246,6 +256,7 @@ public Update pop(String key, Position pos) { * @return this. * @see MongoDB Update operator: $pull */ + @Contract("_, _ -> this") public Update pull(String key, @Nullable Object value) { addMultiFieldOperation("$pull", key, value); return this; @@ -260,6 +271,7 @@ public Update pull(String key, @Nullable Object value) { * @see MongoDB Update operator: * $pullAll */ + @Contract("_, _ -> this") public Update pullAll(String key, Object[] values) { addMultiFieldOperation("$pullAll", key, Arrays.asList(values)); return this; @@ -274,6 +286,7 @@ public Update pullAll(String key, Object[] values) { * @see MongoDB Update operator: * $rename */ + @Contract("_, _ -> this") public Update rename(String oldName, String newName) { addMultiFieldOperation("$rename", oldName, newName); return this; @@ -288,6 +301,7 @@ public Update rename(String oldName, String newName) { * @see MongoDB Update operator: * $currentDate */ + @Contract("_ -> this") public Update currentDate(String key) { addMultiFieldOperation("$currentDate", key, true); @@ -303,6 +317,7 @@ public Update currentDate(String key) { * @see MongoDB Update operator: * $currentDate */ + @Contract("_ -> this") public Update currentTimestamp(String key) { addMultiFieldOperation("$currentDate", key, new Document("$type", "timestamp")); @@ -318,6 +333,7 @@ public Update currentTimestamp(String key) { * @since 1.7 * @see MongoDB Update operator: $mul */ + @Contract("_, _ -> this") public Update multiply(String key, Number multiplier) { Assert.notNull(multiplier, "Multiplier must not be null"); @@ -335,6 +351,7 @@ public Update multiply(String key, Number multiplier) { * @see Comparison/Sort Order * @see MongoDB Update operator: $max */ + @Contract("_, _ -> this") public Update max(String key, Object value) { Assert.notNull(value, "Value for max operation must not be null"); @@ -352,6 +369,7 @@ public Update max(String key, Object value) { * @see Comparison/Sort Order * @see MongoDB Update operator: $min */ + @Contract("_, _ -> this") public Update min(String key, Object value) { Assert.notNull(value, "Value for min operation must not be null"); @@ -366,6 +384,7 @@ public Update min(String key, Object value) { * @return this. * @since 1.7 */ + @Contract("_ -> new") public BitwiseOperatorBuilder bitwise(String key) { return new BitwiseOperatorBuilder(this, key); } @@ -378,6 +397,7 @@ public BitwiseOperatorBuilder bitwise(String key) { * @return this. * @since 2.0 */ + @Contract("-> this") public Update isolated() { isolated = true; @@ -392,6 +412,7 @@ public Update isolated() { * @return this. * @since 2.2 */ + @Contract("_ -> this") public Update filterArray(CriteriaDefinition criteria) { if (arrayFilters == Collections.EMPTY_LIST) { @@ -411,6 +432,7 @@ public Update filterArray(CriteriaDefinition criteria) { * @return this. * @since 2.2 */ + @Contract("_, _ -> this") public Update filterArray(String identifier, Object expression) { if (arrayFilters == Collections.EMPTY_LIST) { @@ -815,6 +837,7 @@ public Update each(Object... values) { * @return never {@literal null}. * @since 1.10 */ + @Contract("_ -> this") public PushOperatorBuilder slice(int count) { this.modifiers.addModifier(new Slice(count)); @@ -829,6 +852,7 @@ public PushOperatorBuilder slice(int count) { * @return never {@literal null}. * @since 1.10 */ + @Contract("_ -> this") public PushOperatorBuilder sort(Direction direction) { Assert.notNull(direction, "Direction must not be null"); @@ -844,6 +868,7 @@ public PushOperatorBuilder sort(Direction direction) { * @return never {@literal null}. * @since 1.10 */ + @Contract("_ -> this") public PushOperatorBuilder sort(Sort sort) { Assert.notNull(sort, "Sort must not be null"); @@ -859,6 +884,7 @@ public PushOperatorBuilder sort(Sort sort) { * @return never {@literal null}. * @since 1.7 */ + @Contract("_ -> this") public PushOperatorBuilder atPosition(int position) { this.modifiers.addModifier(new PositionModifier(position)); @@ -872,6 +898,7 @@ public PushOperatorBuilder atPosition(int position) { * @return never {@literal null}. * @since 1.7 */ + @Contract("_ -> this") public PushOperatorBuilder atPosition(@Nullable Position position) { if (position == null || Position.LAST.equals(position)) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/IdentifiableJsonSchemaProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/IdentifiableJsonSchemaProperty.java index f008683666..3b7c3255eb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/IdentifiableJsonSchemaProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/IdentifiableJsonSchemaProperty.java @@ -33,6 +33,7 @@ import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ObjectJsonSchemaObject; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.StringJsonSchemaObject; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.TimestampJsonSchemaObject; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -96,6 +97,7 @@ public static class UntypedJsonSchemaProperty extends IdentifiableJsonSchemaProp * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#possibleValues(Collection) */ + @Contract("_ -> new") public UntypedJsonSchemaProperty possibleValues(Object... possibleValues) { return possibleValues(Arrays.asList(possibleValues)); } @@ -105,6 +107,7 @@ public UntypedJsonSchemaProperty possibleValues(Object... possibleValues) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#allOf(Collection) */ + @Contract("_ -> new") public UntypedJsonSchemaProperty allOf(JsonSchemaObject... allOf) { return allOf(new LinkedHashSet<>(Arrays.asList(allOf))); } @@ -114,6 +117,7 @@ public UntypedJsonSchemaProperty allOf(JsonSchemaObject... allOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#anyOf(Collection) */ + @Contract("_ -> new") public UntypedJsonSchemaProperty anyOf(JsonSchemaObject... anyOf) { return anyOf(new LinkedHashSet<>(Arrays.asList(anyOf))); } @@ -123,6 +127,7 @@ public UntypedJsonSchemaProperty anyOf(JsonSchemaObject... anyOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#oneOf(Collection) */ + @Contract("_ -> new") public UntypedJsonSchemaProperty oneOf(JsonSchemaObject... oneOf) { return oneOf(new LinkedHashSet<>(Arrays.asList(oneOf))); } @@ -132,6 +137,7 @@ public UntypedJsonSchemaProperty oneOf(JsonSchemaObject... oneOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#possibleValues(Collection) */ + @Contract("_ -> new") public UntypedJsonSchemaProperty possibleValues(Collection possibleValues) { return new UntypedJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.possibleValues(possibleValues)); } @@ -141,6 +147,7 @@ public UntypedJsonSchemaProperty possibleValues(Collection possibleValue * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#allOf(Collection) */ + @Contract("_ -> new") public UntypedJsonSchemaProperty allOf(Collection allOf) { return new UntypedJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.allOf(allOf)); } @@ -150,6 +157,7 @@ public UntypedJsonSchemaProperty allOf(Collection allOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#anyOf(Collection) */ + @Contract("_ -> new") public UntypedJsonSchemaProperty anyOf(Collection anyOf) { return new UntypedJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.anyOf(anyOf)); } @@ -159,6 +167,7 @@ public UntypedJsonSchemaProperty anyOf(Collection anyOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#oneOf(Collection) */ + @Contract("_ -> new") public UntypedJsonSchemaProperty oneOf(Collection oneOf) { return new UntypedJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.oneOf(oneOf)); } @@ -168,6 +177,7 @@ public UntypedJsonSchemaProperty oneOf(Collection oneOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#notMatch(JsonSchemaObject) */ + @Contract("_ -> new") public UntypedJsonSchemaProperty notMatch(JsonSchemaObject notMatch) { return new UntypedJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.notMatch(notMatch)); } @@ -177,6 +187,7 @@ public UntypedJsonSchemaProperty notMatch(JsonSchemaObject notMatch) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#description(String) */ + @Contract("_ -> new") public UntypedJsonSchemaProperty description(String description) { return new UntypedJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.description(description)); } @@ -185,6 +196,7 @@ public UntypedJsonSchemaProperty description(String description) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#generateDescription() */ + @Contract("_ -> new") public UntypedJsonSchemaProperty generatedDescription() { return new UntypedJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.generatedDescription()); } @@ -212,6 +224,7 @@ public static class StringJsonSchemaProperty extends IdentifiableJsonSchemaPrope * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#minLength(int) */ + @Contract("_ -> new") public StringJsonSchemaProperty minLength(int length) { return new StringJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.minLength(length)); } @@ -221,6 +234,7 @@ public StringJsonSchemaProperty minLength(int length) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#maxLength(int) */ + @Contract("_ -> new") public StringJsonSchemaProperty maxLength(int length) { return new StringJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.maxLength(length)); } @@ -230,6 +244,7 @@ public StringJsonSchemaProperty maxLength(int length) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#matching(String) */ + @Contract("_ -> new") public StringJsonSchemaProperty matching(String pattern) { return new StringJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.matching(pattern)); } @@ -239,6 +254,7 @@ public StringJsonSchemaProperty matching(String pattern) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#possibleValues(Collection) */ + @Contract("_ -> new") public StringJsonSchemaProperty possibleValues(String... possibleValues) { return possibleValues(Arrays.asList(possibleValues)); } @@ -248,6 +264,7 @@ public StringJsonSchemaProperty possibleValues(String... possibleValues) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#allOf(Collection) */ + @Contract("_ -> new") public StringJsonSchemaProperty allOf(JsonSchemaObject... allOf) { return allOf(new LinkedHashSet<>(Arrays.asList(allOf))); } @@ -257,6 +274,7 @@ public StringJsonSchemaProperty allOf(JsonSchemaObject... allOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#anyOf(Collection) */ + @Contract("_ -> new") public StringJsonSchemaProperty anyOf(JsonSchemaObject... anyOf) { return anyOf(new LinkedHashSet<>(Arrays.asList(anyOf))); } @@ -266,6 +284,7 @@ public StringJsonSchemaProperty anyOf(JsonSchemaObject... anyOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#oneOf(Collection) */ + @Contract("_ -> new") public StringJsonSchemaProperty oneOf(JsonSchemaObject... oneOf) { return oneOf(new LinkedHashSet<>(Arrays.asList(oneOf))); } @@ -275,6 +294,7 @@ public StringJsonSchemaProperty oneOf(JsonSchemaObject... oneOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#possibleValues(Collection) */ + @Contract("_ -> new") public StringJsonSchemaProperty possibleValues(Collection possibleValues) { return new StringJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.possibleValues(possibleValues)); } @@ -284,6 +304,7 @@ public StringJsonSchemaProperty possibleValues(Collection possibleValues * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#allOf(Collection) */ + @Contract("_ -> new") public StringJsonSchemaProperty allOf(Collection allOf) { return new StringJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.allOf(allOf)); } @@ -293,6 +314,7 @@ public StringJsonSchemaProperty allOf(Collection allOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#anyOf(Collection) */ + @Contract("_ -> new") public StringJsonSchemaProperty anyOf(Collection anyOf) { return new StringJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.anyOf(anyOf)); } @@ -302,6 +324,7 @@ public StringJsonSchemaProperty anyOf(Collection anyOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#oneOf(Collection) */ + @Contract("_ -> new") public StringJsonSchemaProperty oneOf(Collection oneOf) { return new StringJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.oneOf(oneOf)); } @@ -311,6 +334,7 @@ public StringJsonSchemaProperty oneOf(Collection oneOf) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#notMatch(JsonSchemaObject) */ + @Contract("_ -> new") public StringJsonSchemaProperty notMatch(JsonSchemaObject notMatch) { return new StringJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.notMatch(notMatch)); } @@ -320,6 +344,7 @@ public StringJsonSchemaProperty notMatch(JsonSchemaObject notMatch) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#description(String) */ + @Contract("_ -> new") public StringJsonSchemaProperty description(String description) { return new StringJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.description(description)); } @@ -328,6 +353,7 @@ public StringJsonSchemaProperty description(String description) { * @return new instance of {@link StringJsonSchemaProperty}. * @see StringJsonSchemaObject#generateDescription() */ + @Contract("_ -> new") public StringJsonSchemaProperty generatedDescription() { return new StringJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.generatedDescription()); } @@ -354,6 +380,7 @@ public static class ObjectJsonSchemaProperty extends IdentifiableJsonSchemaPrope * @param range must not be {@literal null}. * @return new instance of {@link ObjectJsonSchemaProperty}. */ + @Contract("_ -> new") public ObjectJsonSchemaProperty propertiesCount(Range range) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.propertiesCount(range)); } @@ -363,6 +390,7 @@ public ObjectJsonSchemaProperty propertiesCount(Range range) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#minProperties(int) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty minProperties(int count) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.minProperties(count)); } @@ -372,6 +400,7 @@ public ObjectJsonSchemaProperty minProperties(int count) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#maxProperties(int) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty maxProperties(int count) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.maxProperties(count)); } @@ -381,6 +410,7 @@ public ObjectJsonSchemaProperty maxProperties(int count) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#required(String...) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty required(String... properties) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.required(properties)); } @@ -390,6 +420,7 @@ public ObjectJsonSchemaProperty required(String... properties) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#additionalProperties(boolean) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty additionalProperties(boolean additionalPropertiesAllowed) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.additionalProperties(additionalPropertiesAllowed)); @@ -400,6 +431,7 @@ public ObjectJsonSchemaProperty additionalProperties(boolean additionalPropertie * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#additionalProperties(ObjectJsonSchemaObject) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty additionalProperties(ObjectJsonSchemaObject additionalProperties) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.additionalProperties(additionalProperties)); @@ -410,6 +442,7 @@ public ObjectJsonSchemaProperty additionalProperties(ObjectJsonSchemaObject addi * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#properties(JsonSchemaProperty...) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty properties(JsonSchemaProperty... properties) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.properties(properties)); } @@ -419,6 +452,7 @@ public ObjectJsonSchemaProperty properties(JsonSchemaProperty... properties) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#possibleValues(Collection) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty possibleValues(Object... possibleValues) { return possibleValues(Arrays.asList(possibleValues)); } @@ -428,6 +462,7 @@ public ObjectJsonSchemaProperty possibleValues(Object... possibleValues) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#allOf(Collection) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty allOf(JsonSchemaObject... allOf) { return allOf(new LinkedHashSet<>(Arrays.asList(allOf))); } @@ -437,6 +472,7 @@ public ObjectJsonSchemaProperty allOf(JsonSchemaObject... allOf) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#anyOf(Collection) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty anyOf(JsonSchemaObject... anyOf) { return anyOf(new LinkedHashSet<>(Arrays.asList(anyOf))); } @@ -446,6 +482,7 @@ public ObjectJsonSchemaProperty anyOf(JsonSchemaObject... anyOf) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#oneOf(Collection) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty oneOf(JsonSchemaObject... oneOf) { return oneOf(new LinkedHashSet<>(Arrays.asList(oneOf))); } @@ -455,6 +492,7 @@ public ObjectJsonSchemaProperty oneOf(JsonSchemaObject... oneOf) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#possibleValues(Collection) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty possibleValues(Collection possibleValues) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.possibleValues(possibleValues)); } @@ -464,6 +502,7 @@ public ObjectJsonSchemaProperty possibleValues(Collection possibleValues * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#allOf(Collection) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty allOf(Collection allOf) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.allOf(allOf)); } @@ -473,6 +512,7 @@ public ObjectJsonSchemaProperty allOf(Collection allOf) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#anyOf(Collection) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty anyOf(Collection anyOf) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.anyOf(anyOf)); } @@ -482,6 +522,7 @@ public ObjectJsonSchemaProperty anyOf(Collection anyOf) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#oneOf(Collection) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty oneOf(Collection oneOf) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.oneOf(oneOf)); } @@ -491,6 +532,7 @@ public ObjectJsonSchemaProperty oneOf(Collection oneOf) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#notMatch(JsonSchemaObject) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty notMatch(JsonSchemaObject notMatch) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.notMatch(notMatch)); } @@ -500,6 +542,7 @@ public ObjectJsonSchemaProperty notMatch(JsonSchemaObject notMatch) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#description(String) */ + @Contract("_ -> new") public ObjectJsonSchemaProperty description(String description) { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.description(description)); } @@ -508,6 +551,7 @@ public ObjectJsonSchemaProperty description(String description) { * @return new instance of {@link ObjectJsonSchemaProperty}. * @see ObjectJsonSchemaObject#generateDescription() */ + @Contract("_ -> new") public ObjectJsonSchemaProperty generatedDescription() { return new ObjectJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.generatedDescription()); } @@ -539,6 +583,7 @@ public NumericJsonSchemaProperty(String identifier, NumericJsonSchemaObject sche * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#multipleOf */ + @Contract("_ -> new") public NumericJsonSchemaProperty multipleOf(Number value) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.multipleOf(value)); } @@ -548,6 +593,7 @@ public NumericJsonSchemaProperty multipleOf(Number value) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#within(Range) */ + @Contract("_ -> new") public NumericJsonSchemaProperty within(Range range) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.within(range)); } @@ -557,6 +603,7 @@ public NumericJsonSchemaProperty within(Range range) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#gt(Number) */ + @Contract("_ -> new") public NumericJsonSchemaProperty gt(Number min) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.gt(min)); } @@ -566,6 +613,7 @@ public NumericJsonSchemaProperty gt(Number min) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#gte(Number) */ + @Contract("_ -> new") public NumericJsonSchemaProperty gte(Number min) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.gte(min)); } @@ -575,6 +623,7 @@ public NumericJsonSchemaProperty gte(Number min) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#lt(Number) */ + @Contract("_ -> new") public NumericJsonSchemaProperty lt(Number max) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.lt(max)); } @@ -584,6 +633,7 @@ public NumericJsonSchemaProperty lt(Number max) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#lte(Number) */ + @Contract("_ -> new") public NumericJsonSchemaProperty lte(Number max) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.lte(max)); } @@ -593,6 +643,7 @@ public NumericJsonSchemaProperty lte(Number max) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#possibleValues(Collection) */ + @Contract("_ -> new") public NumericJsonSchemaProperty possibleValues(Number... possibleValues) { return possibleValues(new LinkedHashSet<>(Arrays.asList(possibleValues))); } @@ -602,6 +653,7 @@ public NumericJsonSchemaProperty possibleValues(Number... possibleValues) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#allOf(Collection) */ + @Contract("_ -> new") public NumericJsonSchemaProperty allOf(JsonSchemaObject... allOf) { return allOf(Arrays.asList(allOf)); } @@ -611,6 +663,7 @@ public NumericJsonSchemaProperty allOf(JsonSchemaObject... allOf) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#anyOf(Collection) */ + @Contract("_ -> new") public NumericJsonSchemaProperty anyOf(JsonSchemaObject... anyOf) { return anyOf(new LinkedHashSet<>(Arrays.asList(anyOf))); } @@ -620,6 +673,7 @@ public NumericJsonSchemaProperty anyOf(JsonSchemaObject... anyOf) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#oneOf(Collection) */ + @Contract("_ -> new") public NumericJsonSchemaProperty oneOf(JsonSchemaObject... oneOf) { return oneOf(new LinkedHashSet<>(Arrays.asList(oneOf))); } @@ -629,6 +683,7 @@ public NumericJsonSchemaProperty oneOf(JsonSchemaObject... oneOf) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#possibleValues(Collection) */ + @Contract("_ -> new") public NumericJsonSchemaProperty possibleValues(Collection possibleValues) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.possibleValues(possibleValues)); } @@ -638,6 +693,7 @@ public NumericJsonSchemaProperty possibleValues(Collection possibleValue * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#allOf(Collection) */ + @Contract("_ -> new") public NumericJsonSchemaProperty allOf(Collection allOf) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.allOf(allOf)); } @@ -647,6 +703,7 @@ public NumericJsonSchemaProperty allOf(Collection allOf) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#anyOf(Collection) */ + @Contract("_ -> new") public NumericJsonSchemaProperty anyOf(Collection anyOf) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.anyOf(anyOf)); } @@ -656,6 +713,7 @@ public NumericJsonSchemaProperty anyOf(Collection anyOf) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#oneOf(Collection) */ + @Contract("_ -> new") public NumericJsonSchemaProperty oneOf(Collection oneOf) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.oneOf(oneOf)); } @@ -665,6 +723,7 @@ public NumericJsonSchemaProperty oneOf(Collection oneOf) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#notMatch(JsonSchemaObject) */ + @Contract("_ -> new") public NumericJsonSchemaProperty notMatch(JsonSchemaObject notMatch) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.notMatch(notMatch)); } @@ -674,6 +733,7 @@ public NumericJsonSchemaProperty notMatch(JsonSchemaObject notMatch) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see NumericJsonSchemaObject#description(String) */ + @Contract("_ -> new") public NumericJsonSchemaProperty description(String description) { return new NumericJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.description(description)); } @@ -709,6 +769,7 @@ public ArrayJsonSchemaProperty(String identifier, ArrayJsonSchemaObject schemaOb * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#uniqueItems(boolean) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty uniqueItems(boolean uniqueItems) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.uniqueItems(uniqueItems)); } @@ -718,6 +779,7 @@ public ArrayJsonSchemaProperty uniqueItems(boolean uniqueItems) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#range(Range) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty range(Range range) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.range(range)); } @@ -727,6 +789,7 @@ public ArrayJsonSchemaProperty range(Range range) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#minItems(int) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty minItems(int count) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.minItems(count)); } @@ -736,6 +799,7 @@ public ArrayJsonSchemaProperty minItems(int count) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#maxItems(int) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty maxItems(int count) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.maxItems(count)); } @@ -745,6 +809,7 @@ public ArrayJsonSchemaProperty maxItems(int count) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#items(Collection) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty items(JsonSchemaObject... items) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.items(Arrays.asList(items))); } @@ -754,6 +819,7 @@ public ArrayJsonSchemaProperty items(JsonSchemaObject... items) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#items(Collection) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty items(Collection items) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.items(items)); } @@ -763,6 +829,7 @@ public ArrayJsonSchemaProperty items(Collection items) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#additionalItems(boolean) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty additionalItems(boolean additionalItemsAllowed) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.additionalItems(additionalItemsAllowed)); } @@ -772,6 +839,7 @@ public ArrayJsonSchemaProperty additionalItems(boolean additionalItemsAllowed) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#possibleValues(Collection) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty possibleValues(Object... possibleValues) { return possibleValues(new LinkedHashSet<>(Arrays.asList(possibleValues))); } @@ -781,6 +849,7 @@ public ArrayJsonSchemaProperty possibleValues(Object... possibleValues) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#allOf(Collection) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty allOf(JsonSchemaObject... allOf) { return allOf(new LinkedHashSet<>(Arrays.asList(allOf))); } @@ -790,6 +859,7 @@ public ArrayJsonSchemaProperty allOf(JsonSchemaObject... allOf) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#anyOf(Collection) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty anyOf(JsonSchemaObject... anyOf) { return anyOf(new LinkedHashSet<>(Arrays.asList(anyOf))); } @@ -799,6 +869,7 @@ public ArrayJsonSchemaProperty anyOf(JsonSchemaObject... anyOf) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#oneOf(Collection) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty oneOf(JsonSchemaObject... oneOf) { return oneOf(new LinkedHashSet<>(Arrays.asList(oneOf))); } @@ -808,6 +879,7 @@ public ArrayJsonSchemaProperty oneOf(JsonSchemaObject... oneOf) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#possibleValues(Collection) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty possibleValues(Collection possibleValues) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.possibleValues(possibleValues)); } @@ -817,6 +889,7 @@ public ArrayJsonSchemaProperty possibleValues(Collection possibleValues) * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#allOf(Collection) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty allOf(Collection allOf) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.allOf(allOf)); } @@ -826,6 +899,7 @@ public ArrayJsonSchemaProperty allOf(Collection allOf) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#anyOf(Collection) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty anyOf(Collection anyOf) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.anyOf(anyOf)); } @@ -835,6 +909,7 @@ public ArrayJsonSchemaProperty anyOf(Collection anyOf) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#oneOf(Collection) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty oneOf(Collection oneOf) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.oneOf(oneOf)); } @@ -844,6 +919,7 @@ public ArrayJsonSchemaProperty oneOf(Collection oneOf) { * @return new instance of {@link ArrayJsonSchemaProperty}. * @see ArrayJsonSchemaObject#notMatch(JsonSchemaObject) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty notMatch(JsonSchemaObject notMatch) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.notMatch(notMatch)); } @@ -853,6 +929,7 @@ public ArrayJsonSchemaProperty notMatch(JsonSchemaObject notMatch) { * @return new instance of {@link NumericJsonSchemaProperty}. * @see ArrayJsonSchemaObject#description(String) */ + @Contract("_ -> new") public ArrayJsonSchemaProperty description(String description) { return new ArrayJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.description(description)); } @@ -883,6 +960,7 @@ public static class BooleanJsonSchemaProperty extends IdentifiableJsonSchemaProp * @return new instance of {@link NumericJsonSchemaProperty}. * @see BooleanJsonSchemaObject#description(String) */ + @Contract("_ -> new") public BooleanJsonSchemaProperty description(String description) { return new BooleanJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.description(description)); } @@ -913,6 +991,7 @@ public static class NullJsonSchemaProperty extends IdentifiableJsonSchemaPropert * @return new instance of {@link NullJsonSchemaProperty}. * @see NullJsonSchemaObject#description(String) */ + @Contract("_ -> new") public NullJsonSchemaProperty description(String description) { return new NullJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.description(description)); } @@ -943,6 +1022,7 @@ public static class DateJsonSchemaProperty extends IdentifiableJsonSchemaPropert * @return new instance of {@link DateJsonSchemaProperty}. * @see DateJsonSchemaProperty#description(String) */ + @Contract("_ -> new") public DateJsonSchemaProperty description(String description) { return new DateJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.description(description)); } @@ -973,6 +1053,7 @@ public static class TimestampJsonSchemaProperty extends IdentifiableJsonSchemaPr * @return new instance of {@link TimestampJsonSchemaProperty}. * @see TimestampJsonSchemaProperty#description(String) */ + @Contract("_ -> new") public TimestampJsonSchemaProperty description(String description) { return new TimestampJsonSchemaProperty(identifier, jsonSchemaObjectDelegate.description(description)); } @@ -1072,6 +1153,7 @@ public static EncryptedJsonSchemaProperty encrypted(JsonSchemaProperty target) { * * @return new instance of {@link EncryptedJsonSchemaProperty}. */ + @Contract("-> new") public EncryptedJsonSchemaProperty aead_aes_256_cbc_hmac_sha_512_random() { return algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Random"); } @@ -1081,6 +1163,7 @@ public EncryptedJsonSchemaProperty aead_aes_256_cbc_hmac_sha_512_random() { * * @return new instance of {@link EncryptedJsonSchemaProperty}. */ + @Contract("-> new") public EncryptedJsonSchemaProperty aead_aes_256_cbc_hmac_sha_512_deterministic() { return algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"); } @@ -1090,6 +1173,7 @@ public EncryptedJsonSchemaProperty aead_aes_256_cbc_hmac_sha_512_deterministic() * * @return new instance of {@link EncryptedJsonSchemaProperty}. */ + @Contract("_ -> new") public EncryptedJsonSchemaProperty algorithm(String algorithm) { return new EncryptedJsonSchemaProperty(targetProperty, algorithm, keyId, keyIds); } @@ -1098,6 +1182,7 @@ public EncryptedJsonSchemaProperty algorithm(String algorithm) { * @param keyId must not be {@literal null}. * @return new instance of {@link EncryptedJsonSchemaProperty}. */ + @Contract("_ -> new") public EncryptedJsonSchemaProperty keyId(String keyId) { return new EncryptedJsonSchemaProperty(targetProperty, algorithm, keyId, null); } @@ -1106,6 +1191,7 @@ public EncryptedJsonSchemaProperty keyId(String keyId) { * @param keyId must not be {@literal null}. * @return new instance of {@link EncryptedJsonSchemaProperty}. */ + @Contract("_ -> new") public EncryptedJsonSchemaProperty keys(UUID... keyId) { return new EncryptedJsonSchemaProperty(targetProperty, algorithm, null, Arrays.asList(keyId)); } @@ -1114,6 +1200,7 @@ public EncryptedJsonSchemaProperty keys(UUID... keyId) { * @param keyId must not be {@literal null}. * @return new instance of {@link EncryptedJsonSchemaProperty}. */ + @Contract("_ -> new") public EncryptedJsonSchemaProperty keys(Object... keyId) { return new EncryptedJsonSchemaProperty(targetProperty, algorithm, null, Arrays.asList(keyId)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java index 7931485cbb..87c46d63dc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/MongoJsonSchema.java @@ -25,6 +25,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ObjectJsonSchemaObject; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -322,6 +323,7 @@ class MongoJsonSchemaBuilder { * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see ObjectJsonSchemaObject#minProperties(int) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder minProperties(int count) { root = root.minProperties(count); @@ -333,6 +335,7 @@ public MongoJsonSchemaBuilder minProperties(int count) { * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see ObjectJsonSchemaObject#maxProperties(int) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder maxProperties(int count) { root = root.maxProperties(count); @@ -344,6 +347,7 @@ public MongoJsonSchemaBuilder maxProperties(int count) { * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see ObjectJsonSchemaObject#required(String...) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder required(String... properties) { root = root.required(properties); @@ -355,6 +359,7 @@ public MongoJsonSchemaBuilder required(String... properties) { * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see ObjectJsonSchemaObject#additionalProperties(boolean) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder additionalProperties(boolean additionalPropertiesAllowed) { root = root.additionalProperties(additionalPropertiesAllowed); @@ -366,6 +371,7 @@ public MongoJsonSchemaBuilder additionalProperties(boolean additionalPropertiesA * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see ObjectJsonSchemaObject#additionalProperties(ObjectJsonSchemaObject) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder additionalProperties(ObjectJsonSchemaObject schema) { root = root.additionalProperties(schema); @@ -377,6 +383,7 @@ public MongoJsonSchemaBuilder additionalProperties(ObjectJsonSchemaObject schema * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see ObjectJsonSchemaObject#properties(JsonSchemaProperty...) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder properties(JsonSchemaProperty... properties) { root = root.properties(properties); @@ -388,6 +395,7 @@ public MongoJsonSchemaBuilder properties(JsonSchemaProperty... properties) { * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see ObjectJsonSchemaObject#patternProperties(JsonSchemaProperty...) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder patternProperties(JsonSchemaProperty... properties) { root = root.patternProperties(properties); @@ -399,6 +407,7 @@ public MongoJsonSchemaBuilder patternProperties(JsonSchemaProperty... properties * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see ObjectJsonSchemaObject#property(JsonSchemaProperty) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder property(JsonSchemaProperty property) { root = root.property(property); @@ -410,6 +419,7 @@ public MongoJsonSchemaBuilder property(JsonSchemaProperty property) { * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see ObjectJsonSchemaObject#possibleValues(Collection) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder possibleValues(Set possibleValues) { root = root.possibleValues(possibleValues); @@ -421,6 +431,7 @@ public MongoJsonSchemaBuilder possibleValues(Set possibleValues) { * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see UntypedJsonSchemaObject#allOf(Collection) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder allOf(Set allOf) { root = root.allOf(allOf); @@ -432,6 +443,7 @@ public MongoJsonSchemaBuilder allOf(Set allOf) { * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see UntypedJsonSchemaObject#anyOf(Collection) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder anyOf(Set anyOf) { root = root.anyOf(anyOf); @@ -443,6 +455,7 @@ public MongoJsonSchemaBuilder anyOf(Set anyOf) { * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see UntypedJsonSchemaObject#oneOf(Collection) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder oneOf(Set oneOf) { root = root.oneOf(oneOf); @@ -454,6 +467,7 @@ public MongoJsonSchemaBuilder oneOf(Set oneOf) { * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see UntypedJsonSchemaObject#notMatch(JsonSchemaObject) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder notMatch(JsonSchemaObject notMatch) { root = root.notMatch(notMatch); @@ -465,6 +479,7 @@ public MongoJsonSchemaBuilder notMatch(JsonSchemaObject notMatch) { * @return {@code this} {@link MongoJsonSchemaBuilder}. * @see UntypedJsonSchemaObject#description(String) */ + @Contract("_ -> this") public MongoJsonSchemaBuilder description(String description) { root = root.description(description); @@ -486,6 +501,7 @@ public void encryptionMetadata(@Nullable Document encryptionMetadata) { * * @return new instance of {@link MongoJsonSchema}. */ + @Contract("-> new") public MongoJsonSchema build() { return new DefaultMongoJsonSchema(root, encryptionMetadata); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypedJsonSchemaObject.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypedJsonSchemaObject.java index 1394a28e24..7b299fd4d2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypedJsonSchemaObject.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/TypedJsonSchemaObject.java @@ -30,6 +30,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.domain.Range.Bound; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -100,6 +101,7 @@ public Set getTypes() { * @return new instance of {@link TypedJsonSchemaObject}. */ @Override + @Contract("_ -> new") public TypedJsonSchemaObject description(String description) { return new TypedJsonSchemaObject(types, description, generateDescription, restrictions); } @@ -110,6 +112,7 @@ public TypedJsonSchemaObject description(String description) { * @return new instance of {@link TypedJsonSchemaObject}. */ @Override + @Contract("-> new") public TypedJsonSchemaObject generatedDescription() { return new TypedJsonSchemaObject(types, description, true, restrictions); } @@ -121,6 +124,7 @@ public TypedJsonSchemaObject generatedDescription() { * @return new instance of {@link TypedJsonSchemaObject}. */ @Override + @Contract("_ -> new") public TypedJsonSchemaObject possibleValues(Collection possibleValues) { return new TypedJsonSchemaObject(types, description, generateDescription, restrictions.possibleValues(possibleValues)); @@ -133,6 +137,7 @@ public TypedJsonSchemaObject possibleValues(Collection possibl * @return new instance of {@link TypedJsonSchemaObject}. */ @Override + @Contract("_ -> new") public TypedJsonSchemaObject allOf(Collection allOf) { return new TypedJsonSchemaObject(types, description, generateDescription, restrictions.allOf(allOf)); } @@ -144,6 +149,7 @@ public TypedJsonSchemaObject allOf(Collection allOf) { * @return new instance of {@link TypedJsonSchemaObject}. */ @Override + @Contract("_ -> new") public TypedJsonSchemaObject anyOf(Collection anyOf) { return new TypedJsonSchemaObject(types, description, generateDescription, restrictions.anyOf(anyOf)); } @@ -155,6 +161,7 @@ public TypedJsonSchemaObject anyOf(Collection anyOf) { * @return new instance of {@link TypedJsonSchemaObject}. */ @Override + @Contract("_ -> new") public TypedJsonSchemaObject oneOf(Collection oneOf) { return new TypedJsonSchemaObject(types, description, generateDescription, restrictions.oneOf(oneOf)); } @@ -166,6 +173,7 @@ public TypedJsonSchemaObject oneOf(Collection oneOf) { * @return new instance of {@link TypedJsonSchemaObject}. */ @Override + @Contract("_ -> new") public TypedJsonSchemaObject notMatch(JsonSchemaObject notMatch) { return new TypedJsonSchemaObject(types, description, generateDescription, restrictions.notMatch(notMatch)); } @@ -263,6 +271,7 @@ public ObjectJsonSchemaObject propertiesCount(Range range) { * @param count the allowed minimal number of properties. * @return new instance of {@link ObjectJsonSchemaObject}. */ + @Contract("_ -> new") public ObjectJsonSchemaObject minProperties(int count) { Bound upper = this.propertiesCount != null ? this.propertiesCount.getUpperBound() : Bound.unbounded(); @@ -275,6 +284,7 @@ public ObjectJsonSchemaObject minProperties(int count) { * @param count the allowed maximum number of properties. * @return new instance of {@link ObjectJsonSchemaObject}. */ + @Contract("_ -> new") public ObjectJsonSchemaObject maxProperties(int count) { Bound lower = this.propertiesCount != null ? this.propertiesCount.getLowerBound() : Bound.unbounded(); @@ -287,6 +297,7 @@ public ObjectJsonSchemaObject maxProperties(int count) { * @param properties the names of required properties. * @return new instance of {@link ObjectJsonSchemaObject}. */ + @Contract("_ -> new") public ObjectJsonSchemaObject required(String... properties) { ObjectJsonSchemaObject newInstance = newInstance(description, generateDescription, restrictions); @@ -304,6 +315,7 @@ public ObjectJsonSchemaObject required(String... properties) { * @param additionalPropertiesAllowed * @return new instance of {@link ObjectJsonSchemaObject}. */ + @Contract("_ -> new") public ObjectJsonSchemaObject additionalProperties(boolean additionalPropertiesAllowed) { ObjectJsonSchemaObject newInstance = newInstance(description, generateDescription, restrictions); @@ -318,6 +330,7 @@ public ObjectJsonSchemaObject additionalProperties(boolean additionalPropertiesA * @param schema must not be {@literal null}. * @return new instance of {@link ObjectJsonSchemaObject}. */ + @Contract("_ -> new") public ObjectJsonSchemaObject additionalProperties(ObjectJsonSchemaObject schema) { ObjectJsonSchemaObject newInstance = newInstance(description, generateDescription, restrictions); @@ -331,6 +344,7 @@ public ObjectJsonSchemaObject additionalProperties(ObjectJsonSchemaObject schema * @param properties must not be {@literal null}. * @return new instance of {@link ObjectJsonSchemaObject}. */ + @Contract("_ -> new") public ObjectJsonSchemaObject properties(JsonSchemaProperty... properties) { ObjectJsonSchemaObject newInstance = newInstance(description, generateDescription, restrictions); @@ -348,6 +362,7 @@ public ObjectJsonSchemaObject properties(JsonSchemaProperty... properties) { * @param regularExpressions must not be {@literal null}. * @return new instance of {@link ObjectJsonSchemaObject}. */ + @Contract("_ -> new") public ObjectJsonSchemaObject patternProperties(JsonSchemaProperty... regularExpressions) { ObjectJsonSchemaObject newInstance = newInstance(description, generateDescription, restrictions); @@ -364,41 +379,49 @@ public ObjectJsonSchemaObject patternProperties(JsonSchemaProperty... regularExp * @param property must not be {@literal null}. * @return new instance of {@link ObjectJsonSchemaObject}. */ + @Contract("_ -> new") public ObjectJsonSchemaObject property(JsonSchemaProperty property) { return properties(property); } @Override + @Contract("_ -> new") public ObjectJsonSchemaObject possibleValues(Collection possibleValues) { return newInstance(description, generateDescription, restrictions.possibleValues(possibleValues)); } @Override + @Contract("_ -> new") public ObjectJsonSchemaObject allOf(Collection allOf) { return newInstance(description, generateDescription, restrictions.allOf(allOf)); } @Override + @Contract("_ -> new") public ObjectJsonSchemaObject anyOf(Collection anyOf) { return newInstance(description, generateDescription, restrictions.anyOf(anyOf)); } @Override + @Contract("_ -> new") public ObjectJsonSchemaObject oneOf(Collection oneOf) { return newInstance(description, generateDescription, restrictions.oneOf(oneOf)); } @Override + @Contract("_ -> new") public ObjectJsonSchemaObject notMatch(JsonSchemaObject notMatch) { return newInstance(description, generateDescription, restrictions.notMatch(notMatch)); } @Override + @Contract("_ -> new") public ObjectJsonSchemaObject description(String description) { return newInstance(description, generateDescription, restrictions); } @Override + @Contract("_ -> new") public ObjectJsonSchemaObject generatedDescription() { return newInstance(description, true, restrictions); } @@ -544,6 +567,7 @@ private NumericJsonSchemaObject(Set types, @Nullable String description, b * @param value must not be {@literal null}. * @return must not be {@literal null}. */ + @Contract("_ -> new") public NumericJsonSchemaObject multipleOf(Number value) { Assert.notNull(value, "Value must not be null"); @@ -560,6 +584,7 @@ public NumericJsonSchemaObject multipleOf(Number value) { * @param range must not be {@literal null}. * @return new instance of {@link NumericJsonSchemaObject}. */ + @Contract("_ -> new") public NumericJsonSchemaObject within(Range range) { Assert.notNull(range, "Range must not be null"); @@ -577,6 +602,7 @@ public NumericJsonSchemaObject within(Range range) { * @return new instance of {@link NumericJsonSchemaObject}. */ @SuppressWarnings("unchecked") + @Contract("_ -> new") public NumericJsonSchemaObject gt(Number min) { Assert.notNull(min, "Min must not be null"); @@ -592,6 +618,7 @@ public NumericJsonSchemaObject gt(Number min) { * @return new instance of {@link NumericJsonSchemaObject}. */ @SuppressWarnings("unchecked") + @Contract("_ -> new") public NumericJsonSchemaObject gte(Number min) { Assert.notNull(min, "Min must not be null"); @@ -607,6 +634,7 @@ public NumericJsonSchemaObject gte(Number min) { * @return new instance of {@link NumericJsonSchemaObject}. */ @SuppressWarnings("unchecked") + @Contract("_ -> new") public NumericJsonSchemaObject lt(Number max) { Assert.notNull(max, "Max must not be null"); @@ -622,6 +650,7 @@ public NumericJsonSchemaObject lt(Number max) { * @return new instance of {@link NumericJsonSchemaObject}. */ @SuppressWarnings("unchecked") + @Contract("_ -> new") public NumericJsonSchemaObject lte(Number max) { Assert.notNull(max, "Max must not be null"); @@ -631,36 +660,43 @@ public NumericJsonSchemaObject lte(Number max) { } @Override + @Contract("_ -> new") public NumericJsonSchemaObject possibleValues(Collection possibleValues) { return newInstance(description, generateDescription, restrictions.possibleValues(possibleValues)); } @Override + @Contract("_ -> new") public NumericJsonSchemaObject allOf(Collection allOf) { return newInstance(description, generateDescription, restrictions.allOf(allOf)); } @Override + @Contract("_ -> new") public NumericJsonSchemaObject anyOf(Collection anyOf) { return newInstance(description, generateDescription, restrictions.anyOf(anyOf)); } @Override + @Contract("_ -> new") public NumericJsonSchemaObject oneOf(Collection oneOf) { return newInstance(description, generateDescription, restrictions.oneOf(oneOf)); } @Override + @Contract("_ -> new") public NumericJsonSchemaObject notMatch(JsonSchemaObject notMatch) { return newInstance(description, generateDescription, restrictions.notMatch(notMatch)); } @Override + @Contract("_ -> new") public NumericJsonSchemaObject description(String description) { return newInstance(description, generateDescription, restrictions); } @Override + @Contract("_ -> new") public NumericJsonSchemaObject generatedDescription() { return newInstance(description, true, restrictions); } @@ -784,6 +820,7 @@ private StringJsonSchemaObject(@Nullable String description, boolean generateDes * @param range must not be {@literal null}. * @return new instance of {@link StringJsonSchemaObject}. */ + @Contract("_ -> new") public StringJsonSchemaObject length(Range range) { Assert.notNull(range, "Range must not be null"); @@ -800,6 +837,7 @@ public StringJsonSchemaObject length(Range range) { * @param length * @return new instance of {@link StringJsonSchemaObject}. */ + @Contract("_ -> new") public StringJsonSchemaObject minLength(int length) { Bound upper = this.length != null ? this.length.getUpperBound() : Bound.unbounded(); @@ -812,6 +850,7 @@ public StringJsonSchemaObject minLength(int length) { * @param length * @return new instance of {@link StringJsonSchemaObject}. */ + @Contract("_ -> new") public StringJsonSchemaObject maxLength(int length) { Bound lower = this.length != null ? this.length.getLowerBound() : Bound.unbounded(); @@ -824,6 +863,7 @@ public StringJsonSchemaObject maxLength(int length) { * @param pattern must not be {@literal null}. * @return new instance of {@link StringJsonSchemaObject}. */ + @Contract("_ -> new") public StringJsonSchemaObject matching(String pattern) { Assert.notNull(pattern, "Pattern must not be null"); @@ -835,36 +875,43 @@ public StringJsonSchemaObject matching(String pattern) { } @Override + @Contract("_ -> new") public StringJsonSchemaObject possibleValues(Collection possibleValues) { return newInstance(description, generateDescription, restrictions.possibleValues(possibleValues)); } @Override + @Contract("_ -> new") public StringJsonSchemaObject allOf(Collection allOf) { return newInstance(description, generateDescription, restrictions.allOf(allOf)); } @Override + @Contract("_ -> new") public StringJsonSchemaObject anyOf(Collection anyOf) { return newInstance(description, generateDescription, restrictions.anyOf(anyOf)); } @Override + @Contract("_ -> new") public StringJsonSchemaObject oneOf(Collection oneOf) { return newInstance(description, generateDescription, restrictions.oneOf(oneOf)); } @Override + @Contract("_ -> new") public StringJsonSchemaObject notMatch(JsonSchemaObject notMatch) { return newInstance(description, generateDescription, restrictions.notMatch(notMatch)); } @Override + @Contract("_ -> new") public StringJsonSchemaObject description(String description) { return newInstance(description, generateDescription, restrictions); } @Override + @Contract("-> new") public StringJsonSchemaObject generatedDescription() { return newInstance(description, true, restrictions); } @@ -945,6 +992,7 @@ private ArrayJsonSchemaObject(@Nullable String description, boolean generateDesc * @param uniqueItems * @return new instance of {@link ArrayJsonSchemaObject}. */ + @Contract("_ -> new") public ArrayJsonSchemaObject uniqueItems(boolean uniqueItems) { ArrayJsonSchemaObject newInstance = newInstance(description, generateDescription, restrictions); @@ -960,6 +1008,7 @@ public ArrayJsonSchemaObject uniqueItems(boolean uniqueItems) { * @param range must not be {@literal null}. Consider {@link Range#unbounded()} instead. * @return new instance of {@link ArrayJsonSchemaObject}. */ + @Contract("_ -> new") public ArrayJsonSchemaObject range(Range range) { ArrayJsonSchemaObject newInstance = newInstance(description, generateDescription, restrictions); @@ -974,6 +1023,7 @@ public ArrayJsonSchemaObject range(Range range) { * @param count the allowed minimal number of array items. * @return new instance of {@link ArrayJsonSchemaObject}. */ + @Contract("_ -> new") public ArrayJsonSchemaObject minItems(int count) { Bound upper = this.range != null ? this.range.getUpperBound() : Bound.unbounded(); @@ -986,6 +1036,7 @@ public ArrayJsonSchemaObject minItems(int count) { * @param count the allowed maximal number of array items. * @return new instance of {@link ArrayJsonSchemaObject}. */ + @Contract("_ -> new") public ArrayJsonSchemaObject maxItems(int count) { Bound lower = this.range != null ? this.range.getLowerBound() : Bound.unbounded(); @@ -998,6 +1049,7 @@ public ArrayJsonSchemaObject maxItems(int count) { * @param items the allowed items in the array. * @return new instance of {@link ArrayJsonSchemaObject}. */ + @Contract("_ -> new") public ArrayJsonSchemaObject items(Collection items) { ArrayJsonSchemaObject newInstance = newInstance(description, generateDescription, restrictions); @@ -1012,6 +1064,7 @@ public ArrayJsonSchemaObject items(Collection items) { * @param additionalItemsAllowed {@literal true} to allow additional items in the array, {@literal false} otherwise. * @return new instance of {@link ArrayJsonSchemaObject}. */ + @Contract("_ -> new") public ArrayJsonSchemaObject additionalItems(boolean additionalItemsAllowed) { ArrayJsonSchemaObject newInstance = newInstance(description, generateDescription, restrictions); @@ -1021,36 +1074,43 @@ public ArrayJsonSchemaObject additionalItems(boolean additionalItemsAllowed) { } @Override + @Contract("_ -> new") public ArrayJsonSchemaObject possibleValues(Collection possibleValues) { return newInstance(description, generateDescription, restrictions.possibleValues(possibleValues)); } @Override + @Contract("_ -> new") public ArrayJsonSchemaObject allOf(Collection allOf) { return newInstance(description, generateDescription, restrictions.allOf(allOf)); } @Override + @Contract("_ -> new") public ArrayJsonSchemaObject anyOf(Collection anyOf) { return newInstance(description, generateDescription, restrictions.anyOf(anyOf)); } @Override + @Contract("_ -> new") public ArrayJsonSchemaObject oneOf(Collection oneOf) { return newInstance(description, generateDescription, restrictions.oneOf(oneOf)); } @Override + @Contract("_ -> new") public ArrayJsonSchemaObject notMatch(JsonSchemaObject notMatch) { return newInstance(description, generateDescription, restrictions.notMatch(notMatch)); } @Override + @Contract("_ -> new") public ArrayJsonSchemaObject description(String description) { return newInstance(description, generateDescription, restrictions); } @Override + @Contract("_ -> new") public ArrayJsonSchemaObject generatedDescription() { return newInstance(description, true, restrictions); } @@ -1146,41 +1206,49 @@ private BooleanJsonSchemaObject(@Nullable String description, boolean generateDe } @Override + @Contract("_ -> new") public BooleanJsonSchemaObject possibleValues(Collection possibleValues) { return new BooleanJsonSchemaObject(description, generateDescription, restrictions.possibleValues(possibleValues)); } @Override + @Contract("_ -> new") public BooleanJsonSchemaObject allOf(Collection allOf) { return new BooleanJsonSchemaObject(description, generateDescription, restrictions.allOf(allOf)); } @Override + @Contract("_ -> new") public BooleanJsonSchemaObject anyOf(Collection anyOf) { return new BooleanJsonSchemaObject(description, generateDescription, restrictions.anyOf(anyOf)); } @Override + @Contract("_ -> new") public BooleanJsonSchemaObject oneOf(Collection oneOf) { return new BooleanJsonSchemaObject(description, generateDescription, restrictions.oneOf(oneOf)); } @Override + @Contract("_ -> new") public BooleanJsonSchemaObject notMatch(JsonSchemaObject notMatch) { return new BooleanJsonSchemaObject(description, generateDescription, restrictions.notMatch(notMatch)); } @Override + @Contract("_ -> new") public BooleanJsonSchemaObject description(String description) { return new BooleanJsonSchemaObject(description, generateDescription, restrictions); } @Override + @Contract("_ -> new") public BooleanJsonSchemaObject generatedDescription() { return new BooleanJsonSchemaObject(description, true, restrictions); } @Override + @Contract("-> new") protected String generateDescription() { return "Must be a boolean"; } @@ -1207,36 +1275,43 @@ private NullJsonSchemaObject(@Nullable String description, boolean generateDescr } @Override + @Contract("_ -> new") public NullJsonSchemaObject possibleValues(Collection possibleValues) { return new NullJsonSchemaObject(description, generateDescription, restrictions.possibleValues(possibleValues)); } @Override + @Contract("_ -> new") public NullJsonSchemaObject allOf(Collection allOf) { return new NullJsonSchemaObject(description, generateDescription, restrictions.allOf(allOf)); } @Override + @Contract("_ -> new") public NullJsonSchemaObject anyOf(Collection anyOf) { return new NullJsonSchemaObject(description, generateDescription, restrictions.anyOf(anyOf)); } @Override + @Contract("_ -> new") public NullJsonSchemaObject oneOf(Collection oneOf) { return new NullJsonSchemaObject(description, generateDescription, restrictions.oneOf(oneOf)); } @Override + @Contract("_ -> new") public NullJsonSchemaObject notMatch(JsonSchemaObject notMatch) { return new NullJsonSchemaObject(description, generateDescription, restrictions.notMatch(notMatch)); } @Override + @Contract("_ -> new") public NullJsonSchemaObject description(String description) { return new NullJsonSchemaObject(description, generateDescription, restrictions); } @Override + @Contract("-> new") public NullJsonSchemaObject generatedDescription() { return new NullJsonSchemaObject(description, true, restrictions); } @@ -1267,36 +1342,43 @@ private DateJsonSchemaObject(@Nullable String description, boolean generateDescr } @Override + @Contract("_ -> new") public DateJsonSchemaObject possibleValues(Collection possibleValues) { return new DateJsonSchemaObject(description, generateDescription, restrictions.possibleValues(possibleValues)); } @Override + @Contract("_ -> new") public DateJsonSchemaObject allOf(Collection allOf) { return new DateJsonSchemaObject(description, generateDescription, restrictions.allOf(allOf)); } @Override + @Contract("_ -> new") public DateJsonSchemaObject anyOf(Collection anyOf) { return new DateJsonSchemaObject(description, generateDescription, restrictions.anyOf(anyOf)); } @Override + @Contract("_ -> new") public DateJsonSchemaObject oneOf(Collection oneOf) { return new DateJsonSchemaObject(description, generateDescription, restrictions.oneOf(oneOf)); } @Override + @Contract("_ -> new") public DateJsonSchemaObject notMatch(JsonSchemaObject notMatch) { return new DateJsonSchemaObject(description, generateDescription, restrictions.notMatch(notMatch)); } @Override + @Contract("_ -> new") public DateJsonSchemaObject description(String description) { return new DateJsonSchemaObject(description, generateDescription, restrictions); } @Override + @Contract("-> new") public DateJsonSchemaObject generatedDescription() { return new DateJsonSchemaObject(description, true, restrictions); } @@ -1327,37 +1409,44 @@ private TimestampJsonSchemaObject(@Nullable String description, boolean generate } @Override + @Contract("_ -> new") public TimestampJsonSchemaObject possibleValues(Collection possibleValues) { return new TimestampJsonSchemaObject(description, generateDescription, restrictions.possibleValues(possibleValues)); } @Override + @Contract("_ -> new") public TimestampJsonSchemaObject allOf(Collection allOf) { return new TimestampJsonSchemaObject(description, generateDescription, restrictions.allOf(allOf)); } @Override + @Contract("_ -> new") public TimestampJsonSchemaObject anyOf(Collection anyOf) { return new TimestampJsonSchemaObject(description, generateDescription, restrictions.anyOf(anyOf)); } @Override + @Contract("_ -> new") public TimestampJsonSchemaObject oneOf(Collection oneOf) { return new TimestampJsonSchemaObject(description, generateDescription, restrictions.oneOf(oneOf)); } @Override + @Contract("_ -> new") public TimestampJsonSchemaObject notMatch(JsonSchemaObject notMatch) { return new TimestampJsonSchemaObject(description, generateDescription, restrictions.notMatch(notMatch)); } @Override + @Contract("_ -> new") public TimestampJsonSchemaObject description(String description) { return new TimestampJsonSchemaObject(description, generateDescription, restrictions); } @Override + @Contract("-> new") public TimestampJsonSchemaObject generatedDescription() { return new TimestampJsonSchemaObject(description, true, restrictions); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java index 3a312d9a9c..d13f8d7985 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/UntypedJsonSchemaObject.java @@ -24,6 +24,7 @@ import org.bson.Document; import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -69,6 +70,7 @@ public Set getTypes() { * @param description must not be {@literal null}. * @return new instance of {@link TypedJsonSchemaObject}. */ + @Contract("_ -> new") public UntypedJsonSchemaObject description(String description) { return new UntypedJsonSchemaObject(restrictions, description, generateDescription); } @@ -78,6 +80,7 @@ public UntypedJsonSchemaObject description(String description) { * * @return new instance of {@link TypedJsonSchemaObject}. */ + @Contract("-> new") public UntypedJsonSchemaObject generatedDescription() { return new UntypedJsonSchemaObject(restrictions, description, true); } @@ -88,6 +91,7 @@ public UntypedJsonSchemaObject generatedDescription() { * @param possibleValues must not be {@literal null}. * @return new instance of {@link TypedJsonSchemaObject}. */ + @Contract("_ -> new") public UntypedJsonSchemaObject possibleValues(Collection possibleValues) { return new UntypedJsonSchemaObject(restrictions.possibleValues(possibleValues), description, generateDescription); } @@ -98,6 +102,7 @@ public UntypedJsonSchemaObject possibleValues(Collection possi * @param allOf must not be {@literal null}. * @return new instance of {@link TypedJsonSchemaObject}. */ + @Contract("_ -> new") public UntypedJsonSchemaObject allOf(Collection allOf) { return new UntypedJsonSchemaObject(restrictions.allOf(allOf), description, generateDescription); } @@ -108,6 +113,7 @@ public UntypedJsonSchemaObject allOf(Collection allOf) { * @param anyOf must not be {@literal null}. * @return new instance of {@link TypedJsonSchemaObject}. */ + @Contract("_ -> new") public UntypedJsonSchemaObject anyOf(Collection anyOf) { return new UntypedJsonSchemaObject(restrictions.anyOf(anyOf), description, generateDescription); } @@ -118,6 +124,7 @@ public UntypedJsonSchemaObject anyOf(Collection anyOf) { * @param oneOf must not be {@literal null}. * @return new instance of {@link TypedJsonSchemaObject}. */ + @Contract("_ -> new") public UntypedJsonSchemaObject oneOf(Collection oneOf) { return new UntypedJsonSchemaObject(restrictions.oneOf(oneOf), description, generateDescription); } @@ -128,6 +135,7 @@ public UntypedJsonSchemaObject oneOf(Collection oneOf) { * @param notMatch must not be {@literal null}. * @return new instance of {@link TypedJsonSchemaObject}. */ + @Contract("_ -> new") public UntypedJsonSchemaObject notMatch(JsonSchemaObject notMatch) { return new UntypedJsonSchemaObject(restrictions.notMatch(notMatch), description, generateDescription); } @@ -205,6 +213,7 @@ static Restrictions empty() { * @param possibleValues must not be {@literal null}. * @return */ + @Contract("_ -> new") Restrictions possibleValues(Collection possibleValues) { Assert.notNull(possibleValues, "PossibleValues must not be null"); @@ -215,6 +224,7 @@ Restrictions possibleValues(Collection possibleValues) { * @param allOf must not be {@literal null}. * @return */ + @Contract("_ -> new") Restrictions allOf(Collection allOf) { Assert.notNull(allOf, "AllOf must not be null"); @@ -225,6 +235,7 @@ Restrictions allOf(Collection allOf) { * @param anyOf must not be {@literal null}. * @return */ + @Contract("_ -> new") Restrictions anyOf(Collection anyOf) { Assert.notNull(anyOf, "AnyOf must not be null"); @@ -235,6 +246,7 @@ Restrictions anyOf(Collection anyOf) { * @param oneOf must not be {@literal null}. * @return */ + @Contract("_ -> new") Restrictions oneOf(Collection oneOf) { Assert.notNull(oneOf, "OneOf must not be null"); @@ -245,6 +257,7 @@ Restrictions oneOf(Collection oneOf) { * @param notMatch must not be {@literal null}. * @return */ + @Contract("_ -> new") Restrictions notMatch(JsonSchemaObject notMatch) { Assert.notNull(notMatch, "NotMatch must not be null"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java index 1e22a5d3f3..99807e63a2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java @@ -19,6 +19,7 @@ import org.jspecify.annotations.Nullable; import com.mongodb.client.gridfs.model.GridFSFile; +import org.springframework.lang.Contract; /** * A common interface when dealing with GridFs items using Spring Data. @@ -110,6 +111,7 @@ public static Options from(@Nullable GridFSFile gridFSFile) { * @param contentType must not be {@literal null}. * @return new instance of {@link Options}. */ + @Contract("_ -> new") public Options contentType(String contentType) { Options target = new Options(new Document(metadata), chunkSize); @@ -121,6 +123,7 @@ public Options contentType(String contentType) { * @param metadata * @return new instance of {@link Options}. */ + @Contract("_ -> new") public Options metadata(Document metadata) { return new Options(metadata, chunkSize); } @@ -129,6 +132,7 @@ public Options metadata(Document metadata) { * @param chunkSize the file chunk size to use. * @return new instance of {@link Options}. */ + @Contract("_ -> new") public Options chunkSize(int chunkSize) { return new Options(metadata, chunkSize); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java index 49085f8007..6f2b9ed85b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java @@ -22,6 +22,7 @@ import org.bson.types.ObjectId; import org.jspecify.annotations.Nullable; import org.springframework.data.util.Lazy; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import com.mongodb.client.gridfs.model.GridFSFile; @@ -123,6 +124,7 @@ public GridFsUploadBuilder content(InputStream stream) { * @param stream the upload content. * @return this. */ + @Contract("_ -> this") public GridFsUploadBuilder content(Supplier stream) { Assert.notNull(stream, "InputStream Supplier must not be null"); @@ -139,6 +141,7 @@ public GridFsUploadBuilder content(Supplier stream) { * @return this. */ @SuppressWarnings("unchecked") + @Contract("_ -> this") public GridFsUploadBuilder id(T1 id) { this.id = id; @@ -151,6 +154,7 @@ public GridFsUploadBuilder id(T1 id) { * @param filename the filename to use. * @return this. */ + @Contract("_ -> this") public GridFsUploadBuilder filename(String filename) { this.filename = filename; @@ -163,6 +167,7 @@ public GridFsUploadBuilder filename(String filename) { * @param options must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public GridFsUploadBuilder options(Options options) { Assert.notNull(options, "Options must not be null"); @@ -177,6 +182,7 @@ public GridFsUploadBuilder options(Options options) { * @param metadata must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public GridFsUploadBuilder metadata(Document metadata) { this.options = this.options.metadata(metadata); @@ -189,6 +195,7 @@ public GridFsUploadBuilder metadata(Document metadata) { * @param chunkSize use negative number for default. * @return this. */ + @Contract("_ -> this") public GridFsUploadBuilder chunkSize(int chunkSize) { this.options = this.options.chunkSize(chunkSize); @@ -201,6 +208,7 @@ public GridFsUploadBuilder chunkSize(int chunkSize) { * @param gridFSFile must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public GridFsUploadBuilder gridFsFile(GridFSFile gridFSFile) { Assert.notNull(gridFSFile, "GridFSFile must not be null"); @@ -219,12 +227,14 @@ public GridFsUploadBuilder gridFsFile(GridFSFile gridFSFile) { * @param contentType must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public GridFsUploadBuilder contentType(String contentType) { this.options = this.options.contentType(contentType); return this; } + @Contract("-> new") public GridFsUpload build() { Assert.notNull(dataStream, "DataStream must be set first"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java index f523677549..09ea77798c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java @@ -20,6 +20,7 @@ import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import com.mongodb.client.gridfs.model.GridFSFile; @@ -107,6 +108,7 @@ private ReactiveGridFsUploadBuilder() {} * @param source the upload content. * @return this. */ + @Contract("_ -> this") public ReactiveGridFsUploadBuilder content(Publisher source) { this.dataStream = source; return this; @@ -119,6 +121,7 @@ public ReactiveGridFsUploadBuilder content(Publisher source) { * @param * @return this. */ + @Contract("_ -> this") public ReactiveGridFsUploadBuilder id(T1 id) { this.id = id; @@ -131,6 +134,7 @@ public ReactiveGridFsUploadBuilder id(T1 id) { * @param filename the filename to use. * @return this. */ + @Contract("_ -> this") public ReactiveGridFsUploadBuilder filename(String filename) { this.filename = filename; @@ -143,6 +147,7 @@ public ReactiveGridFsUploadBuilder filename(String filename) { * @param options must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public ReactiveGridFsUploadBuilder options(Options options) { Assert.notNull(options, "Options must not be null"); @@ -155,8 +160,9 @@ public ReactiveGridFsUploadBuilder options(Options options) { * Set the file metadata. * * @param metadata must not be {@literal null}. - * @return + * @return this. */ + @Contract("_ -> this") public ReactiveGridFsUploadBuilder metadata(Document metadata) { this.options = this.options.metadata(metadata); @@ -167,8 +173,9 @@ public ReactiveGridFsUploadBuilder metadata(Document metadata) { * Set the upload chunk size in bytes. * * @param chunkSize use negative number for default. - * @return + * @return this. */ + @Contract("_ -> this") public ReactiveGridFsUploadBuilder chunkSize(int chunkSize) { this.options = this.options.chunkSize(chunkSize); @@ -181,6 +188,7 @@ public ReactiveGridFsUploadBuilder chunkSize(int chunkSize) { * @param gridFSFile must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public ReactiveGridFsUploadBuilder gridFsFile(GridFSFile gridFSFile) { Assert.notNull(gridFSFile, "GridFSFile must not be null"); @@ -199,12 +207,14 @@ public ReactiveGridFsUploadBuilder gridFsFile(GridFSFile gridFSFile) { * @param contentType must not be {@literal null}. * @return this. */ + @Contract("_ -> this") public ReactiveGridFsUploadBuilder contentType(String contentType) { this.options = this.options.contentType(contentType); return this; } + @Contract("-> new") public ReactiveGridFsUpload build() { Assert.notNull(dataStream, "DataStream must be set first"); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/Order.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/Order.java index 1174507e1c..a463b72cff 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/Order.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/Order.java @@ -20,6 +20,8 @@ import java.util.Date; import java.util.List; +import org.springframework.lang.Contract; + /** * @author Thomas Darimont */