From 242ae3744c51699a161e8d3ad22b1e5e60cc3596 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 6 Apr 2024 09:53:19 +0200 Subject: [PATCH] Code cleanup. Closes #2888 --- .../annotations/IndexedIndexName.java | 11 +-- .../elasticsearch/annotations/Mapping.java | 2 +- .../elc/AutoCloseableElasticsearchClient.java | 6 -- .../client/elc/CriteriaQueryProcessor.java | 2 +- .../elasticsearch/client/elc/JsonUtils.java | 11 +-- .../client/elc/NativeQueryBuilder.java | 4 +- .../client/elc/RequestConverter.java | 4 - .../client/elc/ResponseConverter.java | 20 ++-- .../core/AbstractElasticsearchTemplate.java | 1 + ...AbstractReactiveElasticsearchTemplate.java | 1 + .../core/DocumentOperations.java | 2 + .../core/ReactiveDocumentOperations.java | 2 + .../elasticsearch/core/RefreshPolicy.java | 2 +- .../elasticsearch/core/SearchHitMapping.java | 6 +- .../elasticsearch/core/SearchHitSupport.java | 2 +- .../elasticsearch/core/SearchHitsImpl.java | 2 +- .../elasticsearch/core/StreamQueries.java | 4 +- .../core/convert/ElasticsearchConverter.java | 2 +- .../core/convert/GeoConverters.java | 2 +- .../MappingElasticsearchConverter.java | 97 +++++++++++-------- .../elasticsearch/core/document/Document.java | 10 +- .../data/elasticsearch/core/geo/GeoBox.java | 4 +- .../core/geo/GeoJsonMultiPolygon.java | 2 +- .../core/index/MappingBuilder.java | 2 +- .../elasticsearch/core/join/JoinField.java | 4 +- .../SimpleElasticsearchPersistentEntity.java | 4 +- .../core/query/ByQueryResponse.java | 6 ++ .../elasticsearch/core/query/Criteria.java | 6 +- .../elasticsearch/core/query/IndexBoost.java | 4 +- .../core/query/IndicesOptions.java | 8 +- .../data/elasticsearch/core/query/Order.java | 25 ++--- .../data/elasticsearch/core/query/Query.java | 5 +- .../core/query/UpdateResponse.java | 4 +- .../AbstractElasticsearchRepositoryQuery.java | 3 +- ...tReactiveElasticsearchRepositoryQuery.java | 4 +- .../query/ElasticsearchParameter.java | 2 +- .../query/ElasticsearchParameters.java | 10 +- .../query/ElasticsearchQueryMethod.java | 12 ++- ...sticsearchParametersParameterAccessor.java | 2 +- .../ReactiveElasticsearchQueryMethod.java | 5 - .../SimpleElasticsearchRepository.java | 11 +-- ...SimpleReactiveElasticsearchRepository.java | 20 ++-- .../support/DefaultStringObjectMap.java | 2 +- .../core/DocumentOperationsExtensions.kt | 14 ++- ...activeElasticsearchOperationsExtensions.kt | 6 +- .../ReactiveSearchOperationsExtensions.kt | 47 +++++++-- .../core/SearchOperationsExtensions.kt | 32 +++--- .../NestedObjectIntegrationTests.java | 65 +++++++------ .../ComposableAnnotationsUnitTest.java | 6 +- .../BlockHoundIntegrationCustomizer.java | 7 +- .../elasticsearch/client/RestClientsTest.java | 14 ++- .../elc/CriteriaQueryMappingUnitTests.java | 2 +- .../elc/CriteriaQueryProcessorUnitTests.java | 8 +- .../elasticsearch/client/elc/DevTests.java | 14 +-- .../client/elc/ELCWiremockTests.java | 1 + .../client/elc/RequestConverterTest.java | 20 ++-- ...earchDocumentResponseBuilderUnitTests.java | 6 +- ...iveElasticsearchConfigurationELCTests.java | 2 +- .../EnableRepositoriesIntegrationTests.java | 3 +- .../core/ElasticsearchIntegrationTests.java | 38 +++++--- .../core/EntityOperationsUnitTests.java | 2 +- ...ReactiveElasticsearchIntegrationTests.java | 15 ++- ...eactiveSearchTemplateIntegrationTests.java | 2 +- ...asticsearchCustomConversionsUnitTests.java | 4 +- .../ElasticsearchDateConverterUnitTests.java | 2 +- ...appingElasticsearchConverterUnitTests.java | 26 ++--- .../core/geo/GeoIntegrationTests.java | 4 +- .../index/IndexTemplateIntegrationTests.java | 8 +- .../index/MappingBuilderIntegrationTests.java | 4 +- .../core/index/MappingBuilderUnitTests.java | 6 +- .../core/index/MappingParametersTest.java | 2 +- ...ReactiveIndexTemplateIntegrationTests.java | 8 +- .../SimpleDynamicTemplatesMappingTests.java | 4 +- .../ReactiveSearchAfterIntegrationTests.java | 2 +- ...lasticsearchPartQueryIntegrationTests.java | 5 +- .../query/NativeQueryIntegrationTests.java | 2 +- ...iptedAndRuntimeFieldsIntegrationTests.java | 4 +- .../DefaultRoutingResolverUnitTest.java | 5 +- .../suggest/CompletionIntegrationTests.java | 4 +- ...ompletionWithContextsIntegrationTests.java | 10 +- .../ReactiveSuggestIntegrationTests.java | 2 +- .../cdi/ElasticsearchOperationsProducer.java | 1 + ...asticsearchRepositoryManualWiringImpl.java | 2 +- ...asticsearchRepositoryIntegrationTests.java | 8 +- ...asticsearchRepositoriesRegistrarTests.java | 2 +- ...sitoryConfigurationExtensionUnitTests.java | 6 +- .../QueryKeywordsIntegrationTests.java | 2 - ...ReactiveQueryKeywordsIntegrationTests.java | 3 - .../support/HttpHeadersTest.java | 1 + .../elasticsearch/utils/IndexBuilder.java | 2 +- .../elasticsearch/utils/geohash/BitUtil.java | 3 +- .../elasticsearch/utils/geohash/Geohash.java | 22 ++--- .../utils/geohash/GeometryVisitor.java | 18 ---- .../utils/geohash/WellKnownText.java | 47 ++++----- .../CoroutineRepositoryELCIntegrationTests.kt | 30 +++--- .../CoroutineRepositoryIntegrationTests.kt | 95 ++++++++++-------- ...sticsearchQueryMethodCoroutineUnitTests.kt | 71 ++++++++------ 97 files changed, 566 insertions(+), 491 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexedIndexName.java b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexedIndexName.java index fd8cc8146a..6fcb10213e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexedIndexName.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexedIndexName.java @@ -15,9 +15,6 @@ */ package org.springframework.data.elasticsearch.annotations; -import org.springframework.data.annotation.ReadOnlyProperty; -import org.springframework.data.annotation.Transient; - import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -25,10 +22,10 @@ import java.lang.annotation.Target; /** - * Annotation to mark a String property of an entity to be filled with the name of the index where the entity was - * stored after it is indexed into Elasticsearch. This can be used when the name of the index is dynamically created - * or when a document was indexed into a write alias. - * + * Annotation to mark a String property of an entity to be filled with the name of the index where the entity was stored + * after it is indexed into Elasticsearch. This can be used when the name of the index is dynamically created or when a + * document was indexed into a write alias. + *

