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 fd8cc8146..6fcb10213 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 0fd36357d..4146824cf 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 d6489ba19..fe6afc148 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 080920959..c4934ddc0 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 64697766e..801e727d0 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 e2eeb49fa..d290dd782 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 4c83e51e3..8e7851f15 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 8b8dbcbc2..1dada5d11 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 60018096b..4275e17f8 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 def1796f5..96e9018c3 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 29b7ac423..1dd000543 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 907ae7352..f5b191501 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 5112dd14b..356a67d8a 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 f1a46518c..42fa2da49 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 18a553ce0..2be5af566 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 13e4d130f..fda8e8a30 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 d1603dc97..5c9a04a56 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 320f50ed7..587540c6d 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 6f10de604..b48654d61 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 68808a711..ccac971fd 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 b1ddccbf8..c2328c25a 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 27200b0ec..802e57ca3 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 e7aee528f..a34cd4be1 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 321486770..bcf25c01b 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 2b1832b27..bc00799a5 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 ab96f7883..f265fa13d 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 84db334b4..cf6d3269b 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 e1581390d..527379799 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 7888cde2f..94ec1c0ac 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 5e518ff21..7ced9cb52 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