1
0
mirror of synced 2026-05-22 20:23:18 +00:00

nullability-fixes

Closes #3282

Signed-off-by: Peter-Josef Meisch <pj.meisch@sothawo.com>
This commit is contained in:
Peter-Josef Meisch
2026-05-02 11:20:02 +02:00
committed by GitHub
parent 795e1ef60a
commit 8ad2e8e0a0
202 changed files with 2364 additions and 810 deletions
@@ -15,10 +15,11 @@
*/
package org.springframework.data.elasticsearch;
import org.springframework.dao.DataRetrievalFailureException;
import java.util.Map;
import org.jspecify.annotations.Nullable;
import org.springframework.dao.DataRetrievalFailureException;
/**
* @author Peter-Josef Meisch
* @author Illia Ulianov
@@ -42,6 +43,6 @@ public class BulkFailureException extends DataRetrievalFailureException {
* @author Illia Ulianov
* @since 5.2
*/
public record FailureDetails(Integer status, String errorMessage) {
public record FailureDetails(Integer status, @Nullable String errorMessage) {
}
}
@@ -28,7 +28,7 @@ import org.jspecify.annotations.Nullable;
public class ElasticsearchErrorCause {
@Nullable private final String type;
private final String reason;
@Nullable private final String reason;
@Nullable private final String stackTrace;
@@ -38,7 +38,7 @@ public class ElasticsearchErrorCause {
private final List<ElasticsearchErrorCause> suppressed;
public ElasticsearchErrorCause(@Nullable String type, String reason, @Nullable String stackTrace,
public ElasticsearchErrorCause(@Nullable String type, @Nullable String reason, @Nullable String stackTrace,
@Nullable ElasticsearchErrorCause causedBy, List<ElasticsearchErrorCause> rootCause,
List<ElasticsearchErrorCause> suppressed) {
this.type = type;
@@ -54,7 +54,7 @@ public class ElasticsearchErrorCause {
return type;
}
public String getReason() {
public @Nullable String getReason() {
return reason;
}
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.annotations;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.aot;
@@ -24,6 +24,14 @@ import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.NestedIdentity;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.json.JsonpMapper;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
@@ -36,13 +44,6 @@ import org.springframework.data.elasticsearch.core.document.SearchDocumentAdapte
import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse;
import org.springframework.util.Assert;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Utility class to adapt different Elasticsearch responses to a
* {@link org.springframework.data.elasticsearch.core.document.Document}
@@ -54,188 +55,187 @@ import java.util.stream.Collectors;
*/
final class DocumentAdapters {
private static final Log LOGGER = LogFactory.getLog(DocumentAdapters.class);
private static final Log LOGGER = LogFactory.getLog(DocumentAdapters.class);
private DocumentAdapters() {
}
private DocumentAdapters() {}
/**
* Creates a {@link SearchDocument} from a {@link Hit} returned by the Elasticsearch client.
*
* @param hit the hit object
* @param jsonpMapper to map JsonData objects
* @return the created {@link SearchDocument}
*/
public static SearchDocument from(Hit<?> hit, JsonpMapper jsonpMapper) {
/**
* Creates a {@link SearchDocument} from a {@link Hit} returned by the Elasticsearch client.
*
* @param hit the hit object
* @param jsonpMapper to map JsonData objects
* @return the created {@link SearchDocument}
*/
public static SearchDocument from(Hit<?> hit, JsonpMapper jsonpMapper) {
Assert.notNull(hit, "hit must not be null");
Assert.notNull(hit, "hit must not be null");
Map<String, List<String>> highlightFields = hit.highlight();
Map<String, List<String>> highlightFields = hit.highlight();
Map<String, SearchDocumentResponse> innerHits = new LinkedHashMap<>();
hit.innerHits().forEach((name, innerHitsResult) -> {
// noinspection ReturnOfNull
innerHits.put(name, SearchDocumentResponseBuilder.from(innerHitsResult.hits(), null, null, null, 0, null, null,
searchDocument -> null, jsonpMapper));
});
Map<String, SearchDocumentResponse> innerHits = new LinkedHashMap<>();
hit.innerHits().forEach((name, innerHitsResult) -> {
// noinspection ReturnOfNull
innerHits.put(name, SearchDocumentResponseBuilder.from(innerHitsResult.hits(), null, null, null, 0, null, null,
searchDocument -> null, jsonpMapper));
});
NestedMetaData nestedMetaData = from(hit.nested());
NestedMetaData nestedMetaData = from(hit.nested());
Explanation explanation = from(hit.explanation());
Explanation explanation = from(hit.explanation());
Map<String, Double> matchedQueries = hit.matchedQueries();
Map<String, Double> matchedQueries = hit.matchedQueries();
Function<Map<String, JsonData>, EntityAsMap> fromFields = fields -> {
StringBuilder sb = new StringBuilder("{");
final boolean[] firstField = {true};
hit.fields().forEach((key, jsonData) -> {
if (!firstField[0]) {
sb.append(',');
}
sb.append('"').append(key).append("\":") //
.append(jsonData.toJson(jsonpMapper).toString());
firstField[0] = false;
});
sb.append('}');
return new EntityAsMap().fromJson(sb.toString());
};
Function<Map<String, JsonData>, EntityAsMap> fromFields = fields -> {
StringBuilder sb = new StringBuilder("{");
final boolean[] firstField = { true };
hit.fields().forEach((key, jsonData) -> {
if (!firstField[0]) {
sb.append(',');
}
sb.append('"').append(key).append("\":") //
.append(jsonData.toJson(jsonpMapper).toString());
firstField[0] = false;
});
sb.append('}');
return new EntityAsMap().fromJson(sb.toString());
};
EntityAsMap hitFieldsAsMap = fromFields.apply(hit.fields());
EntityAsMap hitFieldsAsMap = fromFields.apply(hit.fields());
Map<String, List<Object>> documentFields = new LinkedHashMap<>();
hitFieldsAsMap.forEach((key, value) -> {
if (value instanceof List) {
// noinspection unchecked
documentFields.put(key, (List<Object>) value);
} else {
documentFields.put(key, Collections.singletonList(value));
}
});
Map<String, List<@Nullable Object>> documentFields = new LinkedHashMap<>();
hitFieldsAsMap.forEach((key, value) -> {
if (value instanceof List) {
// noinspection unchecked
documentFields.put(key, (List<Object>) value);
} else {
documentFields.put(key, Collections.singletonList(value));
}
});
Document document;
Object source = hit.source();
if (source == null) {
document = Document.from(hitFieldsAsMap);
} else {
if (source instanceof EntityAsMap entityAsMap) {
document = Document.from(entityAsMap);
} else if (source instanceof JsonData jsonData) {
document = Document.from(jsonData.to(EntityAsMap.class));
} else {
Document document;
Object source = hit.source();
if (source == null) {
document = Document.from(hitFieldsAsMap);
} else {
if (source instanceof EntityAsMap entityAsMap) {
document = Document.from(entityAsMap);
} else if (source instanceof JsonData jsonData) {
document = Document.from(jsonData.to(EntityAsMap.class));
} else {
if (LOGGER.isWarnEnabled()) {
LOGGER.warn(String.format("Cannot map from type " + source.getClass().getName()));
}
document = Document.create();
}
}
document.setIndex(hit.index());
document.setId(hit.id());
if (LOGGER.isWarnEnabled()) {
LOGGER.warn(String.format("Cannot map from type " + source.getClass().getName()));
}
document = Document.create();
}
}
document.setIndex(hit.index());
document.setId(hit.id());
if (hit.version() != null) {
document.setVersion(hit.version());
}
document.setSeqNo(hit.seqNo() != null && hit.seqNo() >= 0 ? hit.seqNo() : -2); // -2 was the default value in the
// old client
document.setPrimaryTerm(hit.primaryTerm() != null && hit.primaryTerm() > 0 ? hit.primaryTerm() : 0);
if (hit.version() != null) {
document.setVersion(hit.version());
}
document.setSeqNo(hit.seqNo() != null && hit.seqNo() >= 0 ? hit.seqNo() : -2); // -2 was the default value in the
// old client
document.setPrimaryTerm(hit.primaryTerm() != null && hit.primaryTerm() > 0 ? hit.primaryTerm() : 0);
float score = hit.score() != null ? hit.score().floatValue() : Float.NaN;
return new SearchDocumentAdapter(document, score, hit.sort().stream().map(TypeUtils::toObject).toArray(),
documentFields, highlightFields, innerHits, nestedMetaData, explanation, matchedQueries, hit.routing());
}
float score = hit.score() != null ? hit.score().floatValue() : Float.NaN;
return new SearchDocumentAdapter(document, score, hit.sort().stream().map(TypeUtils::toObject).toArray(),
documentFields, highlightFields, innerHits, nestedMetaData, explanation, matchedQueries, hit.routing());
}
public static SearchDocument from(CompletionSuggestOption<EntityAsMap> completionSuggestOption) {
public static SearchDocument from(CompletionSuggestOption<EntityAsMap> completionSuggestOption) {
Document document = completionSuggestOption.source() != null ? Document.from(completionSuggestOption.source())
: Document.create();
document.setIndex(completionSuggestOption.index());
Document document = completionSuggestOption.source() != null ? Document.from(completionSuggestOption.source())
: Document.create();
document.setIndex(completionSuggestOption.index());
if (completionSuggestOption.id() != null) {
document.setId(completionSuggestOption.id());
}
if (completionSuggestOption.id() != null) {
document.setId(completionSuggestOption.id());
}
float score = completionSuggestOption.score() != null ? completionSuggestOption.score().floatValue() : Float.NaN;
return new SearchDocumentAdapter(document, score, new Object[]{}, Collections.emptyMap(), Collections.emptyMap(),
Collections.emptyMap(), null, null, null, completionSuggestOption.routing());
}
float score = completionSuggestOption.score() != null ? completionSuggestOption.score().floatValue() : Float.NaN;
return new SearchDocumentAdapter(document, score, new Object[] {}, Collections.emptyMap(), Collections.emptyMap(),
Collections.emptyMap(), null, null, null, completionSuggestOption.routing());
}
@Nullable
private static Explanation from(co.elastic.clients.elasticsearch.core.explain.@Nullable Explanation explanation) {
@Nullable
private static Explanation from(co.elastic.clients.elasticsearch.core.explain.@Nullable Explanation explanation) {
if (explanation == null) {
return null;
}
List<Explanation> details = explanation.details().stream().map(DocumentAdapters::from).collect(Collectors.toList());
return new Explanation(true, (double) explanation.value(), explanation.description(), details);
}
if (explanation == null) {
return null;
}
List<Explanation> details = explanation.details().stream().map(DocumentAdapters::from).collect(Collectors.toList());
return new Explanation(true, (double) explanation.value(), explanation.description(), details);
}
private static Explanation from(ExplanationDetail explanationDetail) {
private static Explanation from(ExplanationDetail explanationDetail) {
List<Explanation> details = explanationDetail.details().stream().map(DocumentAdapters::from)
.collect(Collectors.toList());
return new Explanation(null, (double) explanationDetail.value(), explanationDetail.description(), details);
}
List<Explanation> details = explanationDetail.details().stream().map(DocumentAdapters::from)
.collect(Collectors.toList());
return new Explanation(null, (double) explanationDetail.value(), explanationDetail.description(), details);
}
@Nullable
private static NestedMetaData from(@Nullable NestedIdentity nestedIdentity) {
@Nullable
private static NestedMetaData from(@Nullable NestedIdentity nestedIdentity) {
if (nestedIdentity == null) {
return null;
}
if (nestedIdentity == null) {
return null;
}
NestedMetaData child = from(nestedIdentity.nested());
return NestedMetaData.of(nestedIdentity.field(), nestedIdentity.offset(), child);
}
NestedMetaData child = from(nestedIdentity.nested());
return NestedMetaData.of(nestedIdentity.field(), nestedIdentity.offset(), child);
}
/**
* Creates a {@link Document} from a {@link GetResponse} where the found document is contained as {@link EntityAsMap}.
*
* @param getResponse the response instance
* @return the Document
*/
@Nullable
public static Document from(GetResult<EntityAsMap> getResponse) {
/**
* Creates a {@link Document} from a {@link GetResponse} where the found document is contained as {@link EntityAsMap}.
*
* @param getResponse the response instance
* @return the Document
*/
@Nullable
public static Document from(GetResult<EntityAsMap> getResponse) {
Assert.notNull(getResponse, "getResponse must not be null");
Assert.notNull(getResponse, "getResponse must not be null");
if (!getResponse.found()) {
return null;
}
if (!getResponse.found()) {
return null;
}
Document document = getResponse.source() != null ? Document.from(getResponse.source()) : Document.create();
document.setIndex(getResponse.index());
document.setId(getResponse.id());
Document document = getResponse.source() != null ? Document.from(getResponse.source()) : Document.create();
document.setIndex(getResponse.index());
document.setId(getResponse.id());
if (getResponse.version() != null) {
document.setVersion(getResponse.version());
}
if (getResponse.version() != null) {
document.setVersion(getResponse.version());
}
if (getResponse.seqNo() != null) {
document.setSeqNo(getResponse.seqNo());
}
if (getResponse.seqNo() != null) {
document.setSeqNo(getResponse.seqNo());
}
if (getResponse.primaryTerm() != null) {
document.setPrimaryTerm(getResponse.primaryTerm());
}
if (getResponse.primaryTerm() != null) {
document.setPrimaryTerm(getResponse.primaryTerm());
}
return document;
}
return document;
}
/**
* Creates a list of {@link MultiGetItem}s from a {@link MgetResponse} where the data is contained as
* {@link EntityAsMap} instances.
*
* @param mgetResponse the response instance
* @return list of multiget items
*/
public static List<MultiGetItem<Document>> from(MgetResponse<EntityAsMap> mgetResponse) {
/**
* Creates a list of {@link MultiGetItem}s from a {@link MgetResponse} where the data is contained as
* {@link EntityAsMap} instances.
*
* @param mgetResponse the response instance
* @return list of multiget items
*/
public static List<MultiGetItem<Document>> from(MgetResponse<EntityAsMap> mgetResponse) {
Assert.notNull(mgetResponse, "mgetResponse must not be null");
Assert.notNull(mgetResponse, "mgetResponse must not be null");
return mgetResponse.docs().stream() //
.map(itemResponse -> MultiGetItem.of( //
itemResponse.isFailure() ? null : from(itemResponse.result()), //
ResponseConverter.getFailure(itemResponse)))
.collect(Collectors.toList());
}
return mgetResponse.docs().stream() //
.map(itemResponse -> MultiGetItem.of( //
itemResponse.isFailure() ? null : from(itemResponse.result()), //
ResponseConverter.getFailure(itemResponse)))
.collect(Collectors.toList());
}
}
@@ -114,7 +114,7 @@ public class IndicesTemplate extends ChildTemplate<ElasticsearchTransport, Elast
}
@Override
public boolean create(Map<String, Object> settings) {
public boolean create(Map<String, @Nullable Object> settings) {
Assert.notNull(settings, "settings must not be null");
@@ -122,7 +122,7 @@ public class IndicesTemplate extends ChildTemplate<ElasticsearchTransport, Elast
}
@Override
public boolean create(Map<String, Object> settings, Document mapping) {
public boolean create(Map<String, @Nullable Object> settings, Document mapping) {
Assert.notNull(settings, "settings must not be null");
Assert.notNull(mapping, "mapping must not be null");
@@ -135,7 +135,7 @@ public class IndicesTemplate extends ChildTemplate<ElasticsearchTransport, Elast
return doCreate(getIndexCoordinates(), createSettings(), createMapping());
}
protected boolean doCreate(IndexCoordinates indexCoordinates, Map<String, Object> settings,
protected boolean doCreate(IndexCoordinates indexCoordinates, Map<String, @Nullable Object> settings,
@Nullable Document mapping) {
Set<Alias> aliases = (boundClass != null) ? getAliasesFor(boundClass) : new HashSet<>();
CreateIndexSettings indexSettings = CreateIndexSettings.builder(indexCoordinates)
@@ -233,7 +233,7 @@ public class IndicesTemplate extends ChildTemplate<ElasticsearchTransport, Elast
}
@Override
public Map<String, Object> getMapping() {
public Map<String, @Nullable Object> getMapping() {
IndexCoordinates indexCoordinates = getIndexCoordinates();
GetMappingRequest getMappingRequest = requestConverter.indicesGetMappingRequest(indexCoordinates);
@@ -18,9 +18,30 @@ package org.springframework.data.elasticsearch.client.elc;
import static co.elastic.clients.util.ApiTypeHelper.*;
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.*;
import co.elastic.clients.elasticsearch._types.Result;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
import co.elastic.clients.elasticsearch.core.search.ResponseBody;
import co.elastic.clients.json.JsonpMapper;
import co.elastic.clients.transport.Version;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuple2;
import java.time.Duration;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.reactivestreams.Publisher;
import org.springframework.beans.BeansException;
@@ -52,28 +73,6 @@ import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.time.Duration;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import co.elastic.clients.elasticsearch._types.Result;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
import co.elastic.clients.elasticsearch.core.search.ResponseBody;
import co.elastic.clients.json.JsonpMapper;
import co.elastic.clients.transport.Version;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuple2;
/**
* Implementation of {@link org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations} using the new
* Elasticsearch client.
@@ -269,7 +268,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
ExistsRequest existsRequest = requestConverter.documentExistsRequest(id, routingResolver.getRouting(), index);
return Mono.from(execute(
((ClientCallback<@NonNull Publisher<BooleanResponse>>) client -> client.exists(existsRequest))))
((ClientCallback<Publisher<BooleanResponse>>) client -> client.exists(existsRequest))))
.map(BooleanResponse::value) //
.onErrorReturn(NoSuchIndexException.class, false);
}
@@ -381,7 +380,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
for (BulkResponseItem item : bulkResponse.items()) {
if (item.error() != null) {
if (item.error() != null && item.id() != null) {
failedDocuments.put(item.id(), new BulkFailureException.FailureDetails(item.status(), item.error().reason()));
}
}
@@ -538,7 +537,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
return Mono.empty();
}
List<Object> sortOptions = hits.get(hits.size() - 1).sort().stream().map(TypeUtils::toObject)
List<Object> sortOptions = hits.get(hits.size() - 1).sort().stream().map(TypeUtils::toObjectNotNull)
.collect(Collectors.toList());
baseQuery.setSearchAfter(sortOptions);
SearchRequest followSearchRequest = requestConverter.searchRequest(baseQuery,
@@ -632,8 +631,8 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
SearchRequest searchRequest = requestConverter.searchRequest(query, routingResolver.getRouting(), clazz, index,
false);
// noinspection unchecked
SearchDocumentCallback<T> callback = new ReadSearchDocumentCallback<>((Class<T>) clazz, index);
SearchDocumentResponse.EntityCreator<T> entityCreator = searchDocument -> callback.toEntity(searchDocument)
.toFuture();
@@ -108,7 +108,7 @@ public class ReactiveIndicesTemplate
}
@Override
public Mono<Boolean> create(Map<String, Object> settings) {
public Mono<Boolean> create(Map<String, @Nullable Object> settings) {
Assert.notNull(settings, "settings must not be null");
@@ -116,7 +116,7 @@ public class ReactiveIndicesTemplate
}
@Override
public Mono<Boolean> create(Map<String, Object> settings, Document mapping) {
public Mono<Boolean> create(Map<String, @Nullable Object> settings, Document mapping) {
Assert.notNull(settings, "settings must not be null");
Assert.notNull(mapping, "mapping must not be null");
@@ -132,7 +132,7 @@ public class ReactiveIndicesTemplate
doCreate(getIndexCoordinates(), settings, mapping))); //
}
private Mono<Boolean> doCreate(IndexCoordinates indexCoordinates, Map<String, Object> settings,
private Mono<Boolean> doCreate(IndexCoordinates indexCoordinates, Map<String, @Nullable Object> settings,
@Nullable Document mapping) {
Set<Alias> aliases = (boundClass != null) ? getAliasesFor(boundClass) : new HashSet<>();
CreateIndexSettings indexSettings = CreateIndexSettings.builder(indexCoordinates)
@@ -270,7 +270,7 @@ public class ReactiveIndicesTemplate
return getAliases(null, indexNames);
}
private Mono<Map<String, Set<AliasData>>> getAliases(@Nullable String[] aliasNames, @Nullable String[] indexNames) {
private Mono<Map<String, Set<AliasData>>> getAliases(String@Nullable [] aliasNames, String@Nullable [] indexNames) {
GetAliasRequest getAliasRequest = requestConverter.indicesGetAliasRequest(aliasNames, indexNames);
Mono<GetAliasResponse> getAliasResponse = Mono.from(execute(client -> client.getAlias(getAliasRequest)));
@@ -66,6 +66,7 @@ import org.springframework.data.elasticsearch.core.reindex.ReindexResponse;
import org.springframework.data.elasticsearch.core.script.Script;
import org.springframework.data.elasticsearch.core.sql.SqlResponse;
import org.springframework.data.elasticsearch.support.DefaultStringObjectMap;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;
/**
@@ -339,7 +340,7 @@ class ResponseConverter {
List<String> composedOf) {
var mapping = typeMapping(indexTemplateSummary.mappings());
Function<IndexSettings, Settings> indexSettingsToSettings = indexSettings -> {
Function<@Nullable IndexSettings, @Nullable Settings> indexSettingsToSettings = indexSettings -> {
if (indexSettings == null) {
return null;
@@ -497,7 +498,7 @@ class ResponseConverter {
builder.withDeleted(response.deleted());
}
if(response.updated() != null) {
if (response.updated() != null) {
builder.withUpdated(response.updated());
}
@@ -574,17 +575,20 @@ class ResponseConverter {
}
}
@Contract("null -> null; !null -> !null")
@Nullable
static ElasticsearchErrorCause toErrorCause(@Nullable ErrorCause errorCause) {
if (errorCause != null) {
return new ElasticsearchErrorCause( //
errorCause.type(), //
errorCause.reason(), //
errorCause.stackTrace(), //
toErrorCause(errorCause.causedBy()), //
errorCause.rootCause().stream().map(ResponseConverter::toErrorCause).collect(Collectors.toList()), //
errorCause.suppressed().stream().map(ResponseConverter::toErrorCause).collect(Collectors.toList()));
return new ElasticsearchErrorCause(
errorCause.type(),
errorCause.reason(),
errorCause.stackTrace(),
toErrorCause(errorCause.causedBy()),
(List<ElasticsearchErrorCause>) (errorCause.rootCause().stream()
.map(ResponseConverter::toErrorCause).collect(Collectors.toList())),
(List<ElasticsearchErrorCause>) (errorCause.suppressed().stream().map(ResponseConverter::toErrorCause)
.collect(Collectors.toList())));
} else {
return null;
}
@@ -36,6 +36,7 @@ import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.jspecify.annotations.Nullable;
@@ -144,6 +145,12 @@ final class TypeUtils {
}
}
static Object toObjectNotNull(FieldValue fieldValue) {
Objects.requireNonNull(fieldValue);
return toObject(fieldValue);
}
@Nullable
static Object toObject(@Nullable FieldValue fieldValue) {
@@ -485,7 +492,7 @@ final class TypeUtils {
}
@Nullable
static IndexSettings indexSettings(@Nullable Map<String, Object> settings) {
static IndexSettings indexSettings(@Nullable Map<String, @Nullable Object> settings) {
return settings != null ? IndexSettings.of(b -> b.withJson(new StringReader(Document.from(settings).toJson())))
: null;
}
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.client.elc.aot;
@@ -28,7 +28,6 @@ import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.http.nio.ssl.BasicClientTlsStrategy;
import org.apache.hc.core5.util.Timeout;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.support.HttpHeaders;
@@ -181,7 +180,7 @@ public final class Rest5Clients {
return builder;
}
private static HttpHost @NonNull [] getHttpHosts(ClientConfiguration clientConfiguration) {
private static HttpHost[] getHttpHosts(ClientConfiguration clientConfiguration) {
List<InetSocketAddress> hosts = clientConfiguration.getEndpoints();
boolean useSsl = clientConfiguration.useSsl();
return hosts.stream()
@@ -21,10 +21,8 @@ import org.apache.http.protocol.HttpContext;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchClients;
import org.springframework.data.elasticsearch.support.HttpHeaders;
import org.springframework.util.Assert;
@@ -107,7 +105,7 @@ public final class RestClients {
return builder;
}
private static HttpHost @NonNull [] getHttpHosts(ClientConfiguration clientConfiguration) {
private static HttpHost[] getHttpHosts(ClientConfiguration clientConfiguration) {
List<InetSocketAddress> hosts = clientConfiguration.getEndpoints();
boolean useSsl = clientConfiguration.useSsl();
return hosts.stream()
@@ -130,10 +128,10 @@ public final class RestClients {
record CustomHeaderInjector(Supplier<HttpHeaders> headersSupplier) implements HttpRequestInterceptor {
@Override
public void process(HttpRequest request, HttpContext context) {
public void process(@Nullable HttpRequest request, @Nullable HttpContext context) {
HttpHeaders httpHeaders = headersSupplier.get();
if (httpHeaders != null && !httpHeaders.isEmpty()) {
if (!httpHeaders.isEmpty() && request != null) {
Arrays.stream(toHeaderArray(httpHeaders)).forEach(request::addHeader);
}
}
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.client;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.client.util;
@@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.config;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jspecify.annotations.Nullable;
@@ -98,7 +99,7 @@ public class ElasticsearchConfigurationSupport {
protected Collection<String> getMappingBasePackages() {
Package mappingBasePackage = getClass().getPackage();
return Collections.singleton(mappingBasePackage == null ? null : mappingBasePackage.getName());
return mappingBasePackage == null ? Collections.emptyList() : List.of(mappingBasePackage.getName());
}
/**
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.config;
@@ -59,6 +59,7 @@ import org.springframework.data.elasticsearch.support.VersionInfo;
import org.springframework.data.mapping.callback.EntityCallbacks;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.util.Streamable;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -260,7 +261,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
List<IndexedObjectInformation> indexedObjectInformationList = bulkIndex(indexQueries, index);
Iterator<IndexedObjectInformation> iterator = indexedObjectInformationList.iterator();
// noinspection unchecked
// noinspection unchecked,DataFlowIssue
return indexQueries.stream() //
.map(IndexQuery::getObject) //
.map(entity -> (T) entityOperations.updateIndexedObject(
@@ -593,7 +594,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
}
protected <T> SearchDocumentResponse.EntityCreator<T> getEntityCreator(ReadDocumentCallback<T> documentCallback) {
return searchDocument -> CompletableFuture.completedFuture(documentCallback.doWith(searchDocument));
return searchDocument -> CompletableFuture.<T> completedFuture(documentCallback.doWith(searchDocument));
}
/**
@@ -752,6 +753,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
// region Document callbacks
protected interface DocumentCallback<T> {
@Contract("null -> null")
@Nullable
T doWith(@Nullable Document document);
}
@@ -815,6 +817,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
@Override
public SearchHits<T> doWith(SearchDocumentResponse response) {
// noinspection NullableProblems,DataFlowIssue
List<T> entities = response.getSearchDocuments().stream().map(delegate::doWith).collect(Collectors.toList());
return SearchHitMapping.mappingFor(type, elasticsearchConverter).mapHits(response, entities);
}
@@ -835,6 +838,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
@Override
public SearchScrollHits<T> doWith(SearchDocumentResponse response) {
// noinspection DataFlowIssue,NullableProblems
List<T> entities = response.getSearchDocuments().stream().map(delegate::doWith).collect(Collectors.toList());
return SearchHitMapping.mappingFor(type, elasticsearchConverter).mapScrollHits(response, entities);
}
@@ -766,7 +766,8 @@ abstract public class AbstractReactiveElasticsearchTemplate
/**
* Value class to capture client independent information from a response to an index request.
*/
public record IndexResponseMetaData(String id, String index, long seqNo, long primaryTerm, long version) {
public record IndexResponseMetaData(String id, String index, @Nullable Long seqNo, @Nullable Long primaryTerm,
long version) {
}
// endregion
@@ -17,7 +17,6 @@ package org.springframework.data.elasticsearch.core;
import java.util.Map;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
@@ -370,7 +369,7 @@ public class EntityOperations {
* @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptableEntity#initializeVersionProperty()
*/
@Override
public @NonNull T initializeVersionProperty() {
public T initializeVersionProperty() {
return map;
}
@@ -399,7 +398,7 @@ public class EntityOperations {
* @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptableEntity#incrementVersion()
*/
@Override
public @NonNull T incrementVersion() {
public T incrementVersion() {
return map;
}
@@ -408,7 +407,7 @@ public class EntityOperations {
* @see org.springframework.data.elasticsearch.core.EntityOperations.Entity#getBean()
*/
@Override
public @NonNull T getBean() {
public T getBean() {
return map;
}
@@ -52,7 +52,7 @@ public interface IndexOperations {
* @param settings the index settings
* @return {@literal true} if the index was created
*/
boolean create(Map<String, Object> settings);
boolean create(Map<String, @Nullable Object> settings);
/**
* Create an index for given settings and mapping.
@@ -62,7 +62,7 @@ public interface IndexOperations {
* @return {@literal true} if the index was created
* @since 4.2
*/
boolean create(Map<String, Object> settings, Document mapping);
boolean create(Map<String, @Nullable Object> settings, Document mapping);
/**
* Create an index with the settings and mapping defined for the entity this IndexOperations is bound to.
@@ -142,7 +142,7 @@ public interface IndexOperations {
*
* @return the mapping
*/
Map<String, Object> getMapping();
Map<String, @Nullable Object> getMapping();
// endregion
@@ -46,12 +46,12 @@ public interface IndexOperationsAdapter extends IndexOperations {
}
@Override
public boolean create(Map<String, Object> settings) {
public boolean create(Map<String, @Nullable Object> settings) {
return Boolean.TRUE.equals(reactiveIndexOperations.create(settings).block());
}
@Override
public boolean create(Map<String, Object> settings, Document mapping) {
public boolean create(Map<String, @Nullable Object> settings, Document mapping) {
return Boolean.TRUE.equals(reactiveIndexOperations.create(settings, mapping).block());
}
@@ -92,7 +92,7 @@ public interface IndexOperationsAdapter extends IndexOperations {
}
@Override
public Map<String, Object> getMapping() {
public Map<String, @Nullable Object> getMapping() {
return Objects.requireNonNull(reactiveIndexOperations.getMapping().block());
}
@@ -36,7 +36,7 @@ public class MultiGetItem<T> {
}
public static <T> MultiGetItem<T> of(@Nullable T item, @Nullable Failure failure) {
return new MultiGetItem<>(item, failure);
return new MultiGetItem(item, failure);
}
public boolean hasItem() {
@@ -21,6 +21,7 @@ import reactor.core.publisher.Mono;
import java.util.Map;
import java.util.Set;
import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.index.*;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
@@ -50,7 +51,7 @@ public interface ReactiveIndexOperations {
* @return a {@link Mono} signalling successful operation completion or an {@link Mono#error(Throwable) error} if eg.
* the index already exist.
*/
Mono<Boolean> create(Map<String, Object> settings);
Mono<Boolean> create(Map<String, @Nullable Object> settings);
/**
* Create an index for given settings and mapping.
@@ -61,7 +62,7 @@ public interface ReactiveIndexOperations {
* the index already exist.
* @since 4.2
*/
Mono<Boolean> create(Map<String, Object> settings, Document mapping);
Mono<Boolean> create(Map<String, @Nullable Object> settings, Document mapping);
/**
* Create an index with the settings and mapping defined for the entity this IndexOperations is bound to.
@@ -51,7 +51,7 @@ public class SearchHit<T> {
private final Map<String, Double> matchedQueries = new LinkedHashMap<>();
public SearchHit(@Nullable String index, @Nullable String id, @Nullable String routing, float score,
@Nullable Object[] sortValues, @Nullable Map<String, List<String>> highlightFields,
Object @Nullable [] sortValues, @Nullable Map<String, List<String>> highlightFields,
@Nullable Map<String, SearchHits<?>> innerHits, @Nullable NestedMetaData nestedMetaData,
@Nullable Explanation explanation, @Nullable Map<String, Double> matchedQueries, T content) {
this.index = index;
@@ -193,7 +193,6 @@ public class SearchHit<T> {
/**
* @return the matched queries for this SearchHit.
*/
@Nullable
public Map<String, Double> getMatchedQueries() {
return matchedQueries;
}
@@ -22,11 +22,11 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jspecify.annotations.Nullable;
import org.springframework.data.core.ReactiveWrappers;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.util.CloseableIterator;
import org.springframework.lang.Contract;
/**
* Utility class with helper methods for working with {@link SearchHit}.
@@ -47,6 +47,7 @@ public final class SearchHitSupport {
* @return a corresponding object where the SearchHits are replaced by their content if possible, otherwise the
* original object
*/
@Contract("null -> null; !null -> !null")
@Nullable
public static Object unwrapSearchHits(@Nullable Object result) {
@@ -133,7 +133,7 @@ public class SearchHitsImpl<T> implements SearchScrollHits<T> {
}
@Override
public SearchShardStatistics getSearchShardStatistics() {
public @Nullable SearchShardStatistics getSearchShardStatistics() {
return searchShardStatistics;
}
@@ -1,5 +1,18 @@
/**
* Interfaces and classes related to Elasticsearch cluster information and management.
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.cluster;
@@ -29,7 +29,7 @@ import org.springframework.data.mapping.context.MappingContext;
* @author Christoph Strobl
* @since 3.2
*/
public interface ElasticsearchTypeMapper extends TypeMapper<Map<String, Object>> {
public interface ElasticsearchTypeMapper extends TypeMapper<Map<String, @Nullable Object>> {
String DEFAULT_TYPE_KEY = "_class";
@@ -47,7 +47,7 @@ public interface ElasticsearchTypeMapper extends TypeMapper<Map<String, Object>>
@Nullable
String getTypeKey();
default boolean containsTypeInformation(Map<String, Object> source) {
default boolean containsTypeInformation(Map<String, @Nullable Object> source) {
return readType(source) != null;
}
@@ -20,9 +20,9 @@ import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.jspecify.annotations.Nullable;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
@@ -167,7 +167,7 @@ public class GeoConverters {
INSTANCE;
@Override
public GeoJson<? extends Iterable<?>> convert(Map<String, Object> source) {
public GeoJson<? extends Iterable<?>> convert(Map<String, @Nullable Object> source) {
String type = GeoConverters.getGeoJsonType(source);
@@ -206,7 +206,7 @@ public class GeoConverters {
INSTANCE;
@Override
public GeoJsonPoint convert(Map<String, Object> source) {
public GeoJsonPoint convert(Map<String, @Nullable Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equalsIgnoreCase(GeoJsonPoint.TYPE), "does not contain a type 'Point'");
@@ -244,7 +244,7 @@ public class GeoConverters {
INSTANCE;
@Override
public GeoJsonMultiPoint convert(Map<String, Object> source) {
public GeoJsonMultiPoint convert(Map<String, @Nullable Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equalsIgnoreCase(GeoJsonMultiPoint.TYPE), "does not contain a type 'MultiPoint'");
@@ -279,7 +279,7 @@ public class GeoConverters {
INSTANCE;
@Override
public GeoJsonLineString convert(Map<String, Object> source) {
public GeoJsonLineString convert(Map<String, @Nullable Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equalsIgnoreCase(GeoJsonLineString.TYPE), "does not contain a type 'LineString'");
@@ -311,7 +311,7 @@ public class GeoConverters {
INSTANCE;
@Override
public GeoJsonMultiLineString convert(Map<String, Object> source) {
public GeoJsonMultiLineString convert(Map<String, @Nullable Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equalsIgnoreCase(GeoJsonMultiLineString.TYPE), "does not contain a type 'MultiLineString'");
@@ -339,7 +339,7 @@ public class GeoConverters {
INSTANCE;
@Override
public GeoJsonPolygon convert(Map<String, Object> source) {
public GeoJsonPolygon convert(Map<String, @Nullable Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equalsIgnoreCase(GeoJsonPolygon.TYPE), "does not contain a type 'Polygon'");
@@ -368,7 +368,6 @@ public class GeoConverters {
List<Object> coordinates = source.getCoordinates().stream() //
.map(GeoJsonPolygonToMapConverter.INSTANCE::convert) //
.filter(Objects::nonNull) //
.map(it -> it.get("coordinates")) //
.collect(Collectors.toList()); //
map.put("coordinates", coordinates);
@@ -383,7 +382,7 @@ public class GeoConverters {
INSTANCE;
@Override
public GeoJsonMultiPolygon convert(Map<String, Object> source) {
public GeoJsonMultiPolygon convert(Map<String, @Nullable Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equalsIgnoreCase(GeoJsonMultiPolygon.TYPE), "does not contain a type 'MultiPolygon'");
@@ -430,7 +429,7 @@ public class GeoConverters {
INSTANCE;
@Override
public GeoJsonGeometryCollection convert(Map<String, Object> source) {
public GeoJsonGeometryCollection convert(Map<String, @Nullable Object> source) {
String type = GeoConverters.getGeoJsonType(source);
Assert.isTrue(type.equalsIgnoreCase(GeoJsonGeometryCollection.TYPE),
@@ -448,7 +447,7 @@ public class GeoConverters {
// endregion
// region helper functions
private static String getGeoJsonType(Map<String, Object> source) {
private static String getGeoJsonType(Map<String, @Nullable Object> source) {
Object type = source.get("type");
Assert.notNull(type, "Document to convert does not contain a type");
@@ -485,7 +484,7 @@ public class GeoConverters {
return map;
}
private static List<GeoJsonLineString> geoJsonLineStringsFromMap(Map<String, Object> source) {
private static List<GeoJsonLineString> geoJsonLineStringsFromMap(Map<String, @Nullable Object> source) {
Object coordinates = source.get("coordinates");
Assert.notNull(coordinates, "Document to convert does not contain coordinates");
Assert.isTrue(coordinates instanceof List, "coordinates must be a List");
@@ -24,7 +24,6 @@ import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
@@ -63,16 +62,7 @@ import org.springframework.data.mapping.Parameter;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.SimplePropertyHandler;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.CachingValueExpressionEvaluatorFactory;
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
import org.springframework.data.mapping.model.EntityInstantiator;
import org.springframework.data.mapping.model.EntityInstantiators;
import org.springframework.data.mapping.model.ParameterValueProvider;
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.ValueExpressionEvaluator;
import org.springframework.data.mapping.model.ValueExpressionParameterValueProvider;
import org.springframework.data.mapping.model.*;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.format.datetime.DateFormatterRegistrar;
import org.springframework.util.Assert;
@@ -267,7 +257,7 @@ public class MappingElasticsearchConverter
@Nullable
@SuppressWarnings("unchecked")
private <R> R read(TypeInformation<R> typeInformation, Map<String, Object> source) {
private <R> R read(TypeInformation<R> typeInformation, Map<String, @Nullable Object> source) {
Assert.notNull(source, "Source must not be null!");
@@ -301,7 +291,7 @@ public class MappingElasticsearchConverter
}
@SuppressWarnings("unchecked")
private <R> R readMap(TypeInformation<?> type, Map<String, Object> source) {
private <R> R readMap(TypeInformation<?> type, Map<String, @Nullable Object> source) {
Assert.notNull(source, "Document must not be null!");
@@ -313,9 +303,10 @@ public class MappingElasticsearchConverter
Class<?> rawKeyType = keyType != null ? keyType.getType() : null;
Class<?> rawValueType = valueType != null ? valueType.getType() : null;
Map<Object, Object> map = CollectionFactory.createMap(mapType, rawKeyType, source.keySet().size());
Map<Object, @Nullable Object> map = (Map<Object, @Nullable Object>) CollectionFactory.createMap(mapType,
rawKeyType, source.keySet().size());
for (Entry<String, Object> entry : source.entrySet()) {
for (Entry<String, @Nullable Object> entry : source.entrySet()) {
if (typeMapper.isTypeKey(entry.getKey())) {
continue;
@@ -325,6 +316,7 @@ public class MappingElasticsearchConverter
if (rawKeyType != null && !rawKeyType.isAssignableFrom(key.getClass())) {
key = conversionService.convert(key, rawKeyType);
Assert.notNull(key, "converted key must not be null");
}
Object value = entry.getValue();
@@ -343,7 +335,7 @@ public class MappingElasticsearchConverter
return (R) map;
}
private <R> R readEntity(ElasticsearchPersistentEntity<?> entity, Map<String, Object> source) {
private <R> R readEntity(ElasticsearchPersistentEntity<?> entity, Map<String, @Nullable Object> source) {
ElasticsearchPersistentEntity<?> targetEntity = computeClosestEntity(entity, source);
ValueExpressionEvaluator evaluator = expressionEvaluatorFactory.create(source);
@@ -582,7 +574,7 @@ public class MappingElasticsearchConverter
: TypeInformation.OBJECT;
Class<?> rawComponentType = componentType.getType();
Collection<Object> items = targetType.getType().isArray() //
Collection<@Nullable Object> items = targetType.getType().isArray() //
? new ArrayList<>(source.size()) //
: CollectionFactory.createCollection(collectionType, rawComponentType, source.size());
@@ -672,7 +664,7 @@ public class MappingElasticsearchConverter
*/
private <T> void populateScriptedFields(ElasticsearchPersistentEntity<?> entity, T result,
SearchDocument searchDocument) {
Map<String, List<Object>> fields = searchDocument.getFields();
Map<String, List<@Nullable Object>> fields = searchDocument.getFields();
entity.doWithProperties((SimplePropertyHandler) property -> {
if (property.isAnnotationPresent(ScriptedField.class)) {
ScriptedField scriptedField = property.findAnnotation(ScriptedField.class);
@@ -695,7 +687,7 @@ public class MappingElasticsearchConverter
* Compute the type to use by checking the given entity against the store type;
*/
private ElasticsearchPersistentEntity<?> computeClosestEntity(ElasticsearchPersistentEntity<?> entity,
Map<String, Object> source) {
Map<String, @Nullable Object> source) {
TypeInformation<?> typeToUse = typeMapper.readType(source);
@@ -770,7 +762,7 @@ public class MappingElasticsearchConverter
INSTANCE;
@Override
public <T> T getParameterValue(Parameter<T, ElasticsearchPersistentProperty> parameter) {
public <T> @Nullable T getParameterValue(Parameter<T, ElasticsearchPersistentProperty> parameter) {
return null;
}
}
@@ -822,7 +814,7 @@ public class MappingElasticsearchConverter
* @param typeInformation type information for the source
*/
@SuppressWarnings("unchecked")
private void writeInternal(@Nullable Object source, Map<String, Object> sink,
private void writeInternal(@Nullable Object source, Map<String, @Nullable Object> sink,
@Nullable TypeInformation<?> typeInformation) {
if (null == source) {
@@ -833,7 +825,7 @@ public class MappingElasticsearchConverter
Optional<Class<?>> customTarget = conversions.getCustomWriteTarget(entityType, Map.class);
if (customTarget.isPresent()) {
Map<String, Object> result = conversionService.convert(source, Map.class);
Map<String, @Nullable Object> result = conversionService.convert(source, Map.class);
if (result != null) {
sink.putAll(result);
@@ -863,7 +855,7 @@ public class MappingElasticsearchConverter
* @param sink the destination
* @param entity entity for the source
*/
private void writeInternal(@Nullable Object source, Map<String, Object> sink,
private void writeInternal(@Nullable Object source, Map<String, @Nullable Object> sink,
@Nullable ElasticsearchPersistentEntity<?> entity) {
if (source == null) {
@@ -905,7 +897,7 @@ public class MappingElasticsearchConverter
* @param sink must not be {@literal null}.
* @param propertyType must not be {@literal null}.
*/
private Map<String, Object> writeMapInternal(Map<?, ?> source, Map<String, Object> sink,
private Map<String, @Nullable Object> writeMapInternal(Map<?, ?> source, Map<String, @Nullable Object> sink,
TypeInformation<?> propertyType) {
for (Map.Entry<?, ?> entry : source.entrySet()) {
@@ -922,7 +914,7 @@ public class MappingElasticsearchConverter
sink.put(simpleKey,
writeCollectionInternal(asCollection(value), propertyType.getMapValueType(), new ArrayList<>()));
} else {
Map<String, Object> document = Document.create();
Map<String, @Nullable Object> document = Document.create();
TypeInformation<?> valueTypeInfo = propertyType.isMap() ? propertyType.getMapValueType()
: TypeInformation.OBJECT;
writeInternal(value, document, valueTypeInfo);
@@ -966,7 +958,7 @@ public class MappingElasticsearchConverter
} else if (element instanceof Collection || elementType.isArray()) {
collection.add(writeCollectionInternal(asCollection(element), componentType, new ArrayList<>()));
} else {
Map<String, Object> document = Document.create();
Map<String, @Nullable Object> document = Document.create();
writeInternal(element, document, componentType);
collection.add(document);
}
@@ -1080,7 +1072,7 @@ public class MappingElasticsearchConverter
: mappingContext.getRequiredPersistentEntity(type);
Object existingValue = sink.get(property);
Map<String, Object> document = existingValue instanceof Map ? (Map<String, Object>) existingValue
Map<String, @Nullable Object> document = existingValue instanceof Map ? (Map<String, Object>) existingValue
: Document.create();
addCustomTypeKeyIfNecessary(value, document, TypeInformation.of(property.getRawType()));
@@ -1097,7 +1089,7 @@ public class MappingElasticsearchConverter
* @param sink must not be {@literal null}.
* @param type type to compare to
*/
private void addCustomTypeKeyIfNecessary(Object source, Map<String, Object> sink,
private void addCustomTypeKeyIfNecessary(Object source, Map<String, @Nullable Object> sink,
@Nullable TypeInformation<?> type) {
if (!writeTypeHints) {
@@ -1218,7 +1210,7 @@ public class MappingElasticsearchConverter
Assert.notNull(map, "Given map must not be null!");
Assert.notNull(property, "PersistentProperty must not be null!");
return writeMapInternal(map, new LinkedHashMap<>(map.size()), property.getTypeInformation());
return writeMapInternal(map, new LinkedHashMap(map.size()), property.getTypeInformation());
}
/**
@@ -1492,9 +1484,9 @@ public class MappingElasticsearchConverter
@SuppressWarnings("ClassCanBeRecord")
static class MapValueAccessor {
final Map<String, Object> target;
final Map<String, @Nullable Object> target;
MapValueAccessor(Map<String, Object> target) {
MapValueAccessor(Map<String, @Nullable Object> target) {
this.target = target;
}
@@ -1528,7 +1520,7 @@ public class MappingElasticsearchConverter
}
Iterator<String> parts = Arrays.asList(fieldName.split("\\.")).iterator();
Map<String, Object> source = target;
Map<String, @Nullable Object> source = target;
Object result = null;
while (parts.hasNext()) {
@@ -1559,11 +1551,11 @@ public class MappingElasticsearchConverter
target.put(property.getFieldName(), value);
}
private Map<String, Object> getAsMap(Object result) {
private Map<String, @Nullable Object> getAsMap(Object result) {
if (result instanceof Map) {
// noinspection unchecked
return (Map<String, Object>) result;
return (Map<String, @Nullable Object>) result;
}
throw new IllegalArgumentException(String.format("%s is not a Map.", result));
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.convert;
@@ -62,7 +62,7 @@ public class Explanation {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -81,7 +81,7 @@ public class Explanation {
@Override
public int hashCode() {
int result = (match ? 1 : 0);
int result = (Boolean.TRUE.equals(match) ? 1 : 0);
result = 31 * result + value.hashCode();
result = 31 * result + (description != null ? description.hashCode() : 0);
result = 31 * result + details.hashCode();
@@ -215,7 +215,7 @@ class MapDocument implements Document {
* @see java.util.Map#containsKey(java.lang.Object)
*/
@Override
public boolean containsKey(Object key) {
public boolean containsKey(@Nullable Object key) {
return documentAsMap.containsKey(key);
}
@@ -224,7 +224,7 @@ class MapDocument implements Document {
* @see java.util.Map#containsValue(java.lang.Object)
*/
@Override
public boolean containsValue(Object value) {
public boolean containsValue(@Nullable Object value) {
return documentAsMap.containsValue(value);
}
@@ -233,7 +233,7 @@ class MapDocument implements Document {
* @see java.util.Map#get(java.lang.Object)
*/
@Override
public Object get(Object key) {
public Object get(@Nullable Object key) {
return documentAsMap.get(key);
}
@@ -242,7 +242,7 @@ class MapDocument implements Document {
* @see java.lang.Object#getOrDefault(java.lang.Object, java.lang.Object)
*/
@Override
public Object getOrDefault(Object key, Object defaultValue) {
public Object getOrDefault(@Nullable Object key, @Nullable Object defaultValue) {
return documentAsMap.getOrDefault(key, defaultValue);
}
@@ -251,7 +251,7 @@ class MapDocument implements Document {
* @see java.util.Map#put(java.lang.Object, java.lang.Object)
*/
@Override
public Object put(String key, Object value) {
public Object put(String key, @Nullable Object value) {
return documentAsMap.put(key, value);
}
@@ -260,7 +260,7 @@ class MapDocument implements Document {
* @see java.util.Map#remove(java.lang.Object)
*/
@Override
public Object remove(Object key) {
public Object remove(@Nullable Object key) {
return documentAsMap.remove(key);
}
@@ -314,7 +314,7 @@ class MapDocument implements Document {
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
return documentAsMap.equals(o);
}
@@ -332,7 +332,8 @@ class MapDocument implements Document {
* @see java.util.Map#forEach(java.util.function.BiConsumer)
*/
@Override
public void forEach(BiConsumer<? super String, ? super Object> action) {
public void forEach(
@SuppressWarnings("NullableProblems") BiConsumer<? super String, ? super @Nullable Object> action) {
documentAsMap.forEach(action);
}
@@ -41,7 +41,7 @@ public interface SearchDocument extends Document {
/**
* @return the fields for the search result, not {@literal null}
*/
Map<String, List<Object>> getFields();
Map<String, List<@Nullable Object>> getFields();
/**
* The first value of the given field.
@@ -50,7 +50,7 @@ public interface SearchDocument extends Document {
*/
@Nullable
default <V> V getFieldValue(final String name) {
List<Object> values = getFields().get(name);
List<@Nullable Object> values = getFields().get(name);
if (values == null || values.isEmpty()) {
return null;
}
@@ -64,7 +64,7 @@ public interface SearchDocument extends Document {
*/
@Nullable
default <V> List<V> getFieldValues(final String name) {
List<Object> values = getFields().get(name);
List<@Nullable Object> values = getFields().get(name);
if (values == null) {
return null;
}
@@ -74,8 +74,7 @@ public interface SearchDocument extends Document {
/**
* @return the sort values for the search hit
*/
@Nullable
default Object[] getSortValues() {
default Object @Nullable [] getSortValues() {
return null;
}
@@ -35,7 +35,7 @@ public class SearchDocumentAdapter implements SearchDocument {
private final float score;
private final Object[] sortValues;
private final Map<String, List<Object>> fields = new HashMap<>();
private final Map<String, List<@Nullable Object>> fields = new HashMap<>();
private final Document delegate;
private final Map<String, List<String>> highlightFields = new HashMap<>();
private final Map<String, SearchDocumentResponse> innerHits = new HashMap<>();
@@ -44,9 +44,11 @@ public class SearchDocumentAdapter implements SearchDocument {
@Nullable private final Map<String, Double> matchedQueries;
@Nullable private final String routing;
public SearchDocumentAdapter(Document delegate, float score, Object[] sortValues, Map<String, List<Object>> fields,
public SearchDocumentAdapter(Document delegate, float score, Object[] sortValues,
Map<String, List<@Nullable Object>> fields,
Map<String, List<String>> highlightFields, Map<String, SearchDocumentResponse> innerHits,
@Nullable NestedMetaData nestedMetaData, @Nullable Explanation explanation, @Nullable Map<String, Double> matchedQueries,
@Nullable NestedMetaData nestedMetaData, @Nullable Explanation explanation,
@Nullable Map<String, Double> matchedQueries,
@Nullable String routing) {
this.delegate = delegate;
@@ -74,7 +76,7 @@ public class SearchDocumentAdapter implements SearchDocument {
}
@Override
public Map<String, List<Object>> getFields() {
public Map<String, List<@Nullable Object>> getFields() {
return fields;
}
@@ -186,17 +188,17 @@ public class SearchDocumentAdapter implements SearchDocument {
}
@Override
public boolean containsKey(Object key) {
public boolean containsKey(@Nullable Object key) {
return delegate.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
public boolean containsValue(@Nullable Object value) {
return delegate.containsValue(value);
}
@Override
public Object get(Object key) {
public Object get(@Nullable Object key) {
if (delegate.containsKey(key)) {
return delegate.get(key);
@@ -207,12 +209,12 @@ public class SearchDocumentAdapter implements SearchDocument {
}
@Override
public Object put(String key, Object value) {
public @Nullable Object put(String key, @Nullable Object value) {
return delegate.put(key, value);
}
@Override
public Object remove(Object key) {
public Object remove(@Nullable Object key) {
return delegate.remove(key);
}
@@ -232,12 +234,12 @@ public class SearchDocumentAdapter implements SearchDocument {
}
@Override
public Collection<Object> values() {
public Collection<@Nullable Object> values() {
return delegate.values();
}
@Override
public Set<Entry<String, Object>> entrySet() {
public Set<Entry<String, @Nullable Object>> entrySet() {
return delegate.entrySet();
}
@@ -254,7 +256,7 @@ public class SearchDocumentAdapter implements SearchDocument {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
@@ -270,17 +272,17 @@ public class SearchDocumentAdapter implements SearchDocument {
}
@Override
public void forEach(BiConsumer<? super String, ? super Object> action) {
public void forEach(@Nullable BiConsumer<? super String, ? super @Nullable Object> action) {
delegate.forEach(action);
}
@Override
public boolean remove(Object key, Object value) {
public boolean remove(@Nullable Object key, @Nullable Object value) {
return delegate.remove(key, value);
}
@Override
public String getRouting() {
public @Nullable String getRouting() {
return routing;
}
@@ -1,5 +1,18 @@
/**
* Classes related to the Document structure of Elasticsearch documents and search responses.
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.document;
@@ -31,10 +31,11 @@ import org.springframework.data.mapping.callback.EntityCallback;
public interface AfterLoadCallback<T> extends EntityCallback<Document> {
/**
* Entity callback method invoked after a domain object is materialized from a {@link Document}. Can return either the
* same or a modified instance of the {@link Document} object.
* Entity callback method invoked after a {@link Document} is read from Elasticsearch. Can return either the same or a
* modified instance of the {@link Document} object.
*
* @param document the document.
* @param type the type into which the document will be converted
* @param indexCoordinates of the index the document was read from.
* @return a possible modified or new {@link Document}.
*/
@@ -1,5 +1,18 @@
/**
* classes and interfaces related to Spring Data Elasticsearch events and callbacks.
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.event;
@@ -8,18 +8,27 @@ import tools.jackson.databind.SerializationContext;
import tools.jackson.databind.ValueDeserializer;
import tools.jackson.databind.ValueSerializer;
import org.jspecify.annotations.Nullable;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
class PointSerializer extends ValueSerializer<Point> {
@Override
public void serialize(Point value, JsonGenerator gen, SerializationContext serializers) throws JacksonException {
public void serialize(Point value, @Nullable JsonGenerator gen, @Nullable SerializationContext serializers)
throws JacksonException {
Assert.notNull(gen, "gen must not be null");
gen.writePOJO(GeoPoint.fromPoint(value));
}
}
class PointDeserializer extends ValueDeserializer<Point> {
@Override
public Point deserialize(JsonParser p, DeserializationContext context) throws JacksonException {
public Point deserialize(@Nullable JsonParser p, @Nullable DeserializationContext context) throws JacksonException {
Assert.notNull(p, "p must not be null");
return GeoPoint.toPoint(p.readValueAs(GeoPoint.class));
}
}
@@ -19,6 +19,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@@ -68,7 +69,7 @@ public class GeoJsonGeometryCollection implements GeoJson<Iterable<GeoJson<?>>>
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.jspecify.annotations.Nullable;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
@@ -122,7 +123,7 @@ public class GeoJsonLineString implements GeoJson<Iterable<Point>> {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.jspecify.annotations.Nullable;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
@@ -81,7 +82,7 @@ public class GeoJsonMultiLineString implements GeoJson<Iterable<GeoJsonLineStrin
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.jspecify.annotations.Nullable;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
@@ -122,7 +123,7 @@ public class GeoJsonMultiPoint implements GeoJson<Iterable<Point>> {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -19,6 +19,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@@ -62,7 +63,7 @@ public class GeoJsonMultiPolygon implements GeoJson<Iterable<GeoJsonPolygon>> {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.core.geo;
import java.util.Arrays;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.springframework.data.geo.Point;
/**
@@ -89,7 +90,7 @@ public class GeoJsonPoint implements GeoJson<List<Double>> {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
@@ -207,7 +208,7 @@ public class GeoJsonPolygon implements GeoJson<Iterable<GeoJsonLineString>> {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.core.geo;
import java.util.Objects;
import org.jspecify.annotations.Nullable;
import org.springframework.data.geo.Point;
/**
@@ -63,7 +64,7 @@ public class GeoPoint {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.geo;
@@ -27,7 +27,7 @@ import org.springframework.util.Assert;
*/
public class AliasActionParameters {
private final String[] indices;
@Nullable private final String[] aliases;
private final String @Nullable [] aliases;
@Nullable private final Query filterQuery;
@Nullable private final Class<?> filterQueryClass;
@Nullable private final Boolean isHidden;
@@ -36,7 +36,7 @@ public class AliasActionParameters {
@Nullable private final String indexRouting;
@Nullable private final String searchRouting;
private AliasActionParameters(String[] indices, @Nullable String[] aliases, @Nullable Boolean isHidden,
private AliasActionParameters(String[] indices, String @Nullable [] aliases, @Nullable Boolean isHidden,
@Nullable Boolean isWriteIndex, @Nullable String routing, @Nullable String indexRouting,
@Nullable String searchRouting, @Nullable Query filterQuery, @Nullable Class<?> filterQueryClass) {
this.indices = indices;
@@ -66,7 +66,7 @@ public class AliasActionParameters {
return indices;
}
public String@Nullable[] getAliases() {
public String @Nullable [] getAliases() {
return aliases;
}
@@ -38,7 +38,7 @@ public class AliasActions {
*
* @param actions {@link AliasAction} elements
*/
public AliasActions(@Nullable AliasAction... actions) {
public AliasActions(AliasAction @Nullable... actions) {
add(actions);
}
@@ -52,10 +52,9 @@ public class AliasActions {
* @param actions elements to add
* @return this object
*/
public AliasActions add(@Nullable AliasAction... actions) {
public AliasActions add(AliasAction @Nullable... actions) {
if (actions != null) {
// noinspection NullableProblems
this.actions.addAll(Arrays.asList(actions));
}
@@ -40,7 +40,7 @@ public record ComponentTemplateRequestData(@Nullable Settings settings, @Nullabl
@Nullable private AliasActions aliasActions;
@Nullable private Boolean allowAutoCreate;
public Builder withSettings(Map<String, Object> settings) {
public Builder withSettings(Map<String, @Nullable Object> settings) {
this.settings = new Settings(settings);
return this;
}
@@ -36,7 +36,6 @@ import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.annotation.Transient;
@@ -280,7 +279,7 @@ public class MappingBuilder {
writeTypeHintMapping(propertiesNode);
if (entity != null) {
entity.doWithProperties((PropertyHandler<@NonNull ElasticsearchPersistentProperty>) property -> {
entity.doWithProperties((PropertyHandler<ElasticsearchPersistentProperty>) property -> {
try {
if (property.isAnnotationPresent(Transient.class) || isInIgnoreFields(property, parentFieldAnnotation)) {
return;
@@ -89,7 +89,7 @@ public class MappingParameters {
private final String analyzer;
private final boolean coerce;
@Nullable private final String[] copyTo;
private final String @Nullable [] copyTo;
private final DateFormat[] dateFormats;
private final String[] dateFormatPatterns;
private final boolean docValues;
@@ -429,7 +429,7 @@ public class MappingParameters {
return coerce;
}
protected String[] copyTo() {
protected String @Nullable [] copyTo() {
return copyTo;
}
@@ -17,8 +17,6 @@ package org.springframework.data.elasticsearch.core.index;
import java.lang.annotation.Annotation;
import org.jspecify.annotations.NonNull;
/**
* Allows to customize {@link org.springframework.data.elasticsearch.core.index.MappingParameters} that are being
* emitted for each supported annotation. Needed by dependent projects like Spring-Data-Opensearch.
@@ -33,6 +31,6 @@ public interface MappingParametersCustomizer {
* @param annotation supported annotation
* @return customized @link org.springframework.data.elasticsearch.core.index.MappingParameters}
*/
@NonNull
MappingParameters from(@NonNull Annotation annotation);
MappingParameters from(Annotation annotation);
}
@@ -102,7 +102,7 @@ public class PutTemplateRequest {
this.indexPatterns = indexPatterns;
}
public TemplateRequestBuilder withSettings(Map<String, Object> settings) {
public TemplateRequestBuilder withSettings(Map<String, @Nullable Object> settings) {
this.settings = new Settings(settings);
return this;
}
@@ -21,6 +21,7 @@ import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.support.DefaultStringObjectMap;
import org.springframework.util.Assert;
@@ -34,7 +35,7 @@ public class Settings extends DefaultStringObjectMap<Settings> {
public Settings() {}
public Settings(Map<String, Object> map) {
public Settings(Map<String, @Nullable Object> map) {
super(map);
}
@@ -54,7 +55,7 @@ public class Settings extends DefaultStringObjectMap<Settings> {
}
@Override
public Object get(Object key) {
public Object get(@Nullable Object key) {
return containsKey(key) ? super.get(key) : path(key.toString());
}
@@ -75,11 +76,11 @@ public class Settings extends DefaultStringObjectMap<Settings> {
* taken from https://stackoverflow.com/a/29698326/4393565
*/
@SuppressWarnings("unchecked")
private static Map<?, ?> deepMerge(Map<String, Object> original, Map<String, Object> newMap) {
private static Map<?, ?> deepMerge(Map<String, @Nullable Object> original, Map<String, @Nullable Object> newMap) {
for (Object key : newMap.keySet()) {
if (newMap.get(key) instanceof Map && original.get(key) instanceof Map) {
Map<String, Object> originalChild = (Map<String, Object>) original.get(key);
Map<String, Object> newChild = (Map<String, Object>) newMap.get(key);
Map<String, @Nullable Object> originalChild = (Map<String, Object>) original.get(key);
Map<String, @Nullable Object> newChild = (Map<String, Object>) newMap.get(key);
original.put(key.toString(), deepMerge(originalChild, newChild));
} else if (newMap.get(key) instanceof List && original.get(key) instanceof List) {
List<Object> originalChild = (List<Object>) original.get(key);
@@ -112,9 +113,9 @@ public class Settings extends DefaultStringObjectMap<Settings> {
* flattens a Map<String, Object> to a stream of Map.Entry objects where the keys are the dot separated concatenated
* keys of sub map entries
*/
static private Stream<Map.Entry<String, Object>> doFlatten(Map.Entry<String, Object> entry) {
static private Stream<Map.Entry<String, @Nullable Object>> doFlatten(Map.Entry<String, @Nullable Object> entry) {
if (entry.getValue()instanceof Map<?, ?> nested) {
if (entry.getValue() instanceof Map<?, ?> nested) {
// noinspection unchecked
return nested.entrySet().stream() //
@@ -91,7 +91,7 @@ public class TemplateData {
return this;
}
public TemplateDataBuilder withSettings(Map<String, Object> settings) {
public TemplateDataBuilder withSettings(Map<String, @Nullable Object> settings) {
this.settings = new Settings(settings);
return this;
}
@@ -1,5 +1,18 @@
/**
* Classes related to Elasticsearch index management.
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.index;
@@ -64,7 +64,7 @@ public class JoinField<ID> {
}
@Override
public boolean equals(Object obj) {
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -0,0 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.join;
@@ -115,7 +115,7 @@ public class Alias {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (!(o instanceof Alias that))
@@ -33,7 +33,7 @@ public class CreateIndexSettings {
private final IndexCoordinates indexCoordinates;
private final Set<Alias> aliases;
@Nullable private final Map<String, Object> settings;
@Nullable private final Map<String, @Nullable Object> settings;
@Nullable private final Document mapping;
@@ -58,7 +58,7 @@ public class CreateIndexSettings {
}
@Nullable
public Map<String, Object> getSettings() {
public Map<String, @Nullable Object> getSettings() {
return settings;
}
@@ -71,7 +71,7 @@ public class CreateIndexSettings {
private final IndexCoordinates indexCoordinates;
private final Set<Alias> aliases = new HashSet<>();
@Nullable private Map<String, Object> settings;
@Nullable private Map<String, @Nullable Object> settings;
@Nullable private Document mapping;
@@ -94,7 +94,7 @@ public class CreateIndexSettings {
return this;
}
public Builder withSettings(Map<String, Object> settings) {
public Builder withSettings(Map<String, @Nullable Object> settings) {
Assert.notNull(settings, "settings must not be null");
this.settings = settings;
@@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.core.mapping;
import java.util.Arrays;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@@ -55,7 +56,7 @@ public class IndexCoordinates {
* @since 4.2
*/
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -23,9 +23,7 @@ import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.core.TypeInformation;
@@ -263,6 +261,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
throw new MappingException("@IndexedIndexName annotation must be put on String property");
}
// noinspection VariableNotUsedInsideIf
if (indexedIndexNameProperty != null) {
throw new MappingException(
"@IndexedIndexName annotation can only be put on one property in an entity");
@@ -301,7 +300,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
return fieldNamePropertyCache.computeIfAbsent(fieldName, key -> {
AtomicReference<@Nullable ElasticsearchPersistentProperty> propertyRef = new AtomicReference<>();
doWithProperties((PropertyHandler<@NonNull ElasticsearchPersistentProperty>) property -> {
doWithProperties((PropertyHandler<ElasticsearchPersistentProperty>) property -> {
if (key.equals(property.getFieldName())) {
propertyRef.set(property);
}
@@ -425,8 +424,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
try {
Expression expression = routingExpressions.computeIfAbsent(routing, PARSER::parseExpression);
ExpressionDependencies expressionDependencies = expression != null ? ExpressionDependencies.discover(expression)
: ExpressionDependencies.none();
ExpressionDependencies expressionDependencies = ExpressionDependencies.discover(expression);
EvaluationContext context = getEvaluationContext(null, expressionDependencies);
context.setVariable("entity", bean);
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.mapping;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core;
@@ -602,6 +602,7 @@ public class BaseQuery implements Query {
// searchForStream to work correctly (#3098) as there the page size defines what is
// returned in a single request, and the max result determines the total number of
// documents returned.
// noinspection DataFlowIssue maxResults is not null here, this is checked with isLimiting()
requestSize = Math.min(pageable.getPageSize(), getMaxResults());
}
} else if (pageable == UNSET_PAGE) {
@@ -622,6 +623,7 @@ public class BaseQuery implements Query {
// searchForStream to work correctly (#3098) as there the page size defines what is
// returned in a single request, and the max result determines the total number of
// documents returned.
// noinspection DataFlowIssue maxResults is not null here, this is checked with isLimiting()
requestSize = Math.min(INDEX_MAX_RESULT_WINDOW, getMaxResults());
}
}
@@ -97,7 +97,6 @@ public abstract class BaseQueryBuilder<Q extends BaseQuery, SELF extends BaseQue
return maxResults;
}
@Nullable
public Collection<String> getIds() {
return ids;
}
@@ -182,7 +181,7 @@ public abstract class BaseQueryBuilder<Q extends BaseQuery, SELF extends BaseQue
* @since 6.1
*/
@Nullable
public Boolean getIncludeNamedQueriesScore(){
public Boolean getIncludeNamedQueriesScore() {
return includeNamedQueryScore;
}
@@ -393,7 +392,7 @@ public abstract class BaseQueryBuilder<Q extends BaseQuery, SELF extends BaseQue
/**
* @since 6.1
*/
public SELF withIncludeNamedQueryScore (@Nullable Boolean namedQueryScore) {
public SELF withIncludeNamedQueryScore(@Nullable Boolean namedQueryScore) {
this.includeNamedQueryScore = namedQueryScore;
return self();
}
@@ -61,16 +61,16 @@ public class Criteria {
private float boost = Float.NaN;
private boolean negating = false;
// we cash this and recalculate when properties used in equals change
// see https://github.com/spring-projects/spring-data-elasticsearch/issues/3083
private int hashCode;
// we cache this and recalculate when properties used in equals change
// see https://github.com/spring-projects/spring-data-elasticsearch/issues/3083
private int hashCode;
private final CriteriaChain criteriaChain = new CriteriaChain();
private final Set<CriteriaEntry> queryCriteriaEntries = new LinkedHashSet<>();
private final Set<CriteriaEntry> filterCriteriaEntries = new LinkedHashSet<>();
private final Set<Criteria> subCriteria = new LinkedHashSet<>();
private final CriteriaChain criteriaChain = new CriteriaChain();
private final Set<CriteriaEntry> queryCriteriaEntries = new LinkedHashSet<>();
private final Set<CriteriaEntry> filterCriteriaEntries = new LinkedHashSet<>();
private final Set<Criteria> subCriteria = new LinkedHashSet<>();
// region criteria creation
// region criteria creation
/**
* @return factory method to create an and-Criteria that is not bound to a field
@@ -89,8 +89,8 @@ public class Criteria {
}
public Criteria() {
recalculateHashCode();
}
recalculateHashCode();
}
/**
* Creates a new Criteria with provided field name
@@ -113,7 +113,7 @@ public class Criteria {
this.field = field;
this.criteriaChain.add(this);
recalculateHashCode();
recalculateHashCode();
}
/**
@@ -143,7 +143,7 @@ public class Criteria {
this.field = field;
this.criteriaChain.addAll(criteriaChain);
this.criteriaChain.add(this);
recalculateHashCode();
recalculateHashCode();
}
/**
@@ -197,7 +197,7 @@ public class Criteria {
*/
public Criteria not() {
this.negating = true;
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -216,7 +216,7 @@ public class Criteria {
Assert.isTrue(boost >= 0, "boost must not be negative");
this.boost = boost;
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -274,7 +274,7 @@ public class Criteria {
Assert.notNull(criteria, "Cannot chain 'null' criteria.");
this.criteriaChain.add(criteria);
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -289,7 +289,7 @@ public class Criteria {
Assert.notNull(criterias, "Cannot chain 'null' criterias.");
this.criteriaChain.addAll(Arrays.asList(criterias));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -332,7 +332,7 @@ public class Criteria {
orCriteria.subCriteria.addAll(criteria.subCriteria);
orCriteria.boost = criteria.boost;
orCriteria.negating = criteria.isNegating();
orCriteria.recalculateHashCode();
orCriteria.recalculateHashCode();
return orCriteria;
}
@@ -348,7 +348,7 @@ public class Criteria {
Assert.notNull(criteria, "criteria must not be null");
subCriteria.add(criteria);
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -363,7 +363,7 @@ public class Criteria {
*/
public Criteria is(Object o) {
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EQUALS, o));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -375,7 +375,7 @@ public class Criteria {
*/
public Criteria exists() {
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EXISTS));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -394,7 +394,7 @@ public class Criteria {
}
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.BETWEEN, new Object[] { lowerBound, upperBound }));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -410,7 +410,7 @@ public class Criteria {
assertNoBlankInWildcardQuery(s, false, true);
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.STARTS_WITH, s));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -427,7 +427,7 @@ public class Criteria {
assertNoBlankInWildcardQuery(s, true, true);
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.CONTAINS, s));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -444,7 +444,7 @@ public class Criteria {
assertNoBlankInWildcardQuery(s, true, false);
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.ENDS_WITH, s));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -472,7 +472,7 @@ public class Criteria {
Assert.notNull(values, "Collection of 'in' values must not be null");
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.IN, values));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -499,7 +499,7 @@ public class Criteria {
Assert.notNull(values, "Collection of 'NotIn' values must not be null");
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.NOT_IN, values));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -512,7 +512,7 @@ public class Criteria {
*/
public Criteria expression(String s) {
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EXPRESSION, s));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -524,7 +524,7 @@ public class Criteria {
*/
public Criteria fuzzy(String s) {
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.FUZZY, s));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -539,7 +539,7 @@ public class Criteria {
Assert.notNull(upperBound, "upperBound must not be null");
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.LESS_EQUAL, upperBound));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -554,7 +554,7 @@ public class Criteria {
Assert.notNull(upperBound, "upperBound must not be null");
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.LESS, upperBound));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -569,7 +569,7 @@ public class Criteria {
Assert.notNull(lowerBound, "lowerBound must not be null");
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.GREATER_EQUAL, lowerBound));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -584,7 +584,7 @@ public class Criteria {
Assert.notNull(lowerBound, "lowerBound must not be null");
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.GREATER, lowerBound));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -601,7 +601,7 @@ public class Criteria {
Assert.notNull(value, "value must not be null");
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.MATCHES, value));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -618,7 +618,7 @@ public class Criteria {
Assert.notNull(value, "value must not be null");
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.MATCHES_ALL, value));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -631,7 +631,7 @@ public class Criteria {
public Criteria empty() {
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EMPTY));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -644,7 +644,7 @@ public class Criteria {
public Criteria notEmpty() {
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.NOT_EMPTY));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -660,7 +660,7 @@ public class Criteria {
Assert.notNull(value, "value must not be null");
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.REGEXP, value));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -679,7 +679,7 @@ public class Criteria {
Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null");
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox }));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -696,7 +696,7 @@ public class Criteria {
filterCriteriaEntries
.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox.getFirst(), boundingBox.getSecond() }));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -714,7 +714,7 @@ public class Criteria {
filterCriteriaEntries
.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftGeohash, bottomRightGeohash }));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -731,7 +731,7 @@ public class Criteria {
Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null");
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftPoint, bottomRightPoint }));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -749,7 +749,7 @@ public class Criteria {
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX,
new Object[] { GeoPoint.fromPoint(topLeftPoint), GeoPoint.fromPoint(bottomRightPoint) }));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -767,7 +767,7 @@ public class Criteria {
Assert.notNull(location, "Distance value for near criteria must not be null");
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance }));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -784,7 +784,7 @@ public class Criteria {
Assert.notNull(location, "Distance value for near criteria must not be null");
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance }));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -801,7 +801,7 @@ public class Criteria {
Assert.isTrue(StringUtils.hasLength(geoLocation), "geoLocation value must not be null");
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { geoLocation, distance }));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -816,7 +816,7 @@ public class Criteria {
Assert.notNull(geoShape, "geoShape must not be null");
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_INTERSECTS, geoShape));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -831,7 +831,7 @@ public class Criteria {
Assert.notNull(geoShape, "geoShape must not be null");
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_IS_DISJOINT, geoShape));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -845,7 +845,7 @@ public class Criteria {
Assert.notNull(geoShape, "geoShape must not be null");
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_WITHIN, geoShape));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -859,7 +859,7 @@ public class Criteria {
Assert.notNull(geoShape, "geoShape must not be null");
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_CONTAINS, geoShape));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -873,7 +873,7 @@ public class Criteria {
Assert.notNull(query, "has_child query must not be null.");
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.HAS_CHILD, query));
recalculateHashCode();
recalculateHashCode();
return this;
}
@@ -887,7 +887,7 @@ public class Criteria {
Assert.notNull(query, "has_parent query must not be null.");
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.HAS_PARENT, query));
recalculateHashCode();
recalculateHashCode();
return this;
}
// endregion
@@ -909,7 +909,7 @@ public class Criteria {
// region equals/hashcode
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -937,19 +937,19 @@ public class Criteria {
return hashCode;
}
private void recalculateHashCode() {
int result = field != null ? field.hashCode() : 0;
result = 31 * result + (boost != +0.0f ? Float.floatToIntBits(boost) : 0);
result = 31 * result + (negating ? 1 : 0);
// the criteriaChain contains "this" object, so we need to filter it out
// to avoid a stackoverflow here, because the hashcode implementation
// uses the element's hashcodes
result = 31 * result + criteriaChain.filter(this).hashCode();
result = 31 * result + queryCriteriaEntries.hashCode();
result = 31 * result + filterCriteriaEntries.hashCode();
result = 31 * result + subCriteria.hashCode();
this.hashCode = result;
}
private void recalculateHashCode() {
int result = field != null ? field.hashCode() : 0;
result = 31 * result + (boost != +0.0f ? Float.floatToIntBits(boost) : 0);
result = 31 * result + (negating ? 1 : 0);
// the criteriaChain contains "this" object, so we need to filter it out
// to avoid a stackoverflow here, because the hashcode implementation
// uses the element's hashcodes
result = 31 * result + criteriaChain.filter(this).hashCode();
result = 31 * result + queryCriteriaEntries.hashCode();
result = 31 * result + filterCriteriaEntries.hashCode();
result = 31 * result + subCriteria.hashCode();
this.hashCode = result;
}
// endregion
@Override
@@ -1141,7 +1141,7 @@ public class Criteria {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -354,7 +354,6 @@ public class DeleteQuery {
return version;
}
@Nullable
public Query getQuery() {
return query;
}
@@ -648,6 +647,7 @@ public class DeleteQuery {
return this;
}
@SuppressWarnings("VariableNotUsedInsideIf")
public DeleteQuery build() {
if (luceneQuery == null) {
if (defaultField != null) {
@@ -29,14 +29,14 @@ import org.springframework.util.Assert;
public class FetchSourceFilter implements SourceFilter {
@Nullable private final Boolean fetchSource;
@Nullable private final String[] includes;
@Nullable private final String[] excludes;
private final String @Nullable [] includes;
private final String @Nullable [] excludes;
/**
* @since 5.2
*/
public static SourceFilter of(@Nullable Boolean fetchSource, @Nullable final String[] includes,
@Nullable final String[] excludes) {
public static SourceFilter of(@Nullable Boolean fetchSource, final String @Nullable [] includes,
final String @Nullable [] excludes) {
return new FetchSourceFilter(fetchSource, includes, excludes);
}
@@ -50,25 +50,25 @@ public class FetchSourceFilter implements SourceFilter {
return builderFunction.apply(new FetchSourceFilterBuilder()).build();
}
public FetchSourceFilter(@Nullable Boolean fetchSource, @Nullable final String[] includes,
@Nullable final String[] excludes) {
public FetchSourceFilter(@Nullable Boolean fetchSource, final String @Nullable [] includes,
final String @Nullable [] excludes) {
this.fetchSource = fetchSource;
this.includes = includes;
this.excludes = excludes;
}
@Override
public Boolean fetchSource() {
public @Nullable Boolean fetchSource() {
return fetchSource;
}
@Override
public @Nullable String[] getIncludes() {
public String @Nullable [] getIncludes() {
return includes;
}
@Override
public @Nullable String[] getExcludes() {
public String @Nullable [] getExcludes() {
return excludes;
}
}
@@ -43,7 +43,7 @@ public class GeoDistanceOrder extends Order {
}
private GeoDistanceOrder(String property, GeoPoint geoPoint, Sort.Direction direction, DistanceType distanceType,
Mode mode, String unit, Boolean ignoreUnmapped) {
@Nullable Mode mode, String unit, Boolean ignoreUnmapped) {
super(direction, property, mode);
this.geoPoint = geoPoint;
this.distanceType = distanceType;
@@ -59,7 +59,7 @@ public class GeoDistanceOrder extends Order {
return distanceType;
}
public Mode getMode() {
public @Nullable Mode getMode() {
return mode;
}
@@ -83,7 +83,7 @@ public class SimpleField implements Field {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (this == o)
return true;
if (!(o instanceof SimpleField that))
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.query;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.query.types;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.reindex;
@@ -37,7 +37,7 @@ public class DefaultRoutingResolver implements RoutingResolver {
}
@Override
public String getRouting() {
public @Nullable String getRouting() {
return null;
}
@@ -1,5 +1,18 @@
/**
* classes/interfaces for specification and implementation of Elasticsearch routing.
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.routing;
@@ -1,6 +1,18 @@
/**
* Classes and interfaces to access to script API of Elasticsearch
* (https://www.elastic.co/guide/en/elasticsearch/reference/8.5/script-apis.html).
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.script;
@@ -25,7 +25,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
/**
@@ -110,7 +109,6 @@ public class SqlResponse {
return new Builder();
}
@NonNull
@Override
public Iterator<Map.Entry<Column, JsonValue>> iterator() {
return row.entrySet().iterator();
@@ -1,5 +1,18 @@
/**
* Classes and interfaces to access to SQL API of Elasticsearch.
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.sql;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.suggest.response;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch;
@@ -44,7 +44,7 @@ public interface ElasticsearchRepository<T, ID> extends PagingAndSortingReposito
* @param pageable , must not be {@literal null}
* @return
*/
Page<T> searchSimilar(T entity, @Nullable String[] fields, Pageable pageable);
Page<T> searchSimilar(T entity, String @Nullable [] fields, Pageable pageable);
/**
* @since 5.2
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.aot;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.cdi;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.config;
@@ -1,5 +1,18 @@
/**
* infrastructure to define the Elasticsearch mapping for an index.
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository;
@@ -15,6 +15,8 @@
*/
package org.springframework.data.elasticsearch.repository.query;
import java.util.Objects;
import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
@@ -82,13 +84,17 @@ public abstract class AbstractElasticsearchRepositoryQuery implements Repository
protected abstract boolean isExistsQuery();
@Override
public Object execute(Object[] parameters) {
public Object execute(@Nullable Object[] parameters) {
ElasticsearchParametersParameterAccessor parameterAccessor = getParameterAccessor(parameters);
// need this additional var, otherwise the code analysis does not recognize
// that parameters is not null after the check
var parametersNN = Objects.requireNonNull(parameters, "parameters must not be null");
ElasticsearchParametersParameterAccessor parameterAccessor = getParameterAccessor(parametersNN);
ResultProcessor resultProcessor = queryMethod.getResultProcessor().withDynamicProjection(parameterAccessor);
Class<?> clazz = resultProcessor.getReturnedType().getDomainType();
Query query = createQuery(parameters);
Query query = createQuery(parametersNN);
IndexCoordinates index = parameterAccessor
.getIndexCoordinates(elasticsearchOperations.getIndexCoordinatesFor(clazz));
@@ -18,6 +18,9 @@ package org.springframework.data.elasticsearch.repository.query;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Objects;
import org.jspecify.annotations.Nullable;
import org.reactivestreams.Publisher;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
@@ -72,10 +75,12 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[])
*/
@Override
public Object execute(Object[] parameters) {
public Object execute(@Nullable Object[] parameters) {
Object result = queryMethod.hasReactiveWrapperParameter() ? executeDeferred(parameters)
: execute(new ReactiveElasticsearchParametersParameterAccessor(queryMethod, parameters));
var parametersNN = Objects.requireNonNull(parameters, "parameters must not be null");
Object result = queryMethod.hasReactiveWrapperParameter() ? executeDeferred(parametersNN)
: execute(new ReactiveElasticsearchParametersParameterAccessor(queryMethod, parametersNN));
return queryMethod.isNotSearchHitMethod() ? SearchHitSupport.unwrapSearchHits(result) : result;
}
@@ -98,7 +103,7 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor
Class<?> domainType = returnedType.getDomainType();
Class<?> typeToRead = returnedType.getTypeToRead();
if (SearchHit.class.isAssignableFrom(typeToRead)) {
if (typeToRead != null && SearchHit.class.isAssignableFrom(typeToRead)) {
typeToRead = queryMethod.unwrappedReturnType;
}
@@ -145,9 +150,10 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor
.map(count -> count > 0);
} else if (queryMethod.isCollectionQuery()) {
return (query, type, targetType, indexCoordinates) -> operations.search(query.setPageable(accessor.getPageable()),
type, targetType, indexCoordinates);
type, Objects.requireNonNull(targetType), indexCoordinates);
} else {
return operations::search;
return (query, type, targetType, index) -> operations.search(query, type, Objects.requireNonNull(targetType),
index);
}
}
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.query;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.query.parser;
@@ -15,6 +15,7 @@
*/
package org.springframework.data.elasticsearch.repository.support;
import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
@@ -58,7 +59,7 @@ public class MappingElasticsearchEntityInformation<T, ID> extends PersistentEnti
}
@Override
public Long getVersion(T entity) {
public @Nullable Long getVersion(T entity) {
ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty();
try {
@@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.repository.support;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -240,13 +241,13 @@ public class SimpleElasticsearchRepository<T, ID> implements ElasticsearchReposi
@SuppressWarnings("unchecked")
@Override
public Page<T> searchSimilar(T entity, @Nullable String[] fields, Pageable pageable) {
public Page<T> searchSimilar(T entity, String @Nullable [] fields, Pageable pageable) {
Assert.notNull(entity, "Cannot search similar records for 'null'.");
Assert.notNull(pageable, "'pageable' cannot be 'null'");
MoreLikeThisQuery query = new MoreLikeThisQuery();
query.setId(stringIdRepresentation(extractIdFromBean(entity)));
query.setId(Objects.requireNonNull(stringIdRepresentation(extractIdFromBean(entity))));
query.setPageable(pageable);
if (fields != null) {
@@ -254,7 +255,7 @@ public class SimpleElasticsearchRepository<T, ID> implements ElasticsearchReposi
}
SearchHits<T> searchHits = execute(operations -> operations.search(query, entityClass, getIndexCoordinates()));
SearchPage<T> searchPage = SearchHitSupport.searchPageFor(searchHits, pageable);
SearchPage<T> searchPage = SearchHitSupport.searchPageFor(Objects.requireNonNull(searchHits), pageable);
return (Page<T>) SearchHitSupport.unwrapSearchHits(searchPage);
}
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.support;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.support.querybyexample;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.support.spel;
@@ -1,2 +1,18 @@
/*
* Copyright 2022-present 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.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.support.value;
@@ -77,33 +77,33 @@ public class DefaultStringObjectMap<T extends StringObjectMap<T>> implements Str
}
@Override
public boolean containsKey(Object key) {
public boolean containsKey(@Nullable Object key) {
return delegate.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
public boolean containsValue(@Nullable Object value) {
return delegate.containsValue(value);
}
@Override
@Nullable
public Object get(Object key) {
public Object get(@Nullable Object key) {
return delegate.get(key);
}
@Override
public Object getOrDefault(Object key, Object defaultValue) {
public Object getOrDefault(@Nullable Object key, @Nullable Object defaultValue) {
return delegate.getOrDefault(key, defaultValue);
}
@Override
public Object put(String key, Object value) {
public @Nullable Object put(String key, @Nullable Object value) {
return delegate.put(key, value);
}
@Override
public Object remove(Object key) {
public Object remove(@Nullable Object key) {
return delegate.remove(key);
}
@@ -133,7 +133,7 @@ public class DefaultStringObjectMap<T extends StringObjectMap<T>> implements Str
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
return delegate.equals(o);
}
@@ -143,7 +143,8 @@ public class DefaultStringObjectMap<T extends StringObjectMap<T>> implements Str
}
@Override
public void forEach(BiConsumer<? super String, ? super Object> action) {
public void forEach(
@SuppressWarnings("NullableProblems") BiConsumer<? super String, ? super @Nullable Object> action) {
delegate.forEach(action);
}
@@ -163,7 +164,7 @@ public class DefaultStringObjectMap<T extends StringObjectMap<T>> implements Str
Assert.notNull(path, "path must not be null");
Map<String, Object> current = this;
Map<String, @Nullable Object> current = this;
String[] segments = path.split("\\.");
for (int i = 0; i < segments.length; i++) {

Some files were not shown because too many files have changed in this diff Show More