From e92b6b0295eb1f06ed0f98b6ce943cfcd6f8efe6 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 20 Nov 2024 11:21:09 +0100 Subject: [PATCH] Adopt to deprecation removals in Commons. Closes #2007 --- .../convert/MappingCouchbaseConverter.java | 67 ++++++---- .../couchbase/core/query/StringQuery.java | 28 ++-- .../query/AbstractCouchbaseQuery.java | 13 +- .../query/AbstractCouchbaseQueryBase.java | 17 +-- .../query/AbstractReactiveCouchbaseQuery.java | 12 +- .../query/CouchbaseRepositoryQuery.java | 8 +- .../query/N1qlRepositoryQueryExecutor.java | 12 +- .../query/PartTreeCouchbaseQuery.java | 11 +- .../query/ReactiveCouchbaseQueryMethod.java | 9 +- .../ReactiveCouchbaseRepositoryQuery.java | 11 +- .../ReactiveN1qlRepositoryQueryExecutor.java | 15 +-- .../query/ReactivePartTreeCouchbaseQuery.java | 10 +- .../ReactiveStringBasedCouchbaseQuery.java | 24 ++-- .../query/StringBasedCouchbaseQuery.java | 22 ++-- .../query/StringBasedN1qlQueryParser.java | 122 +++++++++--------- .../query/StringN1qlQueryCreator.java | 19 ++- .../support/CouchbaseRepositoryFactory.java | 23 ++-- .../ReactiveCouchbaseRepositoryFactory.java | 20 +-- .../data/couchbase/domain/Airline.java | 4 +- .../couchbase/domain/AirlineCollectioned.java | 5 +- .../data/couchbase/domain/Airport.java | 4 +- .../couchbase/domain/AirportJsonValue.java | 4 +- .../data/couchbase/domain/AirportMini.java | 12 +- .../data/couchbase/domain/BigAirline.java | 4 +- .../data/couchbase/domain/OtherUser.java | 4 +- .../data/couchbase/domain/TestEncrypted.java | 14 -- .../data/couchbase/domain/User.java | 9 +- .../data/couchbase/domain/UserAnnotated.java | 9 -- .../data/couchbase/domain/UserCol.java | 4 +- .../data/couchbase/domain/UserEncrypted.java | 4 +- .../couchbase/domain/UserJustLastName.java | 4 +- .../data/couchbase/domain/UserNoAlias.java | 4 +- ...tringN1qlQueryCreatorIntegrationTests.java | 12 +- .../query/StringN1qlQueryCreatorTests.java | 18 ++- 34 files changed, 252 insertions(+), 306 deletions(-) diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java b/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java index c5afb887..83b932f4 100644 --- a/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java +++ b/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java @@ -16,8 +16,7 @@ package org.springframework.data.couchbase.core.convert; -import static org.springframework.data.couchbase.core.mapping.id.GenerationStrategy.UNIQUE; -import static org.springframework.data.couchbase.core.mapping.id.GenerationStrategy.USE_ATTRIBUTES; +import static org.springframework.data.couchbase.core.mapping.id.GenerationStrategy.*; import java.beans.Transient; import java.lang.reflect.InaccessibleObjectException; @@ -34,10 +33,14 @@ import java.util.UUID; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.context.EnvironmentAware; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.support.DefaultConversionService; +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.convert.PropertyValueConverter; import org.springframework.data.couchbase.core.mapping.CouchbaseDocument; @@ -62,16 +65,17 @@ import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.callback.EntityCallbacks; 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.DefaultSpELExpressionEvaluator; import org.springframework.data.mapping.model.EntityInstantiator; 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.SpELExpressionEvaluator; -import org.springframework.data.mapping.model.SpELExpressionParameterValueProvider; +import org.springframework.data.mapping.model.ValueExpressionEvaluator; +import org.springframework.data.mapping.model.ValueExpressionParameterValueProvider; import org.springframework.data.util.TypeInformation; +import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -92,7 +96,7 @@ import com.couchbase.client.java.json.JsonObject; * @author Remi Bleuse * @author Vipul Gupta */ -public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implements ApplicationContextAware { +public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implements ApplicationContextAware, EnvironmentCapable, EnvironmentAware { /** * The default "type key", the name of the field that will hold type information. @@ -113,6 +117,10 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem * Spring Expression Language context. */ private final SpELContext spELContext; + + private final SpelExpressionParser expressionParser = new SpelExpressionParser(); + + private final CachingValueExpressionEvaluatorFactory expressionEvaluatorFactory; /** * The overall application context. */ @@ -127,6 +135,8 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem */ private @Nullable EntityCallbacks entityCallbacks; + private @Nullable Environment environment; + public MappingCouchbaseConverter() { this(new CouchbaseMappingContext(), null); } @@ -173,6 +183,9 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem ((CouchbaseMappingContext) mappingContext).setSimpleTypeHolder(customConversions.getSimpleTypeHolder()); typeMapper = new DefaultCouchbaseTypeMapper(typeKey != null ? typeKey : TYPEKEY_DEFAULT); spELContext = new SpELContext(CouchbaseDocumentPropertyAccessor.INSTANCE); + + expressionEvaluatorFactory = new CachingValueExpressionEvaluatorFactory( + expressionParser, this, o -> spELContext.getEvaluationContext(o)); } /** @@ -200,6 +213,21 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem return left.isAssignableFrom(right) && !left.equals(right); } + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + @Override + public Environment getEnvironment() { + + if (this.environment == null) { + this.environment = new StandardEnvironment(); + } + + return environment; + } + @Override public MappingContext, CouchbasePersistentProperty> getMappingContext() { return mappingContext; @@ -273,7 +301,8 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem * @return the converted entity. */ protected R read(final CouchbasePersistentEntity entity, final CouchbaseDocument source, final Object parent) { - final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(source, spELContext); + + ValueExpressionEvaluator evaluator = expressionEvaluatorFactory.create(source); ParameterValueProvider provider = getParameterProvider(entity, source, evaluator, parent); EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity); @@ -284,7 +313,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem entity.doWithProperties(new PropertyHandler<>() { @Override public void doWithPersistentProperty(final CouchbasePersistentProperty prop) { - if (!doesPropertyExistInSource(prop) || entity.isConstructorArgument(prop) || isIdConstructionProperty(prop) + if (!doesPropertyExistInSource(prop) || entity.isCreatorArgument(prop) || isIdConstructionProperty(prop) || prop.isAnnotationPresent(N1qlJoin.class)) { return; } @@ -330,7 +359,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem */ protected Object getValueInternal(final CouchbasePersistentProperty property, final CouchbaseDocument source, final Object parent, PersistentEntity entity) { - return new CouchbasePropertyValueProvider(source, spELContext, parent, entity).getPropertyValue(property); + return new CouchbasePropertyValueProvider(source, expressionEvaluatorFactory.create(source), parent, entity).getPropertyValue(property); } /** @@ -344,7 +373,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem */ private ParameterValueProvider getParameterProvider( final CouchbasePersistentEntity entity, final CouchbaseDocument source, - final DefaultSpELExpressionEvaluator evaluator, final Object parent) { + final ValueExpressionEvaluator evaluator, final Object parent) { CouchbasePropertyValueProvider provider = new CouchbasePropertyValueProvider(source, evaluator, parent, entity); PersistentEntityParameterValueProvider parameterProvider = new PersistentEntityParameterValueProvider<>( entity, provider, parent); @@ -1070,7 +1099,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem /** * The expression evaluator. */ - private final SpELExpressionEvaluator evaluator; + private final ValueExpressionEvaluator evaluator; /** * The optional parent object. @@ -1082,15 +1111,10 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem */ private final PersistentEntity entity; - public CouchbasePropertyValueProvider(final CouchbaseDocument source, final SpELContext factory, - final Object parent, final PersistentEntity entity) { - this(source, new DefaultSpELExpressionEvaluator(source, factory), parent, entity); - } - public CouchbasePropertyValueProvider(final CouchbaseDocument source, - final DefaultSpELExpressionEvaluator evaluator, final Object parent, final PersistentEntity entity) { + final ValueExpressionEvaluator evaluator, final Object parent, final PersistentEntity entity) { Assert.notNull(source, "CouchbaseDocument must not be null!"); - Assert.notNull(evaluator, "DefaultSpELExpressionEvaluator must not be null!"); + Assert.notNull(evaluator, "ValueExpressionEvaluator must not be null!"); this.source = source; this.evaluator = evaluator; @@ -1148,11 +1172,11 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem * A expression parameter value provider. */ private class ConverterAwareSpELExpressionParameterValueProvider - extends SpELExpressionParameterValueProvider { + extends ValueExpressionParameterValueProvider { private final Object parent; - public ConverterAwareSpELExpressionParameterValueProvider(final SpELExpressionEvaluator evaluator, + public ConverterAwareSpELExpressionParameterValueProvider(final ValueExpressionEvaluator evaluator, final ConversionService conversionService, final ParameterValueProvider delegate, final Object parent) { super(evaluator, conversionService, delegate); @@ -1160,8 +1184,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem } @Override - protected T potentiallyConvertSpelValue(final Object object, - final Parameter parameter) { + protected T potentiallyConvertExpressionValue(Object object, Parameter parameter) { return readValue(object, parameter.getType(), parent); } } diff --git a/src/main/java/org/springframework/data/couchbase/core/query/StringQuery.java b/src/main/java/org/springframework/data/couchbase/core/query/StringQuery.java index 96d7c53b..43eb4692 100644 --- a/src/main/java/org/springframework/data/couchbase/core/query/StringQuery.java +++ b/src/main/java/org/springframework/data/couchbase/core/query/StringQuery.java @@ -25,9 +25,8 @@ import org.springframework.data.couchbase.repository.query.StringBasedN1qlQueryP import org.springframework.data.couchbase.repository.support.MappingCouchbaseEntityInformation; import org.springframework.data.mapping.Alias; import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.util.TypeInformation; -import org.springframework.expression.spel.standard.SpelExpressionParser; import com.couchbase.client.java.json.JsonArray; import com.couchbase.client.java.json.JsonObject; @@ -35,37 +34,34 @@ import com.couchbase.client.java.json.JsonValue; /** * Query created from the string in @Query annotation in the repository interface. - * + * *
  * @Query("#{#n1ql.selectEntity} where #{#n1ql.filter} and firstname = $1 and lastname = $2")
  * List<User> getByFirstnameAndLastname(String firstname, String lastname);
  * 