* This can not be used to specify the index where an entity should be written to. * * @author Peter-Josef Meisch diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java index 0fd36357df..4146824cf0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java @@ -82,6 +82,6 @@ MappingAlias[] aliases() default {}; enum Detection { - DEFAULT, TRUE, FALSE; + DEFAULT, TRUE, FALSE } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/AutoCloseableElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/AutoCloseableElasticsearchClient.java index d6489ba19c..fe6afc148c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/elc/AutoCloseableElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/AutoCloseableElasticsearchClient.java @@ -16,7 +16,6 @@ package org.springframework.data.elasticsearch.client.elc; import co.elastic.clients.elasticsearch.ElasticsearchClient; -import co.elastic.clients.elasticsearch.cluster.ElasticsearchClusterClient; import co.elastic.clients.transport.ElasticsearchTransport; import org.elasticsearch.client.RestClient; @@ -40,9 +39,4 @@ public AutoCloseableElasticsearchClient(ElasticsearchTransport transport) { public void close() throws Exception { transport.close(); } - - @Override - public ElasticsearchClusterClient cluster() { - return super.cluster(); - } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryProcessor.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryProcessor.java index 080920959e..c4934ddc03 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryProcessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryProcessor.java @@ -365,7 +365,7 @@ private static String orQueryString(Iterable iterable) { if (item != null) { - if (sb.length() > 0) { + if (!sb.isEmpty()) { sb.append(' '); } sb.append('"'); diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/JsonUtils.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/JsonUtils.java index 64697766e7..801e727d0d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/elc/JsonUtils.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/JsonUtils.java @@ -19,7 +19,6 @@ import jakarta.json.stream.JsonGenerator; import java.io.ByteArrayOutputStream; -import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import org.apache.commons.logging.Log; @@ -44,17 +43,13 @@ public static String toJson(Object object, JsonpMapper mapper) { mapper.serialize(object, generator); generator.close(); String json = "{}"; - try { - json = baos.toString("UTF-8"); - } catch (UnsupportedEncodingException e) { - LOGGER.warn("could not read json", e); - } - + json = baos.toString(StandardCharsets.UTF_8); return json; } @Nullable - public static String queryToJson(@Nullable co.elastic.clients.elasticsearch._types.query_dsl.Query query, JsonpMapper mapper) { + public static String queryToJson(@Nullable co.elastic.clients.elasticsearch._types.query_dsl.Query query, + JsonpMapper mapper) { if (query == null) { return null; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/NativeQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/NativeQueryBuilder.java index e2eeb49fa4..d290dd7826 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/elc/NativeQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/NativeQueryBuilder.java @@ -47,8 +47,8 @@ public class NativeQueryBuilder extends BaseQueryBuilder aggregations = new LinkedHashMap<>(); @Nullable private Suggester suggester; @Nullable private FieldCollapse fieldCollapse; - private List sortOptions = new ArrayList<>(); - private Map searchExtensions = new LinkedHashMap<>(); + private final List sortOptions = new ArrayList<>(); + private final Map searchExtensions = new LinkedHashMap<>(); @Nullable private org.springframework.data.elasticsearch.core.query.Query springDataQuery; @Nullable private KnnQuery knnQuery; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/RequestConverter.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/RequestConverter.java index 4c83e51e3a..8e7851f150 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/elc/RequestConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/RequestConverter.java @@ -157,7 +157,6 @@ public co.elastic.clients.elasticsearch.cluster.PutComponentTemplateRequest clus aliasActions.getActions().forEach(aliasAction -> { if (aliasAction instanceof AliasAction.Add add) { var parameters = add.getParameters(); - // noinspection DuplicatedCode String[] parametersAliases = parameters.getAliases(); if (parametersAliases != null) { for (String aliasName : parametersAliases) { @@ -173,7 +172,6 @@ public co.elastic.clients.elasticsearch.cluster.PutComponentTemplateRequest clus private Alias.Builder buildAlias(AliasActionParameters parameters, Alias.Builder aliasBuilder) { - // noinspection DuplicatedCode if (parameters.getRouting() != null) { aliasBuilder.routing(parameters.getRouting()); } @@ -416,7 +414,6 @@ public co.elastic.clients.elasticsearch.indices.PutTemplateRequest indicesPutTem if (aliasActions != null) { aliasActions.getActions().forEach(aliasAction -> { AliasActionParameters parameters = aliasAction.getParameters(); - // noinspection DuplicatedCode String[] parametersAliases = parameters.getAliases(); if (parametersAliases != null) { @@ -450,7 +447,6 @@ public co.elastic.clients.elasticsearch.indices.PutIndexTemplateRequest indicesP aliasActions.getActions().forEach(aliasAction -> { if (aliasAction instanceof AliasAction.Add add) { var parameters = add.getParameters(); - // noinspection DuplicatedCode String[] parametersAliases = parameters.getAliases(); if (parametersAliases != null) { for (String aliasName : parametersAliases) { diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/ResponseConverter.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/ResponseConverter.java index 8b8dbcbc23..1dada5d11f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/elc/ResponseConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/ResponseConverter.java @@ -15,9 +15,8 @@ */ package org.springframework.data.elasticsearch.client.elc; -import static org.springframework.data.elasticsearch.client.elc.JsonUtils.toJson; -import static org.springframework.data.elasticsearch.client.elc.TypeUtils.removePrefixFromJson; -import static org.springframework.data.elasticsearch.client.elc.TypeUtils.typeMapping; +import static org.springframework.data.elasticsearch.client.elc.JsonUtils.*; +import static org.springframework.data.elasticsearch.client.elc.TypeUtils.*; import co.elastic.clients.elasticsearch._types.BulkIndexByScrollFailure; import co.elastic.clients.elasticsearch._types.ErrorCause; @@ -36,7 +35,12 @@ import co.elastic.clients.elasticsearch.indices.get_mapping.IndexMappingRecord; import co.elastic.clients.json.JsonpMapper; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -47,7 +51,11 @@ import org.springframework.data.elasticsearch.core.MultiGetItem; import org.springframework.data.elasticsearch.core.cluster.ClusterHealth; import org.springframework.data.elasticsearch.core.document.Document; -import org.springframework.data.elasticsearch.core.index.*; +import org.springframework.data.elasticsearch.core.index.AliasData; +import org.springframework.data.elasticsearch.core.index.Settings; +import org.springframework.data.elasticsearch.core.index.TemplateData; +import org.springframework.data.elasticsearch.core.index.TemplateResponse; +import org.springframework.data.elasticsearch.core.index.TemplateResponseData; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.ByQueryResponse; import org.springframework.data.elasticsearch.core.query.StringQuery; @@ -182,7 +190,7 @@ public Document indicesGetMapping(GetMappingResponse getMappingResponse, IndexCo Map mappings = getMappingResponse.result(); - if (mappings == null || mappings.size() == 0) { + if (mappings == null || mappings.isEmpty()) { return Document.create(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 60018096b2..4275e17f8b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -299,6 +299,7 @@ public String delete(String id, Class entityType) { } @Override + @Deprecated public ByQueryResponse delete(Query query, Class clazz) { return delete(query, clazz, getIndexCoordinatesFor(clazz)); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractReactiveElasticsearchTemplate.java index def1796f5c..96e9018c39 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractReactiveElasticsearchTemplate.java @@ -409,6 +409,7 @@ public Mono delete(String id, IndexCoordinates index) { abstract protected Mono doDeleteById(String id, @Nullable String routing, IndexCoordinates index); @Override + @Deprecated public Mono delete(Query query, Class entityType) { return delete(query, entityType, getIndexCoordinatesFor(entityType)); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java index 29b7ac4237..1dd0005433 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -282,6 +282,7 @@ default void bulkUpdate(List queries, IndexCoordinates index) { * @since 4.1 * @deprecated since 5.3.0, use {@link #delete(DeleteQuery, Class)} */ + @Deprecated ByQueryResponse delete(Query query, Class clazz); /** @@ -305,6 +306,7 @@ default void bulkUpdate(List queries, IndexCoordinates index) { * @return response with detailed information * @deprecated since 5.3.0, use {@link #delete(DeleteQuery, Class, IndexCoordinates)} */ + @Deprecated ByQueryResponse delete(Query query, Class clazz, IndexCoordinates index); /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java index 907ae73525..f5b191501c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java @@ -334,6 +334,7 @@ default Mono bulkUpdate(List queries, IndexCoordinates index) * @return a {@link Mono} emitting the number of the removed documents. * @deprecated since 5.3.0, use {@link #delete(DeleteQuery, Class)} */ + @Deprecated Mono delete(Query query, Class entityType); /** @@ -355,6 +356,7 @@ default Mono bulkUpdate(List queries, IndexCoordinates index) * @return a {@link Mono} emitting the number of the removed documents. * @deprecated since 5.3.0, use {@link #delete(DeleteQuery, Class, IndexCoordinates)} */ + @Deprecated Mono delete(Query query, Class entityType, IndexCoordinates index); /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RefreshPolicy.java b/src/main/java/org/springframework/data/elasticsearch/core/RefreshPolicy.java index 5112dd14b5..356a67d8a5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RefreshPolicy.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RefreshPolicy.java @@ -22,5 +22,5 @@ * @since 4.2 */ public enum RefreshPolicy { - NONE, IMMEDIATE, WAIT_UNTIL; + NONE, IMMEDIATE, WAIT_UNTIL } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java index f1a46518cd..42fa2da496 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java @@ -167,7 +167,7 @@ private Map> mapInnerHits(SearchDocument searchDocument) { Map> innerHits = new LinkedHashMap<>(); Map documentInnerHits = searchDocument.getInnerHits(); - if (documentInnerHits != null && documentInnerHits.size() > 0) { + if (documentInnerHits != null && !documentInnerHits.isEmpty()) { SearchHitMapping searchDocumentSearchHitMapping = SearchHitMapping .mappingFor(SearchDocument.class, converter); @@ -287,8 +287,8 @@ private ElasticsearchPersistentEntityWithNestedMetaData getPersistentEntity( } private static class ElasticsearchPersistentEntityWithNestedMetaData { - @Nullable private ElasticsearchPersistentEntity entity; - private NestedMetaData nestedMetaData; + @Nullable private final ElasticsearchPersistentEntity entity; + private final NestedMetaData nestedMetaData; public ElasticsearchPersistentEntityWithNestedMetaData(@Nullable ElasticsearchPersistentEntity entity, NestedMetaData nestedMetaData) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java index 18a553ce0c..2be5af5665 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -23,8 +23,8 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; -import org.springframework.data.repository.util.ReactiveWrappers; import org.springframework.data.util.CloseableIterator; +import org.springframework.data.util.ReactiveWrappers; import org.springframework.lang.Nullable; /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitsImpl.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitsImpl.java index 13e4d130f5..fda8e8a302 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitsImpl.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitsImpl.java @@ -42,7 +42,7 @@ public class SearchHitsImpl implements SearchScrollHits { private final Lazy>> unmodifiableSearchHits; @Nullable private final AggregationsContainer aggregations; @Nullable private final Suggest suggest; - @Nullable private String pointInTimeId; + @Nullable private final String pointInTimeId; @Nullable private final SearchShardStatistics searchShardStatistics; /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java index d1603dc976..5c9a04a566 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java @@ -61,10 +61,10 @@ static SearchHitsIterator streamResults(int maxCount, SearchScrollHits return new SearchHitsIterator<>() { - private volatile AtomicInteger currentCount = new AtomicInteger(); + private final AtomicInteger currentCount = new AtomicInteger(); private volatile Iterator> currentScrollHits = searchHits.iterator(); private volatile boolean continueScroll = currentScrollHits.hasNext(); - private volatile ScrollState scrollState = new ScrollState(searchHits.getScrollId()); + private final ScrollState scrollState = new ScrollState(searchHits.getScrollId()); private volatile boolean isClosed = false; @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java index 320f50ed7b..587540c6d7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java @@ -110,6 +110,6 @@ default Document mapObject(@Nullable Object source) { * @return a String wihere the property names are replaced with field names * @since 5.2 */ - public String updateFieldNames(String propertyPath, ElasticsearchPersistentEntity persistentEntity); + String updateFieldNames(String propertyPath, ElasticsearchPersistentEntity persistentEntity); // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java index 6f10de6042..b48654d614 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java @@ -344,7 +344,7 @@ public GeoJsonPolygon convert(Map source) { String type = GeoConverters.getGeoJsonType(source); Assert.isTrue(type.equalsIgnoreCase(GeoJsonPolygon.TYPE), "does not contain a type 'Polygon'"); List lines = geoJsonLineStringsFromMap(source); - Assert.isTrue(lines.size() > 0, "no linestrings defined in polygon"); + Assert.isTrue(!lines.isEmpty(), "no linestrings defined in polygon"); GeoJsonPolygon geoJsonPolygon = GeoJsonPolygon.of(lines.get(0)); for (int i = 1; i < lines.size(); i++) { geoJsonPolygon = geoJsonPolygon.withInnerRing(lines.get(i)); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 68808a7119..ccac971fd1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -34,6 +34,9 @@ import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.core.env.Environment; +import org.springframework.core.env.EnvironmentCapable; +import org.springframework.core.env.StandardEnvironment; import org.springframework.data.convert.CustomConversions; import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.ScriptedField; @@ -58,6 +61,7 @@ import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.*; import org.springframework.data.util.TypeInformation; +import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.format.datetime.DateFormatterRegistrar; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -65,8 +69,6 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import javax.print.Doc; - /** * Elasticsearch specific {@link org.springframework.data.convert.EntityConverter} implementation based on domain type * {@link ElasticsearchPersistentEntity metadata}. @@ -86,7 +88,7 @@ * @since 3.2 */ public class MappingElasticsearchConverter - implements ElasticsearchConverter, ApplicationContextAware, InitializingBean { + implements ElasticsearchConverter, ApplicationContextAware, InitializingBean, EnvironmentCapable { private static final String INCOMPATIBLE_TYPES = "Cannot convert %1$s of type %2$s into an instance of %3$s! Implement a custom Converter<%2$s, %3$s> and register it with the CustomConversions."; private static final String INVALID_TYPE_TO_READ = "Expected to read Document %s into type %s but didn't find a PersistentEntity for the latter!"; @@ -96,7 +98,14 @@ public class MappingElasticsearchConverter private final MappingContext, ElasticsearchPersistentProperty> mappingContext; private final GenericConversionService conversionService; private CustomConversions conversions = new ElasticsearchCustomConversions(Collections.emptyList()); + + protected @Nullable Environment environment; + private final SpELContext spELContext = new SpELContext(new MapAccessor()); + private final SpelExpressionParser expressionParser = new SpelExpressionParser(); + private final CachingValueExpressionEvaluatorFactory expressionEvaluatorFactory = new CachingValueExpressionEvaluatorFactory( + expressionParser, this, spELContext); + private final EntityInstantiators instantiators = new EntityInstantiators(); private final ElasticsearchTypeMapper typeMapper; @@ -124,6 +133,14 @@ public void setApplicationContext(ApplicationContext applicationContext) throws } } + @Override + public Environment getEnvironment() { + if (environment == null) { + environment = new StandardEnvironment(); + } + return environment; + } + @Override public MappingContext, ElasticsearchPersistentProperty> getMappingContext() { return mappingContext; @@ -162,7 +179,8 @@ public ElasticsearchTypeMapper getTypeMapper() { @Override public R read(Class type, Document source) { - Reader reader = new Reader(mappingContext, conversionService, conversions, typeMapper, spELContext, instantiators); + Reader reader = new Reader(mappingContext, conversionService, conversions, typeMapper, expressionEvaluatorFactory, + instantiators); return reader.read(type, source); } @@ -202,29 +220,29 @@ private Base( */ private static class Reader extends Base { - private final SpELContext spELContext; private final EntityInstantiators instantiators; + private final CachingValueExpressionEvaluatorFactory expressionEvaluatorFactory; public Reader( MappingContext, ElasticsearchPersistentProperty> mappingContext, GenericConversionService conversionService, CustomConversions conversions, ElasticsearchTypeMapper typeMapper, - SpELContext spELContext, EntityInstantiators instantiators) { + CachingValueExpressionEvaluatorFactory expressionEvaluatorFactory, EntityInstantiators instantiators) { super(mappingContext, conversionService, conversions, typeMapper); - this.spELContext = spELContext; + this.expressionEvaluatorFactory = expressionEvaluatorFactory; this.instantiators = instantiators; } - @SuppressWarnings("unchecked") /** * Reads the given source into the given type. * - * @param type they type to convert the given source to. + * @param type the type to convert the given source to. * @param source the source to create an object of the given type from. * @return the object that was read */ R read(Class type, Document source) { + // noinspection unchecked TypeInformation typeInformation = TypeInformation.of((Class) ClassUtils.getUserClass(type)); R r = read(typeInformation, source); @@ -316,8 +334,7 @@ private R readMap(TypeInformation type, Map source) { private R readEntity(ElasticsearchPersistentEntity entity, Map source) { ElasticsearchPersistentEntity targetEntity = computeClosestEntity(entity, source); - - SpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(source, spELContext); + ValueExpressionEvaluator evaluator = expressionEvaluatorFactory.create(source); MapValueAccessor accessor = new MapValueAccessor(source); InstanceCreatorMetadata creatorMetadata = entity.getInstanceCreatorMetadata(); @@ -384,7 +401,7 @@ private R readEntity(ElasticsearchPersistentEntity entity, Map getParameterProvider( - ElasticsearchPersistentEntity entity, MapValueAccessor source, SpELExpressionEvaluator evaluator) { + ElasticsearchPersistentEntity entity, MapValueAccessor source, ValueExpressionEvaluator evaluator) { ElasticsearchPropertyValueProvider provider = new ElasticsearchPropertyValueProvider(source, evaluator); @@ -393,7 +410,7 @@ private ParameterValueProvider getParameterProv PersistentEntityParameterValueProvider parameterProvider = new PersistentEntityParameterValueProvider<>( entity, provider, null); - return new ConverterAwareSpELExpressionParameterValueProvider(evaluator, conversionService, parameterProvider); + return new ConverterAwareValueExpressionParameterValueProvider(evaluator, conversionService, parameterProvider); } private boolean isAssignedSeqNo(long seqNo) { @@ -475,7 +492,7 @@ private T readValue(Object value, TypeInformation type) { TypeInformation collectionComponentType = getCollectionComponentType(type); if (collectionComponentType != null) { Object o = read(collectionComponentType, (Map) value); - return getCollectionWithSingleElement(type, collectionComponentType, o); + return (o != null) ? getCollectionWithSingleElement(type, collectionComponentType, o) : null; } return (T) read(type, (Map) value); } else { @@ -484,7 +501,7 @@ private T readValue(Object value, TypeInformation type) { if (collectionComponentType != null && collectionComponentType.isAssignableFrom(TypeInformation.of(value.getClass()))) { Object o = getPotentiallyConvertedSimpleRead(value, collectionComponentType); - return getCollectionWithSingleElement(type, collectionComponentType, o); + return (o != null) ? getCollectionWithSingleElement(type, collectionComponentType, o) : null; } return (T) getPotentiallyConvertedSimpleRead(value, rawType); @@ -502,7 +519,7 @@ private static T getCollectionWithSingleElement(TypeInformation collectio /** * @param type the type to check - * @return true if type is a collectoin, null otherwise, + * @return the collection type if type is a collection, null otherwise, */ @Nullable TypeInformation getCollectionComponentType(TypeInformation type) { @@ -618,9 +635,10 @@ private Object getPotentiallyConvertedSimpleRead(@Nullable Object value, @Nullab * but will be removed from spring-data-commons, so we do it here */ @Nullable - private Object convertFromCollectionToObject(Object value, @Nullable Class target) { + private Object convertFromCollectionToObject(Object value, Class target) { if (value.getClass().isArray()) { + // noinspection ArraysAsListWithZeroOrOneArgument value = Arrays.asList(value); } @@ -670,9 +688,9 @@ private ElasticsearchPersistentEntity computeClosestEntity(ElasticsearchPersi class ElasticsearchPropertyValueProvider implements PropertyValueProvider { final MapValueAccessor accessor; - final SpELExpressionEvaluator evaluator; + final ValueExpressionEvaluator evaluator; - ElasticsearchPropertyValueProvider(MapValueAccessor accessor, SpELExpressionEvaluator evaluator) { + ElasticsearchPropertyValueProvider(MapValueAccessor accessor, ValueExpressionEvaluator evaluator) { this.accessor = accessor; this.evaluator = evaluator; } @@ -692,33 +710,29 @@ public T getPropertyValue(ElasticsearchPersistentProperty property) { } /** - * Extension of {@link SpELExpressionParameterValueProvider} to recursively trigger value conversion on the raw + * Extension of {@link ValueExpressionParameterValueProvider} to recursively trigger value conversion on the raw * resolved SpEL value. * * @author Mark Paluch */ - private class ConverterAwareSpELExpressionParameterValueProvider - extends SpELExpressionParameterValueProvider { + private class ConverterAwareValueExpressionParameterValueProvider + extends ValueExpressionParameterValueProvider { /** - * Creates a new {@link ConverterAwareSpELExpressionParameterValueProvider}. + * Creates a new {@link ConverterAwareValueExpressionParameterValueProvider}. * * @param evaluator must not be {@literal null}. * @param conversionService must not be {@literal null}. * @param delegate must not be {@literal null}. */ - public ConverterAwareSpELExpressionParameterValueProvider(SpELExpressionEvaluator evaluator, + public ConverterAwareValueExpressionParameterValueProvider(ValueExpressionEvaluator evaluator, ConversionService conversionService, ParameterValueProvider delegate) { super(evaluator, conversionService, delegate); } - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.model.SpELExpressionParameterValueProvider#potentiallyConvertSpelValue(java.lang.Object, org.springframework.data.mapping.PreferredConstructor.Parameter) - */ @Override - protected T potentiallyConvertSpelValue(Object object, + protected T potentiallyConvertExpressionValue(Object object, Parameter parameter) { return readValue(object, parameter.getType()); } @@ -995,12 +1009,8 @@ private void writeProperties(ElasticsearchPersistentEntity entity, Persistent private static boolean hasEmptyValue(Object value) { - if (value instanceof String s && s.isEmpty() || value instanceof Collection c && c.isEmpty() - || value instanceof Map m && m.isEmpty()) { - return true; - } - - return false; + return value instanceof String s && s.isEmpty() || value instanceof Collection c && c.isEmpty() + || value instanceof Map m && m.isEmpty(); } @SuppressWarnings("unchecked") @@ -1402,12 +1412,18 @@ public String updateFieldNames(String propertyPath, ElasticsearchPersistentEntit if (properties.length > 1) { var persistentProperty = persistentEntity.getPersistentProperty(propertyName); - return (persistentProperty != null) - ? fieldName + "." + updateFieldNames(properties[1], mappingContext.getPersistentEntity(persistentProperty)) - : fieldName; - } else { - return fieldName; + + if (persistentProperty != null) { + ElasticsearchPersistentEntity nestedPersistentEntity = mappingContext + .getPersistentEntity(persistentProperty); + if (nestedPersistentEntity != null) { + return fieldName + '.' + updateFieldNames(properties[1], nestedPersistentEntity); + } else { + return fieldName; + } + } } + return fieldName; } else { return propertyPath; } @@ -1416,6 +1432,7 @@ public String updateFieldNames(String propertyPath, ElasticsearchPersistentEntit // endregion + @SuppressWarnings("ClassCanBeRecord") static class MapValueAccessor { final Map target; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java index b1ddccbf83..c2328c25aa 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java @@ -18,11 +18,7 @@ import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; -import java.util.function.BooleanSupplier; import java.util.function.Function; -import java.util.function.IntSupplier; -import java.util.function.LongSupplier; -import java.util.function.Supplier; import org.springframework.data.elasticsearch.core.convert.ConversionException; import org.springframework.data.elasticsearch.support.StringObjectMap; @@ -30,8 +26,8 @@ import org.springframework.util.Assert; /** - * A representation of an Elasticsearch document as extended {@link StringObjectMap Map}. All iterators preserve original - * insertion order. + * A representation of an Elasticsearch document as extended {@link StringObjectMap Map}. All iterators preserve + * original insertion order. *

* Document does not allow {@code null} keys. It allows {@literal null} values. *

@@ -60,7 +56,7 @@ static Document create() { * @param map source map containing key-value pairs and sub-documents. must not be {@literal null}. * @return a new {@link Document}. */ - static Document from(Map map) { + static Document from(Map map) { Assert.notNull(map, "Map must not be null"); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoBox.java b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoBox.java index 27200b0ec3..802e57ca37 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoBox.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoBox.java @@ -24,8 +24,8 @@ */ public class GeoBox { - private GeoPoint topLeft; - private GeoPoint bottomRight; + private final GeoPoint topLeft; + private final GeoPoint bottomRight; public GeoBox(GeoPoint topLeft, GeoPoint bottomRight) { this.topLeft = topLeft; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoJsonMultiPolygon.java b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoJsonMultiPolygon.java index e7aee528f3..a34cd4be1a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoJsonMultiPolygon.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoJsonMultiPolygon.java @@ -33,7 +33,7 @@ public class GeoJsonMultiPolygon implements GeoJson> { public static final String TYPE = "MultiPolygon"; - private List coordinates = new ArrayList<>(); + private final List coordinates = new ArrayList<>(); private GeoJsonMultiPolygon(List polygons) { this.coordinates.addAll(polygons); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index 3214867704..bcf25c01b3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -443,7 +443,7 @@ private void applyCompletionFieldMapping(ObjectNode propertyNode, ElasticsearchP contextNode.put(FIELD_CONTEXT_NAME, context.name()); contextNode.put(FIELD_CONTEXT_TYPE, context.type().getMappedName()); - if (context.precision().length() > 0) { + if (!context.precision().isEmpty()) { contextNode.put(FIELD_CONTEXT_PRECISION, context.precision()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java b/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java index 2b1832b27d..bc00799a56 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java @@ -17,7 +17,7 @@ import java.util.Objects; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.lang.Nullable; /** @@ -39,7 +39,7 @@ public JoinField(String name) { this(name, null); } - @PersistenceConstructor + @PersistenceCreator public JoinField(String name, @Nullable ID parent) { this.name = name; this.parent = parent; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java index ab96f7883a..f265fa13d1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java @@ -73,8 +73,8 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit private @Nullable ElasticsearchPersistentProperty joinFieldProperty; private @Nullable ElasticsearchPersistentProperty indexedIndexNameProperty; private @Nullable Document.VersionType versionType; - private boolean createIndexAndMapping; - private boolean alwaysWriteMapping; + private final boolean createIndexAndMapping; + private final boolean alwaysWriteMapping; private final Dynamic dynamic; private final Map fieldNamePropertyCache = new ConcurrentHashMap<>(); private final ConcurrentHashMap routingExpressions = new ConcurrentHashMap<>(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/ByQueryResponse.java b/src/main/java/org/springframework/data/elasticsearch/core/query/ByQueryResponse.java index 84db334b46..cf6d3269bc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/ByQueryResponse.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/ByQueryResponse.java @@ -230,11 +230,17 @@ public Boolean getAborted() { return aborted; } + @Nullable + public ElasticsearchErrorCause getElasticsearchErrorCause() { + return elasticsearchErrorCause; + } + /** * Create a new {@link FailureBuilder} to build {@link Failure} * * @return a new {@link FailureBuilder} to build {@link Failure} */ + public static FailureBuilder builder() { return new FailureBuilder(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java index e1581390de..5273797996 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java @@ -673,8 +673,8 @@ public Criteria boundedBy(Box boundingBox) { */ public Criteria boundedBy(String topLeftGeohash, String bottomRightGeohash) { - Assert.isTrue(!StringUtils.isEmpty(topLeftGeohash), "topLeftGeohash must not be empty"); - Assert.isTrue(!StringUtils.isEmpty(bottomRightGeohash), "bottomRightGeohash must not be empty"); + Assert.isTrue(StringUtils.hasLength(topLeftGeohash), "topLeftGeohash must not be empty"); + Assert.isTrue(StringUtils.hasLength(bottomRightGeohash), "bottomRightGeohash must not be empty"); filterCriteriaEntries .add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftGeohash, bottomRightGeohash })); @@ -757,7 +757,7 @@ public Criteria within(Point location, Distance distance) { */ public Criteria within(String geoLocation, String distance) { - Assert.isTrue(!StringUtils.isEmpty(geoLocation), "geoLocation value must not be null"); + Assert.isTrue(StringUtils.hasLength(geoLocation), "geoLocation value must not be null"); filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { geoLocation, distance })); return this; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexBoost.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexBoost.java index 7888cde2f4..94ec1c0ace 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexBoost.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexBoost.java @@ -23,8 +23,8 @@ */ public class IndexBoost { - private String indexName; - private float boost; + private final String indexName; + private final float boost; public IndexBoost(String indexName, float boost) { this.indexName = indexName; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndicesOptions.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndicesOptions.java index 5e518ff21a..7ced9cb52b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndicesOptions.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndicesOptions.java @@ -25,8 +25,8 @@ */ public class IndicesOptions { - private EnumSet