- * + * * It must include the SELECT ... FROM ... preferably via the #n1ql expression, in addition to any predicates required, * including the n1ql.filter (for _class = className) - * + * * @author Michael Reiche */ public class StringQuery extends Query { private final CouchbaseQueryMethod queryMethod; private final String inlineN1qlQuery; - private final QueryMethodEvaluationContextProvider evaluationContextProvider; + private final ValueExpressionDelegate valueExpressionDelegate; private final ParameterAccessor parameterAccessor; - private final SpelExpressionParser spelExpressionParser; public StringQuery(CouchbaseQueryMethod queryMethod, String n1qlString, - QueryMethodEvaluationContextProvider queryMethodEvaluationContextProvider, ParameterAccessor parameterAccessor, - SpelExpressionParser spelExpressionParser) { + ValueExpressionDelegate valueExpressionDelegate, ParameterAccessor parameterAccessor) { this.queryMethod = queryMethod; this.inlineN1qlQuery = n1qlString; - this.evaluationContextProvider = queryMethodEvaluationContextProvider; + this.valueExpressionDelegate = valueExpressionDelegate; this.parameterAccessor = parameterAccessor; - this.spelExpressionParser = spelExpressionParser; } public StringQuery(String n1qlString) { - this(null,n1qlString, null, null, null); + this(null,n1qlString, null, null); } @Override @@ -75,8 +71,7 @@ public class StringQuery extends Query { StringBasedN1qlQueryParser parser = getStringN1qlQueryParser(converter, bucketName, scope, collection, domainClass, distinctFields, fields); - N1QLExpression parsedExpression = parser.getExpression(inlineN1qlQuery, queryMethod, parameterAccessor, - spelExpressionParser, evaluationContextProvider); + N1QLExpression parsedExpression = parser.getExpression(inlineN1qlQuery, queryMethod, parameterAccessor, valueExpressionDelegate); String queryString = parsedExpression.toString(); @@ -128,8 +123,7 @@ public class StringQuery extends Query { } // there are no options for distinct and fields for @Query StringBasedN1qlQueryParser sbnqp = new StringBasedN1qlQueryParser(inlineN1qlQuery, queryMethod, bucketName, - scopeName, collectionName, converter, typeKey, typeValue, parameterAccessor, new SpelExpressionParser(), - evaluationContextProvider); + scopeName, collectionName, converter, typeKey, typeValue, parameterAccessor, valueExpressionDelegate); return sbnqp; } @@ -144,7 +138,7 @@ public class StringQuery extends Query { /** * toN1qlRemoveString - use toN1qlSelectString - * + * * @param converter * @param bucketName * @param scopeName diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/AbstractCouchbaseQuery.java b/src/main/java/org/springframework/data/couchbase/repository/query/AbstractCouchbaseQuery.java index 2a6deb4e..ddf3ca7a 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/AbstractCouchbaseQuery.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/AbstractCouchbaseQuery.java @@ -27,10 +27,9 @@ import org.springframework.data.couchbase.repository.query.CouchbaseQueryExecuti import org.springframework.data.repository.core.EntityMetadata; import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ResultProcessor; -import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -52,16 +51,14 @@ public abstract class AbstractCouchbaseQuery extends AbstractCouchbaseQueryBase< * * @param method must not be {@literal null}. * @param operations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. + * @param valueExpressionDelegate must not be {@literal null}. */ public AbstractCouchbaseQuery(CouchbaseQueryMethod method, CouchbaseOperations operations, - SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) { - super(method, operations, expressionParser, evaluationContextProvider); + ValueExpressionDelegate valueExpressionDelegate) { + super(method, operations, valueExpressionDelegate); Assert.notNull(method, "CouchbaseQueryMethod must not be null!"); Assert.notNull(operations, "ReactiveCouchbaseOperations must not be null!"); - Assert.notNull(expressionParser, "SpelExpressionParser must not be null!"); - Assert.notNull(evaluationContextProvider, "QueryMethodEvaluationContextProvider must not be null!"); + Assert.notNull(valueExpressionDelegate, "QueryMethodEvaluationContextProvider must not be null!"); EntityMetadata metadata = method.getEntityInformation(); Class type = metadata.getJavaType(); this.findOp = (ExecutableFindByQuery) (operations.findByQuery(type).inScope(method.getScope()) diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/AbstractCouchbaseQueryBase.java b/src/main/java/org/springframework/data/couchbase/repository/query/AbstractCouchbaseQueryBase.java index 5baa9b4c..df2cadd8 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/AbstractCouchbaseQueryBase.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/AbstractCouchbaseQueryBase.java @@ -26,11 +26,10 @@ import org.springframework.data.mapping.model.EntityInstantiators; import org.springframework.data.repository.core.EntityMetadata; import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ResultProcessor; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.util.TypeInformation; -import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -47,8 +46,7 @@ public abstract class AbstractCouchbaseQueryBase implem private final CouchbaseOperationsType operations; private final EntityInstantiators instantiators; private final ExecutableFindByQuery findOperationWithProjection; - private final SpelExpressionParser expressionParser; - private final QueryMethodEvaluationContextProvider evaluationContextProvider; + private final ValueExpressionDelegate valueExpressionDelegate; /** * Creates a new {@link AbstractCouchbaseQuery} from the given {@link ReactiveCouchbaseQueryMethod} and @@ -56,22 +54,19 @@ public abstract class AbstractCouchbaseQueryBase implem * * @param method must not be {@literal null}. * @param operations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. + * @param valueExpressionDelegate must not be {@literal null}. */ public AbstractCouchbaseQueryBase(CouchbaseQueryMethod method, CouchbaseOperationsType operations, - SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) { + ValueExpressionDelegate valueExpressionDelegate) { Assert.notNull(method, "CouchbaseQueryMethod must not be null!"); Assert.notNull(operations, "ReactiveCouchbaseOperations must not be null!"); - Assert.notNull(expressionParser, "SpelExpressionParser must not be null!"); - Assert.notNull(evaluationContextProvider, "QueryMethodEvaluationContextProvider must not be null!"); + Assert.notNull(valueExpressionDelegate, "ValueExpressionDelegate must not be null!"); this.method = method; this.operations = operations; this.instantiators = new EntityInstantiators(); - this.expressionParser = expressionParser; - this.evaluationContextProvider = evaluationContextProvider; + this.valueExpressionDelegate = valueExpressionDelegate; EntityMetadata metadata = method.getEntityInformation(); Class type = metadata.getJavaType(); diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/AbstractReactiveCouchbaseQuery.java b/src/main/java/org/springframework/data/couchbase/repository/query/AbstractReactiveCouchbaseQuery.java index 2e7e3264..4476b442 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/AbstractReactiveCouchbaseQuery.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/AbstractReactiveCouchbaseQuery.java @@ -26,10 +26,9 @@ import org.springframework.data.couchbase.repository.query.ReactiveCouchbaseQuer import org.springframework.data.repository.core.EntityMetadata; import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ResultProcessor; -import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -51,16 +50,13 @@ public abstract class AbstractReactiveCouchbaseQuery extends AbstractCouchbaseQu * * @param method must not be {@literal null}. * @param operations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. + * @param valueExpressionDelegate must not be {@literal null}. */ public AbstractReactiveCouchbaseQuery(ReactiveCouchbaseQueryMethod method, ReactiveCouchbaseOperations operations, - SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) { - super(method, operations, expressionParser, evaluationContextProvider); + ValueExpressionDelegate valueExpressionDelegate) { + super(method, operations, valueExpressionDelegate); Assert.notNull(method, "CouchbaseQueryMethod must not be null!"); Assert.notNull(operations, "ReactiveCouchbaseOperations must not be null!"); - Assert.notNull(expressionParser, "SpelExpressionParser must not be null!"); - Assert.notNull(evaluationContextProvider, "QueryMethodEvaluationContextProvider must not be null!"); EntityMetadata metadata = method.getEntityInformation(); Class type = metadata.getJavaType(); diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/CouchbaseRepositoryQuery.java b/src/main/java/org/springframework/data/couchbase/repository/query/CouchbaseRepositoryQuery.java index 065ded5b..ae6a6e0d 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/CouchbaseRepositoryQuery.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/CouchbaseRepositoryQuery.java @@ -18,8 +18,8 @@ package org.springframework.data.couchbase.repository.query; import org.springframework.data.couchbase.core.CouchbaseOperations; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; +import org.springframework.data.repository.query.ValueExpressionDelegate; /** * @author Michael Nitschinger @@ -32,19 +32,19 @@ public class CouchbaseRepositoryQuery implements RepositoryQuery { private final CouchbaseOperations operations; private final CouchbaseQueryMethod queryMethod; private final NamedQueries namedQueries; - private final QueryMethodEvaluationContextProvider evaluationContextProvider; + private final ValueExpressionDelegate valueExpressionDelegate; public CouchbaseRepositoryQuery(final CouchbaseOperations operations, final CouchbaseQueryMethod queryMethod, final NamedQueries namedQueries) { this.operations = operations; this.queryMethod = queryMethod; this.namedQueries = namedQueries; - this.evaluationContextProvider = QueryMethodEvaluationContextProvider.DEFAULT; + this.valueExpressionDelegate = ValueExpressionDelegate.create(); } @Override public Object execute(final Object[] parameters) { - return new N1qlRepositoryQueryExecutor(operations, queryMethod, namedQueries, evaluationContextProvider) + return new N1qlRepositoryQueryExecutor(operations, queryMethod, namedQueries, valueExpressionDelegate) .execute(parameters); } diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/N1qlRepositoryQueryExecutor.java b/src/main/java/org/springframework/data/couchbase/repository/query/N1qlRepositoryQueryExecutor.java index 1d477a1c..50f24c33 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/N1qlRepositoryQueryExecutor.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/N1qlRepositoryQueryExecutor.java @@ -22,7 +22,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.repository.query.parser.PartTree; import org.springframework.expression.spel.standard.SpelExpressionParser; @@ -39,14 +39,14 @@ public class N1qlRepositoryQueryExecutor { private final CouchbaseOperations operations; private final CouchbaseQueryMethod queryMethod; private final NamedQueries namedQueries; - private final QueryMethodEvaluationContextProvider evaluationContextProvider; + private final ValueExpressionDelegate valueExpressionDelegate; public N1qlRepositoryQueryExecutor(final CouchbaseOperations operations, final CouchbaseQueryMethod queryMethod, - final NamedQueries namedQueries, final QueryMethodEvaluationContextProvider evaluationContextProvider) { + final NamedQueries namedQueries, final ValueExpressionDelegate valueExpressionDelegate) { this.operations = operations; this.queryMethod = queryMethod; this.namedQueries = namedQueries; - this.evaluationContextProvider = evaluationContextProvider; + this.valueExpressionDelegate = valueExpressionDelegate; } private static final SpelExpressionParser SPEL_PARSER = new SpelExpressionParser(); @@ -69,8 +69,8 @@ public class N1qlRepositoryQueryExecutor { Query query; ExecutableFindByQuery q; if (queryMethod.hasN1qlAnnotation()) { - query = new StringN1qlQueryCreator(accessor, queryMethod, operations.getConverter(), SPEL_PARSER, - evaluationContextProvider, namedQueries).createQuery(); + query = new StringN1qlQueryCreator(accessor, queryMethod, operations.getConverter(), + valueExpressionDelegate, namedQueries).createQuery(); } else { final PartTree tree = new PartTree(queryMethod.getName(), domainClass); query = new N1qlQueryCreator(tree, accessor, queryMethod, operations.getConverter(), operations.getBucketName()) diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/PartTreeCouchbaseQuery.java b/src/main/java/org/springframework/data/couchbase/repository/query/PartTreeCouchbaseQuery.java index fa0e96e7..ebe972cc 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/PartTreeCouchbaseQuery.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/PartTreeCouchbaseQuery.java @@ -21,11 +21,10 @@ import org.springframework.data.couchbase.core.convert.CouchbaseConverter; import org.springframework.data.couchbase.core.query.Query; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ResultProcessor; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.expression.spel.standard.SpelExpressionParser; /** * {@link RepositoryQuery} implementation for Couchbase. Replaces PartTreeN1qlBasedQuery @@ -43,13 +42,11 @@ public class PartTreeCouchbaseQuery extends AbstractCouchbaseQuery { * * @param method must not be {@literal null}. * @param operations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. + * @param valueExpressionDelegate must not be {@literal null}. */ - public PartTreeCouchbaseQuery(CouchbaseQueryMethod method, CouchbaseOperations operations, - SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) { + public PartTreeCouchbaseQuery(CouchbaseQueryMethod method, CouchbaseOperations operations, ValueExpressionDelegate valueExpressionDelegate) { - super(method, operations, expressionParser, evaluationContextProvider); + super(method, operations, valueExpressionDelegate); ResultProcessor processor = method.getResultProcessor(); this.tree = new CouchbasePartTree(method.getName(), processor.getReturnedType().getDomainType()); diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseQueryMethod.java b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseQueryMethod.java index 9c24e637..846e0b4f 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseQueryMethod.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseQueryMethod.java @@ -15,8 +15,6 @@ */ package org.springframework.data.couchbase.repository.query; -import static org.springframework.data.repository.util.ClassUtils.hasParameterOfType; - import java.lang.reflect.Method; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -29,8 +27,9 @@ import org.springframework.data.domain.Sort; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.util.ReactiveWrappers; import org.springframework.data.util.Lazy; +import org.springframework.data.util.ReactiveWrappers; +import org.springframework.data.util.ReflectionUtils; import org.springframework.data.util.TypeInformation; import org.springframework.util.ClassUtils; @@ -60,7 +59,7 @@ public class ReactiveCouchbaseQueryMethod extends CouchbaseQueryMethod { super(method, metadata, projectionFactory, mappingContext); - if (hasParameterOfType(method, Pageable.class)) { + if (ReflectionUtils.hasParameterOfType(method, Pageable.class)) { TypeInformation returnType = TypeInformation.fromReturnTypeOf(method); @@ -81,7 +80,7 @@ public class ReactiveCouchbaseQueryMethod extends CouchbaseQueryMethod { method.toString())); } - if (hasParameterOfType(method, Sort.class)) { + if (ReflectionUtils.hasParameterOfType(method, Sort.class)) { throw new IllegalStateException(String.format("Method must not have Pageable *and* Sort parameter. " + "Use sorting capabilities on Pageable instead! Offending method: %s", method.toString())); } diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseRepositoryQuery.java b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseRepositoryQuery.java index ccc3319b..3a4987a6 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseRepositoryQuery.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseRepositoryQuery.java @@ -19,8 +19,7 @@ import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations; import org.springframework.data.couchbase.core.query.Query; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.data.repository.query.ValueExpressionDelegate; /** * @author Michael Nitschinger @@ -33,20 +32,20 @@ public class ReactiveCouchbaseRepositoryQuery extends AbstractReactiveCouchbaseQ private final ReactiveCouchbaseOperations operations; private final ReactiveCouchbaseQueryMethod queryMethod; private final NamedQueries namedQueries; - private final QueryMethodEvaluationContextProvider evaluationContextProvider; + private final ValueExpressionDelegate valueExpressionDelegate; public ReactiveCouchbaseRepositoryQuery(final ReactiveCouchbaseOperations operations, final ReactiveCouchbaseQueryMethod queryMethod, final NamedQueries namedQueries) { - super(queryMethod, operations, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT); + super(queryMethod, operations, ValueExpressionDelegate.create()); this.operations = operations; this.queryMethod = queryMethod; this.namedQueries = namedQueries; - this.evaluationContextProvider = QueryMethodEvaluationContextProvider.DEFAULT; + this.valueExpressionDelegate = ValueExpressionDelegate.create(); } @Override public Object execute(final Object[] parameters) { - return new ReactiveN1qlRepositoryQueryExecutor(operations, queryMethod, namedQueries, evaluationContextProvider) + return new ReactiveN1qlRepositoryQueryExecutor(operations, queryMethod, namedQueries, valueExpressionDelegate) .execute(parameters); } diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveN1qlRepositoryQueryExecutor.java b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveN1qlRepositoryQueryExecutor.java index eb186be2..3a70ea20 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveN1qlRepositoryQueryExecutor.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveN1qlRepositoryQueryExecutor.java @@ -17,8 +17,7 @@ package org.springframework.data.couchbase.repository.query; import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations; import org.springframework.data.repository.core.NamedQueries; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.data.repository.query.ValueExpressionDelegate; /** * @author Michael Nitschinger @@ -31,15 +30,15 @@ public class ReactiveN1qlRepositoryQueryExecutor { private final ReactiveCouchbaseOperations operations; private final ReactiveCouchbaseQueryMethod queryMethod; private final NamedQueries namedQueries; - private final QueryMethodEvaluationContextProvider evaluationContextProvider; + private final ValueExpressionDelegate valueExpressionDelegate; public ReactiveN1qlRepositoryQueryExecutor(final ReactiveCouchbaseOperations operations, final ReactiveCouchbaseQueryMethod queryMethod, final NamedQueries namedQueries, - QueryMethodEvaluationContextProvider evaluationContextProvider) { + ValueExpressionDelegate valueExpressionDelegate) { this.operations = operations; this.queryMethod = queryMethod; this.namedQueries = namedQueries; - this.evaluationContextProvider = evaluationContextProvider; + this.valueExpressionDelegate = valueExpressionDelegate; } /** @@ -52,11 +51,9 @@ public class ReactiveN1qlRepositoryQueryExecutor { // counterpart to N1qlRespositoryQueryExecutor, if (queryMethod.hasN1qlAnnotation()) { - return new ReactiveStringBasedCouchbaseQuery(queryMethod, operations, new SpelExpressionParser(), - evaluationContextProvider, namedQueries).execute(parameters); + return new ReactiveStringBasedCouchbaseQuery(queryMethod, operations, valueExpressionDelegate, namedQueries).execute(parameters); } else { - return new ReactivePartTreeCouchbaseQuery(queryMethod, operations, new SpelExpressionParser(), - evaluationContextProvider).execute(parameters); + return new ReactivePartTreeCouchbaseQuery(queryMethod, operations, valueExpressionDelegate).execute(parameters); } } diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/ReactivePartTreeCouchbaseQuery.java b/src/main/java/org/springframework/data/couchbase/repository/query/ReactivePartTreeCouchbaseQuery.java index e84dc3c3..4e545719 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/ReactivePartTreeCouchbaseQuery.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/ReactivePartTreeCouchbaseQuery.java @@ -23,10 +23,9 @@ import org.springframework.data.couchbase.core.convert.CouchbaseConverter; import org.springframework.data.couchbase.core.query.Query; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.expression.spel.standard.SpelExpressionParser; /** * Reactive PartTree {@link RepositoryQuery} implementation for Couchbase. Replaces ReactivePartN1qlBasedQuery @@ -46,13 +45,12 @@ public class ReactivePartTreeCouchbaseQuery extends AbstractReactiveCouchbaseQue * * @param method must not be {@literal null}. * @param operations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. + * @param valueExpressionDelegate must not be {@literal null}. */ public ReactivePartTreeCouchbaseQuery(ReactiveCouchbaseQueryMethod method, ReactiveCouchbaseOperations operations, - SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) { + ValueExpressionDelegate valueExpressionDelegate) { - super(method, operations, expressionParser, evaluationContextProvider); + super(method, operations, valueExpressionDelegate); this.tree = new PartTree(method.getName(), method.getResultProcessor().getReturnedType().getDomainType()); this.converter = operations.getConverter(); } diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveStringBasedCouchbaseQuery.java b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveStringBasedCouchbaseQuery.java index c1e93b4d..5fd56696 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveStringBasedCouchbaseQuery.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/ReactiveStringBasedCouchbaseQuery.java @@ -21,9 +21,7 @@ import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations; import org.springframework.data.couchbase.core.query.Query; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.util.Assert; +import org.springframework.data.repository.query.ValueExpressionDelegate; /** * Query to use a plain JSON String to create the {@link Query} to actually execute. @@ -36,30 +34,24 @@ public class ReactiveStringBasedCouchbaseQuery extends AbstractReactiveCouchbase private static final String COUNT_EXISTS_AND_DELETE = "Manually defined query for %s cannot be a count and exists or delete query at the same time!"; private static final Logger LOG = LoggerFactory.getLogger(ReactiveStringBasedCouchbaseQuery.class); - private final SpelExpressionParser expressionParser; - private final QueryMethodEvaluationContextProvider evaluationContextProvider; + private final ValueExpressionDelegate valueExpressionDelegate; private final NamedQueries namedQueries; /** * Creates a new {@link ReactiveStringBasedCouchbaseQuery} for the given {@link String}, {@link CouchbaseQueryMethod}, - * {@link ReactiveCouchbaseOperations}, {@link SpelExpressionParser} and {@link QueryMethodEvaluationContextProvider}. + * {@link ReactiveCouchbaseOperations}, and {@link ValueExpressionDelegate}. * * @param method must not be {@literal null}. * @param couchbaseOperations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. + * @param valueExpressionDelegate must not be {@literal null}. * @param namedQueries must not be {@literal null}. */ public ReactiveStringBasedCouchbaseQuery(ReactiveCouchbaseQueryMethod method, - ReactiveCouchbaseOperations couchbaseOperations, SpelExpressionParser expressionParser, - QueryMethodEvaluationContextProvider evaluationContextProvider, NamedQueries namedQueries) { + ReactiveCouchbaseOperations couchbaseOperations, ValueExpressionDelegate valueExpressionDelegate, NamedQueries namedQueries) { - super(method, couchbaseOperations, expressionParser, evaluationContextProvider); + super(method, couchbaseOperations, valueExpressionDelegate); - Assert.notNull(expressionParser, "SpelExpressionParser must not be null!"); - - this.expressionParser = expressionParser; - this.evaluationContextProvider = evaluationContextProvider; + this.valueExpressionDelegate = valueExpressionDelegate; if (hasAmbiguousProjectionFlags(isCountQuery(), isExistsQuery(), isDeleteQuery())) { throw new IllegalArgumentException(String.format(COUNT_EXISTS_AND_DELETE, method)); @@ -77,7 +69,7 @@ public class ReactiveStringBasedCouchbaseQuery extends AbstractReactiveCouchbase protected Query createQuery(ParametersParameterAccessor accessor) { StringN1qlQueryCreator creator = new StringN1qlQueryCreator(accessor, getQueryMethod(), - getOperations().getConverter(), expressionParser, evaluationContextProvider, namedQueries); + getOperations().getConverter(), valueExpressionDelegate, namedQueries); Query query = creator.createQuery(); diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/StringBasedCouchbaseQuery.java b/src/main/java/org/springframework/data/couchbase/repository/query/StringBasedCouchbaseQuery.java index ee4c3be8..82fdd86f 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/StringBasedCouchbaseQuery.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/StringBasedCouchbaseQuery.java @@ -21,9 +21,8 @@ import org.springframework.data.couchbase.core.CouchbaseOperations; import org.springframework.data.couchbase.core.query.Query; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.util.Assert; /** * Query to use a plain JSON String to create the {@link Query} to actually execute. @@ -36,30 +35,25 @@ public class StringBasedCouchbaseQuery extends AbstractCouchbaseQuery { private static final String COUNT_EXISTS_AND_DELETE = "Manually defined query for %s cannot be a count and exists or delete query at the same time!"; private static final Logger LOG = LoggerFactory.getLogger(StringBasedCouchbaseQuery.class); - private final SpelExpressionParser expressionParser; - private final QueryMethodEvaluationContextProvider evaluationContextProvider; + private final ValueExpressionDelegate valueExpressionDelegate; private final NamedQueries namedQueries; /** * Creates a new {@link StringBasedCouchbaseQuery} for the given {@link String}, {@link CouchbaseQueryMethod}, - * {@link CouchbaseOperations}, {@link SpelExpressionParser} and {@link QueryMethodEvaluationContextProvider}. + * {@link CouchbaseOperations}, {@link SpelExpressionParser} and {@link ValueExpressionDelegate}. * * @param method must not be {@literal null}. * @param couchbaseOperations must not be {@literal null}. - * @param expressionParser must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. + * @param valueExpressionDelegate must not be {@literal null}. * @param namedQueries must not be {@literal null}. */ public StringBasedCouchbaseQuery(CouchbaseQueryMethod method, CouchbaseOperations couchbaseOperations, - SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider, + ValueExpressionDelegate valueExpressionDelegate, NamedQueries namedQueries) { - super(method, couchbaseOperations, expressionParser, evaluationContextProvider); + super(method, couchbaseOperations, valueExpressionDelegate); - Assert.notNull(expressionParser, "SpelExpressionParser must not be null!"); - - this.expressionParser = expressionParser; - this.evaluationContextProvider = evaluationContextProvider; + this.valueExpressionDelegate = valueExpressionDelegate; if (hasAmbiguousProjectionFlags(isCountQuery(), isExistsQuery(), isDeleteQuery())) { throw new IllegalArgumentException(String.format(COUNT_EXISTS_AND_DELETE, method)); @@ -75,7 +69,7 @@ public class StringBasedCouchbaseQuery extends AbstractCouchbaseQuery { protected Query createQuery(ParametersParameterAccessor accessor) { StringN1qlQueryCreator creator = new StringN1qlQueryCreator(accessor, getQueryMethod(), - getOperations().getConverter(), expressionParser, evaluationContextProvider, namedQueries); + getOperations().getConverter(), valueExpressionDelegate, namedQueries); Query query = creator.createQuery(); if (LOG.isTraceEnabled()) { diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/StringBasedN1qlQueryParser.java b/src/main/java/org/springframework/data/couchbase/repository/query/StringBasedN1qlQueryParser.java index 8d820b3b..6e21c8ea 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/StringBasedN1qlQueryParser.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/StringBasedN1qlQueryParser.java @@ -15,11 +15,8 @@ */ package org.springframework.data.couchbase.repository.query; -import static org.springframework.data.couchbase.core.query.N1QLExpression.i; -import static org.springframework.data.couchbase.core.query.N1QLExpression.s; -import static org.springframework.data.couchbase.core.query.N1QLExpression.x; -import static org.springframework.data.couchbase.core.support.TemplateUtils.SELECT_CAS; -import static org.springframework.data.couchbase.core.support.TemplateUtils.SELECT_ID; +import static org.springframework.data.couchbase.core.query.N1QLExpression.*; +import static org.springframework.data.couchbase.core.support.TemplateUtils.*; import java.lang.reflect.Modifier; import java.util.ArrayList; @@ -33,6 +30,7 @@ import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.data.couchbase.core.convert.CouchbaseConverter; import org.springframework.data.couchbase.core.mapping.CouchbaseDocument; import org.springframework.data.couchbase.core.mapping.CouchbaseList; @@ -42,15 +40,17 @@ import org.springframework.data.couchbase.core.query.N1QLExpression; import org.springframework.data.couchbase.core.query.StringQuery; import org.springframework.data.couchbase.repository.Query; import org.springframework.data.couchbase.repository.query.support.N1qlUtils; +import org.springframework.data.expression.ValueEvaluationContext; +import org.springframework.data.expression.ValueExpression; +import org.springframework.data.expression.ValueExpressionParser; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.expression.EvaluationContext; -import org.springframework.expression.common.TemplateParserContext; -import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.util.Assert; import com.couchbase.client.core.error.CouchbaseException; @@ -156,21 +156,18 @@ public class StringBasedN1qlQueryParser { * @param typeField * @param typeValue * @param accessor - * @param spelExpressionParser - * @param evaluationContextProvider + * @param valueExpressionDelegate */ public StringBasedN1qlQueryParser(String statement, CouchbaseQueryMethod queryMethod, String bucketName, String scope, String collection, CouchbaseConverter couchbaseConverter, String typeField, String typeValue, - ParameterAccessor accessor, SpelExpressionParser spelExpressionParser, - QueryMethodEvaluationContextProvider evaluationContextProvider) { + ParameterAccessor accessor, ValueExpressionDelegate valueExpressionDelegate) { this.statement = statement; this.queryMethod = queryMethod; this.couchbaseConverter = couchbaseConverter; this.statementContext = queryMethod == null ? null - : createN1qlSpelValues(bucketName, scope, collection, - queryMethod.getEntityInformation().getJavaType(), typeField, typeValue, queryMethod.isCountQuery(), null, null); - this.parsedExpression = getExpression(statement, queryMethod, accessor, spelExpressionParser, - evaluationContextProvider); + : createN1qlSpelValues(bucketName, scope, collection, queryMethod.getEntityInformation().getJavaType(), + typeField, typeValue, queryMethod.isCountQuery(), null, null); + this.parsedExpression = getExpression(statement, queryMethod, accessor, valueExpressionDelegate); } /** @@ -201,22 +198,22 @@ public class StringBasedN1qlQueryParser { } /** - * Create the n1ql spel values. The domainClass is needed, but not the returnClass. Mapping the domainClass to the - * returnClass is the responsibility of decoding. - * - * @param bucketName - * @param scope - * @param collection - * @param domainClass - * @param typeKey - * @param typeValue - * @param isCount - * @param distinctFields - * @param fields - * @return - */ + * Create the n1ql spel values. The domainClass is needed, but not the returnClass. Mapping the domainClass to the + * returnClass is the responsibility of decoding. + * + * @param bucketName + * @param scope + * @param collection + * @param domainClass + * @param typeKey + * @param typeValue + * @param isCount + * @param distinctFields + * @param fields + * @return + */ public N1qlSpelValues createN1qlSpelValues(String bucketName, String scope, String collection, Class domainClass, - String typeKey, String typeValue, boolean isCount, String[] distinctFields, String[] fields) { + String typeKey, String typeValue, boolean isCount, String[] distinctFields, String[] fields) { String b = bucketName; String keyspace = collection != null ? collection : bucketName; Assert.isTrue(!(distinctFields != null && fields != null), @@ -224,7 +221,7 @@ public class StringBasedN1qlQueryParser { String entityFields = ""; String selectEntity; if (distinctFields != null) { - String distinctFieldsStr = getProjectedOrDistinctFields(b, domainClass, typeKey, fields, distinctFields); + String distinctFieldsStr = getProjectedOrDistinctFields(b, domainClass, typeKey, fields, distinctFields); if (isCount) { selectEntity = N1QLExpression.select(N1QLExpression.count(N1QLExpression.distinct(x(distinctFieldsStr))) .as(i(CountFragment.COUNT_ALIAS)).from(keyspace)).toString(); @@ -235,12 +232,11 @@ public class StringBasedN1qlQueryParser { selectEntity = N1QLExpression.select(N1QLExpression.count(x("\"*\"")).as(i(CountFragment.COUNT_ALIAS))) .from(keyspace).toString(); } else { - String projectedFields = getProjectedOrDistinctFields(keyspace, domainClass, typeKey, fields, - distinctFields); + String projectedFields = getProjectedOrDistinctFields(keyspace, domainClass, typeKey, fields, distinctFields); entityFields = projectedFields; selectEntity = N1QLExpression.select(x(projectedFields)).from(keyspace).toString(); } - String typeSelection = !empty(typeKey) && !empty(typeValue) ? i(typeKey).eq(s(typeValue)).toString() : null; + String typeSelection = !empty(typeKey) && !empty(typeValue) ? i(typeKey).eq(s(typeValue)).toString() : null; String delete = N1QLExpression.delete().from(keyspace).toString(); String returning = " returning " + N1qlUtils.createReturningExpressionForDelete(keyspace); @@ -249,9 +245,9 @@ public class StringBasedN1qlQueryParser { i(collection).toString(), typeSelection, delete, returning); } - private static boolean empty(String s) { - return s == null || s.length() == 0; - } + private static boolean empty(String s) { + return s == null || s.length() == 0; + } private String getProjectedOrDistinctFields(String b, Class resultClass, String typeField, String[] fields, String[] distinctFields) { @@ -373,12 +369,16 @@ public class StringBasedN1qlQueryParser { // this static method can be used to test the parsing behavior for Couchbase specific spel variables // in isolation from the rest of the spel parser initialization chain. - public static String doParse(String statement, SpelExpressionParser parser, EvaluationContext evaluationContext, - N1qlSpelValues n1qlSpelValues) { - org.springframework.expression.Expression parsedExpression = parser.parseExpression(statement, - new TemplateParserContext()); - evaluationContext.setVariable(SPEL_PREFIX, n1qlSpelValues); - return parsedExpression.getValue(evaluationContext, String.class); + public static String doParse(String statement, ValueExpressionParser parser, + ValueEvaluationContext valueEvaluationContext, N1qlSpelValues n1qlSpelValues) { + ValueExpression parsedExpression = parser.parse(statement); + + EvaluationContext evaluationContext = valueEvaluationContext.getRequiredEvaluationContext(); + if (evaluationContext instanceof StandardEvaluationContext ctx) { + ctx.setVariable(SPEL_PREFIX, n1qlSpelValues); + } + Object result = parsedExpression.evaluate(valueEvaluationContext); + return result != null ? result.toString() : null; } private void checkPlaceholders(String statement) { @@ -386,9 +386,8 @@ public class StringBasedN1qlQueryParser { Matcher quoteMatcher = QUOTE_DETECTION_PATTERN.matcher(statement); Matcher positionMatcher = POSITIONAL_PLACEHOLDER_PATTERN.matcher(statement); Matcher namedMatcher = NAMED_PLACEHOLDER_PATTERN.matcher(statement); - String queryIdentifier = (this.queryMethod != null ? queryMethod.getClass().getName() - : StringQuery.class.getName()) + "." - + (this.queryMethod != null ? queryMethod.getName() : this.statement); + String queryIdentifier = (this.queryMethod != null ? queryMethod.getClass().getName() : StringQuery.class.getName()) + + "." + (this.queryMethod != null ? queryMethod.getName() : this.statement); List quotes = new ArrayList(); while (quoteMatcher.find()) { @@ -404,8 +403,7 @@ public class StringBasedN1qlQueryParser { if (checkNotQuoted(placeholder, positionMatcher.start(), positionMatcher.end(), quotes, queryIdentifier)) { if (this.queryMethod == null) { throw new IllegalArgumentException( - "StringQuery created from StringQuery(String) cannot have parameters. " - + "They cannot be processed. " + "StringQuery created from StringQuery(String) cannot have parameters. " + "They cannot be processed. " + "Use an @Query annotated method and the SPEL Expression #{[]} : " + statement); } LOGGER.trace("{}: Found positional placeholder {}", queryIdentifier, placeholder); @@ -419,9 +417,8 @@ public class StringBasedN1qlQueryParser { // check not in quoted if (checkNotQuoted(placeholder, namedMatcher.start(), namedMatcher.end(), quotes, queryIdentifier)) { if (this.queryMethod == null) { - throw new IllegalArgumentException( - "StringQuery created from StringQuery(String) cannot have parameters. " - + "Use an @Query annotated method and the SPEL Expression #{[]} : " + statement); + throw new IllegalArgumentException("StringQuery created from StringQuery(String) cannot have parameters. " + + "Use an @Query annotated method and the SPEL Expression #{[]} : " + statement); } LOGGER.trace("{}: Found named placeholder {}", queryIdentifier, placeholder); namedCount++; @@ -449,10 +446,8 @@ public class StringBasedN1qlQueryParser { // check not in quoted if (checkNotQuoted(placeholder, spelMatcher.start(), spelMatcher.end(), quotes, queryIdentifier)) { if (this.queryMethod == null) { - throw new IllegalArgumentException( - "StringQuery created from StringQuery(String) cannot SPEL expressions. " - + "Use an @Query annotated method and the SPEL Expression #{[]} : " - + statement); + throw new IllegalArgumentException("StringQuery created from StringQuery(String) cannot SPEL expressions. " + + "Use an @Query annotated method and the SPEL Expression #{[]} : " + statement); } LOGGER.trace("{}: Found SPEL Experssion {}", queryIdentifier, placeholder); } @@ -686,19 +681,18 @@ public class StringBasedN1qlQueryParser { * @param statement * @param queryMethod * @param accessor - * @param parser - * @param evaluationContextProvider + * @param valueExpressionDelegate * @return */ public N1QLExpression getExpression(String statement, CouchbaseQueryMethod queryMethod, ParameterAccessor accessor, - SpelExpressionParser parser, QueryMethodEvaluationContextProvider evaluationContextProvider) { + ValueExpressionDelegate valueExpressionDelegate) { N1QLExpression parsedStatement; - if (accessor != null && queryMethod != null && parser != null) { + if (accessor != null && queryMethod != null) { Object[] runtimeParameters = getParameters(accessor); - EvaluationContext evaluationContext = evaluationContextProvider - .getEvaluationContext(queryMethod.getParameters(), runtimeParameters); - parsedStatement = x(doParse(statement, parser, evaluationContext, this.getStatementContext())); + ValueEvaluationContext evaluationContext = valueExpressionDelegate + .createValueContextProvider(queryMethod.getParameters()).getEvaluationContext(runtimeParameters); + parsedStatement = x(doParse(statement, valueExpressionDelegate, evaluationContext, this.getStatementContext())); } else { parsedStatement = x(statement); } @@ -711,7 +705,7 @@ public class StringBasedN1qlQueryParser { for (Object o : accessor) { params.add(o); } - if( accessor.getPageable().isPaged()) { + if (accessor.getPageable().isPaged()) { params.add(accessor.getPageable()); } else if (accessor.getSort().isSorted()) { params.add(accessor.getSort()); diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreator.java b/src/main/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreator.java index 7aab0ff1..6838ea13 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreator.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreator.java @@ -15,8 +15,8 @@ */ package org.springframework.data.couchbase.repository.query; -import static org.springframework.data.couchbase.core.query.N1QLExpression.x; -import static org.springframework.data.couchbase.core.query.QueryCriteria.where; +import static org.springframework.data.couchbase.core.query.N1QLExpression.*; +import static org.springframework.data.couchbase.core.query.QueryCriteria.*; import java.util.Iterator; import java.util.Optional; @@ -33,11 +33,10 @@ import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.data.repository.query.parser.AbstractQueryCreator; import org.springframework.data.repository.query.parser.Part; import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.expression.spel.standard.SpelExpressionParser; /** * @author Michael Reiche @@ -48,15 +47,14 @@ public class StringN1qlQueryCreator extends AbstractQueryCreator context; - private final QueryMethodEvaluationContextProvider evaluationContextProvider; + private final ValueExpressionDelegate valueExpressionDelegate; private final CouchbaseQueryMethod queryMethod; private final CouchbaseConverter couchbaseConverter; private final String queryString; - private final SpelExpressionParser spelExpressionParser; public StringN1qlQueryCreator(final ParameterAccessor accessor, CouchbaseQueryMethod queryMethod, - CouchbaseConverter couchbaseConverter, SpelExpressionParser spelExpressionParser, - QueryMethodEvaluationContextProvider evaluationContextProvider, NamedQueries namedQueries) { + CouchbaseConverter couchbaseConverter, + ValueExpressionDelegate valueExpressionDelegate, NamedQueries namedQueries) { // AbstractQueryCreator needs a PartTree, so we give it a dummy one. // The resulting dummy criteria will not be included in the Query @@ -68,8 +66,7 @@ public class StringN1qlQueryCreator extends AbstractQueryCreator getQueryLookupStrategy(QueryLookupStrategy.Key key, - QueryMethodEvaluationContextProvider contextProvider) { - return Optional.of(new CouchbaseQueryLookupStrategy(contextProvider)); + ValueExpressionDelegate valueExpressionDelegate) { + return Optional.of(new CouchbaseQueryLookupStrategy(valueExpressionDelegate)); } /** @@ -151,10 +152,10 @@ public class CouchbaseRepositoryFactory extends RepositoryFactorySupport { */ private class CouchbaseQueryLookupStrategy implements QueryLookupStrategy { - private final QueryMethodEvaluationContextProvider evaluationContextProvider; + private final ValueExpressionDelegate valueExpressionDelegate; - public CouchbaseQueryLookupStrategy(QueryMethodEvaluationContextProvider evaluationContextProvider) { - this.evaluationContextProvider = evaluationContextProvider; + public CouchbaseQueryLookupStrategy(ValueExpressionDelegate valueExpressionDelegate) { + this.valueExpressionDelegate = new CachingValueExpressionDelegate(valueExpressionDelegate); } @Override @@ -166,11 +167,11 @@ public class CouchbaseRepositoryFactory extends RepositoryFactorySupport { CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method, metadata, factory, mappingContext); if (queryMethod.hasN1qlAnnotation()) { - return new StringBasedCouchbaseQuery(queryMethod, couchbaseOperations, new SpelExpressionParser(), - evaluationContextProvider, namedQueries); + return new StringBasedCouchbaseQuery(queryMethod, couchbaseOperations, + valueExpressionDelegate, namedQueries); } else { - return new PartTreeCouchbaseQuery(queryMethod, couchbaseOperations, new SpelExpressionParser(), - evaluationContextProvider); + return new PartTreeCouchbaseQuery(queryMethod, couchbaseOperations, + valueExpressionDelegate); } } } diff --git a/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactory.java b/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactory.java index 667e9608..2f8f98ad 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactory.java +++ b/src/main/java/org/springframework/data/couchbase/repository/support/ReactiveCouchbaseRepositoryFactory.java @@ -34,8 +34,8 @@ import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.ReactiveRepositoryFactorySupport; import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.util.Assert; @@ -132,8 +132,8 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor @Override protected Optional getQueryLookupStrategy(QueryLookupStrategy.Key key, - QueryMethodEvaluationContextProvider contextProvider) { - return Optional.of(new ReactiveCouchbaseRepositoryFactory.CouchbaseQueryLookupStrategy(contextProvider)); + ValueExpressionDelegate valueExpressionDelegate) { + return Optional.of(new ReactiveCouchbaseRepositoryFactory.CouchbaseQueryLookupStrategy(valueExpressionDelegate)); } /** @@ -141,10 +141,10 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor */ private class CouchbaseQueryLookupStrategy implements QueryLookupStrategy { - private final QueryMethodEvaluationContextProvider evaluationContextProvider; + private final ValueExpressionDelegate valueExpressionDelegate; - public CouchbaseQueryLookupStrategy(QueryMethodEvaluationContextProvider evaluationContextProvider) { - this.evaluationContextProvider = evaluationContextProvider; + public CouchbaseQueryLookupStrategy(ValueExpressionDelegate valueExpressionDelegate) { + this.valueExpressionDelegate = valueExpressionDelegate; } @Override @@ -156,11 +156,11 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor mappingContext); if (queryMethod.hasN1qlAnnotation()) { - return new ReactiveStringBasedCouchbaseQuery(queryMethod, couchbaseOperations, new SpelExpressionParser(), - evaluationContextProvider, namedQueries); + return new ReactiveStringBasedCouchbaseQuery(queryMethod, couchbaseOperations, + valueExpressionDelegate, namedQueries); } else { - return new ReactivePartTreeCouchbaseQuery(queryMethod, couchbaseOperations, new SpelExpressionParser(), - evaluationContextProvider); + return new ReactivePartTreeCouchbaseQuery(queryMethod, couchbaseOperations, + valueExpressionDelegate); } } } diff --git a/src/test/java/org/springframework/data/couchbase/domain/Airline.java b/src/test/java/org/springframework/data/couchbase/domain/Airline.java index bbe1210f..64032a74 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/Airline.java +++ b/src/test/java/org/springframework/data/couchbase/domain/Airline.java @@ -16,7 +16,7 @@ package org.springframework.data.couchbase.domain; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.couchbase.core.index.CompositeQueryIndex; import org.springframework.data.couchbase.core.index.QueryIndexed; import org.springframework.data.couchbase.core.mapping.Document; @@ -34,7 +34,7 @@ public class Airline extends ComparableEntity { String hqCountry; - @PersistenceConstructor + @PersistenceCreator public Airline(String id, String name, String hqCountry) { this.id = id; this.name = name; diff --git a/src/test/java/org/springframework/data/couchbase/domain/AirlineCollectioned.java b/src/test/java/org/springframework/data/couchbase/domain/AirlineCollectioned.java index af84ba42..5848fecd 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/AirlineCollectioned.java +++ b/src/test/java/org/springframework/data/couchbase/domain/AirlineCollectioned.java @@ -16,8 +16,7 @@ package org.springframework.data.couchbase.domain; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; -import org.springframework.data.couchbase.core.index.CompositeQueryIndex; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.couchbase.core.index.QueryIndexed; import org.springframework.data.couchbase.core.mapping.Document; import org.springframework.data.couchbase.repository.Collection; @@ -34,7 +33,7 @@ public class AirlineCollectioned extends ComparableEntity { String hqCountry; - @PersistenceConstructor + @PersistenceCreator public AirlineCollectioned(String id, String name, String hqCountry) { this.id = id; this.name = name; diff --git a/src/test/java/org/springframework/data/couchbase/domain/Airport.java b/src/test/java/org/springframework/data/couchbase/domain/Airport.java index 9bad65f5..7e06af6e 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/Airport.java +++ b/src/test/java/org/springframework/data/couchbase/domain/Airport.java @@ -20,7 +20,7 @@ import jakarta.validation.constraints.Max; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.annotation.Version; import org.springframework.data.couchbase.core.mapping.Document; @@ -59,7 +59,7 @@ public class Airport extends ComparableEntity { public Airport() {} - @PersistenceConstructor + @PersistenceCreator public Airport(String key, String iata, String icao) { this.key = key; this.iata = iata; diff --git a/src/test/java/org/springframework/data/couchbase/domain/AirportJsonValue.java b/src/test/java/org/springframework/data/couchbase/domain/AirportJsonValue.java index b1978142..cc9a6883 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/AirportJsonValue.java +++ b/src/test/java/org/springframework/data/couchbase/domain/AirportJsonValue.java @@ -20,7 +20,7 @@ import jakarta.validation.constraints.Max; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.annotation.Version; import org.springframework.data.couchbase.core.mapping.Document; @@ -61,7 +61,7 @@ public class AirportJsonValue extends ComparableEntity { public AirportJsonValue() {} - @PersistenceConstructor + @PersistenceCreator public AirportJsonValue(String key, String iata, String icao) { this.key = key; this.iata = iata; diff --git a/src/test/java/org/springframework/data/couchbase/domain/AirportMini.java b/src/test/java/org/springframework/data/couchbase/domain/AirportMini.java index f85d5d8f..ad655592 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/AirportMini.java +++ b/src/test/java/org/springframework/data/couchbase/domain/AirportMini.java @@ -19,7 +19,7 @@ package org.springframework.data.couchbase.domain; import java.util.Objects; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.couchbase.core.mapping.Document; /** @@ -34,11 +34,11 @@ public class AirportMini extends ComparableEntity { private String iata; private Address address; - @PersistenceConstructor - public AirportMini(final String id, final String iata) { - this.id = id; - this.iata = iata; - } + @PersistenceCreator + public AirportMini(final String id, final String iata) { + this.id = id; + this.iata = iata; + } public String getId() { return id; diff --git a/src/test/java/org/springframework/data/couchbase/domain/BigAirline.java b/src/test/java/org/springframework/data/couchbase/domain/BigAirline.java index a8599299..f54d640e 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/BigAirline.java +++ b/src/test/java/org/springframework/data/couchbase/domain/BigAirline.java @@ -18,7 +18,7 @@ package org.springframework.data.couchbase.domain; import java.math.BigDecimal; import java.math.BigInteger; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.couchbase.core.mapping.Document; @Document @@ -29,7 +29,7 @@ public class BigAirline extends Airline { BigInteger airlineNumber = new BigInteger("88881234567890123456"); // less than 63 bits, otherwise query truncates BigDecimal airlineDecimal = new BigDecimal("888812345678901.23"); // less than 53 bits in mantissa - @PersistenceConstructor + @PersistenceCreator public BigAirline(String id, String name, String hqCountry, Number airlineNumber, Number airlineDecimal) { super(id, name, hqCountry); this.airlineNumber = airlineNumber != null && !airlineNumber.equals("") diff --git a/src/test/java/org/springframework/data/couchbase/domain/OtherUser.java b/src/test/java/org/springframework/data/couchbase/domain/OtherUser.java index e8181978..1a1f8025 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/OtherUser.java +++ b/src/test/java/org/springframework/data/couchbase/domain/OtherUser.java @@ -16,7 +16,7 @@ package org.springframework.data.couchbase.domain; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.couchbase.core.mapping.Document; @@ -30,7 +30,7 @@ import org.springframework.data.couchbase.core.mapping.Document; @TypeAlias(AbstractingTypeMapper.Type.ABSTRACTUSER) public class OtherUser extends AbstractUser { - @PersistenceConstructor + @PersistenceCreator public OtherUser(final String id, final String firstname, final String lastname) { this.id = id; this.firstname = firstname; diff --git a/src/test/java/org/springframework/data/couchbase/domain/TestEncrypted.java b/src/test/java/org/springframework/data/couchbase/domain/TestEncrypted.java index 01ea6869..2b6c45a6 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/TestEncrypted.java +++ b/src/test/java/org/springframework/data/couchbase/domain/TestEncrypted.java @@ -17,25 +17,11 @@ package org.springframework.data.couchbase.domain; import java.io.Serializable; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Locale; import java.util.Objects; -import java.util.UUID; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.springframework.data.annotation.PersistenceConstructor; -import org.springframework.data.annotation.TypeAlias; -import org.springframework.data.annotation.Version; import org.springframework.data.couchbase.core.mapping.Document; import com.couchbase.client.java.encryption.annotation.Encrypted; -import com.couchbase.client.java.query.QueryScanConsistency; /** * UserEncrypted entity for tests diff --git a/src/test/java/org/springframework/data/couchbase/domain/User.java b/src/test/java/org/springframework/data/couchbase/domain/User.java index 0d6cd712..853e51a5 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/User.java +++ b/src/test/java/org/springframework/data/couchbase/domain/User.java @@ -21,19 +21,18 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; -import com.couchbase.client.java.json.JsonArray; -import com.couchbase.client.java.json.JsonObject; -import com.couchbase.client.java.json.JsonValue; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.annotation.Version; import org.springframework.data.couchbase.core.mapping.Document; +import com.couchbase.client.java.json.JsonArray; +import com.couchbase.client.java.json.JsonObject; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -53,7 +52,7 @@ public class User extends AbstractUser implements Serializable { public JsonObject jsonObject; public JsonArray jsonArray; - @PersistenceConstructor + @PersistenceCreator public User(final String id, final String firstname, final String lastname) { this.id = id; this.firstname = firstname; diff --git a/src/test/java/org/springframework/data/couchbase/domain/UserAnnotated.java b/src/test/java/org/springframework/data/couchbase/domain/UserAnnotated.java index 05ea6e17..316380a6 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/UserAnnotated.java +++ b/src/test/java/org/springframework/data/couchbase/domain/UserAnnotated.java @@ -16,15 +16,6 @@ package org.springframework.data.couchbase.domain; -import java.util.Objects; - -import org.springframework.data.annotation.CreatedBy; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.LastModifiedBy; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.annotation.PersistenceConstructor; -import org.springframework.data.annotation.Version; import org.springframework.data.couchbase.core.mapping.Document; /** diff --git a/src/test/java/org/springframework/data/couchbase/domain/UserCol.java b/src/test/java/org/springframework/data/couchbase/domain/UserCol.java index 6c9a22ff..3ed2b7e1 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/UserCol.java +++ b/src/test/java/org/springframework/data/couchbase/domain/UserCol.java @@ -16,7 +16,7 @@ package org.springframework.data.couchbase.domain; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.couchbase.core.mapping.Document; import org.springframework.data.couchbase.repository.Collection; import org.springframework.data.couchbase.repository.Scope; @@ -33,7 +33,7 @@ import org.springframework.data.couchbase.repository.Scope; @Collection("other_collection") public class UserCol extends User { - @PersistenceConstructor + @PersistenceCreator public UserCol(final String id, final String firstname, final String lastname) { super(id, firstname, lastname); } diff --git a/src/test/java/org/springframework/data/couchbase/domain/UserEncrypted.java b/src/test/java/org/springframework/data/couchbase/domain/UserEncrypted.java index 1dd67cdb..fd45e45b 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/UserEncrypted.java +++ b/src/test/java/org/springframework/data/couchbase/domain/UserEncrypted.java @@ -29,7 +29,7 @@ import java.util.UUID; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.annotation.Version; import org.springframework.data.couchbase.core.mapping.Document; @@ -55,7 +55,7 @@ public class UserEncrypted extends AbstractUser implements Serializable { public String _class; // cheat a little so that will work with Java SDK - @PersistenceConstructor + @PersistenceCreator public UserEncrypted(final String id, final String firstname, final String lastname) { this(); this.id = id; diff --git a/src/test/java/org/springframework/data/couchbase/domain/UserJustLastName.java b/src/test/java/org/springframework/data/couchbase/domain/UserJustLastName.java index 65a9068b..dffc6926 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/UserJustLastName.java +++ b/src/test/java/org/springframework/data/couchbase/domain/UserJustLastName.java @@ -19,7 +19,7 @@ package org.springframework.data.couchbase.domain; import java.util.Objects; import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.couchbase.core.mapping.Document; /** @@ -37,7 +37,7 @@ public class UserJustLastName extends ComparableEntity { public User user; - @PersistenceConstructor + @PersistenceCreator public UserJustLastName(final String id, final String lastname) { this.id = id; this.lastname = lastname; diff --git a/src/test/java/org/springframework/data/couchbase/domain/UserNoAlias.java b/src/test/java/org/springframework/data/couchbase/domain/UserNoAlias.java index 24d0571c..d868dc8b 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/UserNoAlias.java +++ b/src/test/java/org/springframework/data/couchbase/domain/UserNoAlias.java @@ -25,7 +25,7 @@ import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.annotation.Version; @@ -52,7 +52,7 @@ public class UserNoAlias extends AbstractUser implements Serializable { public JsonObject jsonObject; public JsonArray jsonArray; - @PersistenceConstructor + @PersistenceCreator public UserNoAlias(final String id, final String firstname, final String lastname) { this.id = id; this.firstname = firstname; diff --git a/src/test/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreatorIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreatorIntegrationTests.java index ef772296..37a0b02d 100644 --- a/src/test/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreatorIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreatorIntegrationTests.java @@ -15,7 +15,7 @@ */ package org.springframework.data.couchbase.repository.query; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; import java.lang.reflect.Method; import java.util.Optional; @@ -23,6 +23,7 @@ import java.util.Properties; import java.util.UUID; import org.junit.jupiter.api.Test; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.couchbase.core.CouchbaseTemplate; import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation.ExecutableFindByQuery; @@ -31,8 +32,8 @@ import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty; import org.springframework.data.couchbase.core.query.Query; import org.springframework.data.couchbase.domain.Airline; -import org.springframework.data.couchbase.domain.Config; import org.springframework.data.couchbase.domain.AirlineRepository; +import org.springframework.data.couchbase.domain.Config; import org.springframework.data.couchbase.util.Capabilities; import org.springframework.data.couchbase.util.ClusterAwareIntegrationTests; import org.springframework.data.couchbase.util.ClusterType; @@ -47,8 +48,7 @@ import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.ParametersSource; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.data.repository.query.ValueExpressionDelegate; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; @@ -83,7 +83,7 @@ class StringN1qlQueryCreatorIntegrationTests extends ClusterAwareIntegrationTest converter.getMappingContext()); StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Continental"), - queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, + queryMethod, converter, ValueExpressionDelegate.create(), namedQueries); Query query = creator.createQuery(); @@ -116,7 +116,7 @@ class StringN1qlQueryCreatorIntegrationTests extends ClusterAwareIntegrationTest converter.getMappingContext()); StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Continental"), - queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, + queryMethod, converter, ValueExpressionDelegate.create(), namedQueries); Query query = creator.createQuery(); diff --git a/src/test/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreatorTests.java b/src/test/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreatorTests.java index d0935888..0d1b5fff 100644 --- a/src/test/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreatorTests.java +++ b/src/test/java/org/springframework/data/couchbase/repository/query/StringN1qlQueryCreatorTests.java @@ -15,15 +15,14 @@ */ package org.springframework.data.couchbase.repository.query; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.*; import java.lang.reflect.Method; import java.util.Properties; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; + import org.springframework.data.couchbase.core.convert.CouchbaseConverter; import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter; import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext; @@ -43,8 +42,7 @@ import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.ParametersSource; -import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; -import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.data.repository.query.ValueExpressionDelegate; /** * @author Michael Nitschinger @@ -73,7 +71,7 @@ class StringN1qlQueryCreatorTests { try { StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver"), - queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, + queryMethod, converter, ValueExpressionDelegate.create(), namedQueries); } catch (IllegalArgumentException e) { return; @@ -91,7 +89,7 @@ class StringN1qlQueryCreatorTests { try { StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver"), - queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, + queryMethod, converter, ValueExpressionDelegate.create(), namedQueries); } catch (IllegalArgumentException e) { return; @@ -109,7 +107,7 @@ class StringN1qlQueryCreatorTests { converter.getMappingContext()); StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver", "Twist"), - queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, namedQueries); + queryMethod, converter, ValueExpressionDelegate.create(), namedQueries); Query query = creator.createQuery(); assertEquals( @@ -130,7 +128,7 @@ class StringN1qlQueryCreatorTests { converter.getMappingContext()); StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver", "Twist"), - queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, namedQueries); + queryMethod, converter, ValueExpressionDelegate.create(), namedQueries); Query query = creator.createQuery(); assertEquals( @@ -203,7 +201,7 @@ class StringN1qlQueryCreatorTests { converter.getMappingContext()); StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method)), queryMethod, - converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, namedQueries); + converter, ValueExpressionDelegate.create(), namedQueries); Query query = creator.createQuery();