3333import org .springframework .data .projection .ProjectionFactory ;
3434import org .springframework .data .repository .query .Parameter ;
3535import org .springframework .data .repository .query .Parameters ;
36- import org .springframework .data .repository .query .QueryMethodEvaluationContextProvider ;
3736import org .springframework .data .repository .query .RepositoryQuery ;
38- import org .springframework .data .repository .query .SpelEvaluator ;
3937import org .springframework .data .repository .query .SpelQueryContext ;
40- import org .springframework .data .repository .query .SpelQueryContext .SpelExtractor ;
38+ import org .springframework .data .repository .query .ValueExpressionDelegate ;
39+ import org .springframework .data .repository .query .ValueExpressionQueryRewriter ;
4140import org .springframework .lang .Nullable ;
4241import org .springframework .util .Assert ;
4342import org .springframework .util .StringUtils ;
@@ -65,24 +64,22 @@ final class ReactiveStringBasedNeo4jQuery extends AbstractReactiveNeo4jQuery {
6564 static final SpelQueryContext SPEL_QUERY_CONTEXT = SpelQueryContext
6665 .of (ReactiveStringBasedNeo4jQuery ::parameterNameSource , ReactiveStringBasedNeo4jQuery ::replacementSource );
6766
68- /**
69- * Used to evaluate the expression found while parsing the cypher template of this query against the actual parameters
70- * with the help of the formal parameters during the building of the {@link PreparedQuery}.
71- */
72- private final SpelEvaluator spelEvaluator ;
67+ private final ValueExpressionQueryRewriter .EvaluatingValueExpressionQueryRewriter queryRewriter ;
68+
69+ private final ValueExpressionQueryRewriter .QueryExpressionEvaluator parsedQuery ;
7370
7471 /**
7572 * Create a {@link ReactiveStringBasedNeo4jQuery} for a query method that is annotated with {@link Query @Query}. The
7673 * annotation is expected to have a value.
7774 *
7875 * @param neo4jOperations reactive Neo4j operations
7976 * @param mappingContext a Neo4jMappingContext instance
80- * @param evaluationContextProvider a QueryMethodEvaluationContextProvider instance
77+ * @param delegate a ValueExpressionDelegate instance
8178 * @param queryMethod the query method
8279 * @return A new instance of a String based Neo4j query.
8380 */
8481 static ReactiveStringBasedNeo4jQuery create (ReactiveNeo4jOperations neo4jOperations ,
85- Neo4jMappingContext mappingContext , QueryMethodEvaluationContextProvider evaluationContextProvider ,
82+ Neo4jMappingContext mappingContext , ValueExpressionDelegate delegate ,
8683 Neo4jQueryMethod queryMethod , ProjectionFactory factory ) {
8784
8885 Query queryAnnotation = queryMethod .getQueryAnnotation ()
@@ -91,7 +88,7 @@ static ReactiveStringBasedNeo4jQuery create(ReactiveNeo4jOperations neo4jOperati
9188 String cypherTemplate = Optional .ofNullable (queryAnnotation .value ()).filter (StringUtils ::hasText )
9289 .orElseThrow (() -> new MappingException ("Expected @Query annotation to have a value, but it did not" ));
9390
94- return new ReactiveStringBasedNeo4jQuery (neo4jOperations , mappingContext , evaluationContextProvider , queryMethod ,
91+ return new ReactiveStringBasedNeo4jQuery (neo4jOperations , mappingContext , delegate , queryMethod ,
9592 cypherTemplate , Neo4jQueryType .fromDefinition (queryAnnotation ), factory );
9693 }
9794
@@ -100,30 +97,30 @@ static ReactiveStringBasedNeo4jQuery create(ReactiveNeo4jOperations neo4jOperati
10097 *
10198 * @param neo4jOperations reactive Neo4j operations
10299 * @param mappingContext a Neo4jMappingContext instance
103- * @param evaluationContextProvider a QueryMethodEvaluationContextProvider instance
100+ * @param delegate a ValueExpressionDelegate instance
104101 * @param queryMethod the query method
105102 * @param cypherTemplate The template to use.
106103 * @return A new instance of a String based Neo4j query.
107104 */
108105 static ReactiveStringBasedNeo4jQuery create (ReactiveNeo4jOperations neo4jOperations ,
109- Neo4jMappingContext mappingContext , QueryMethodEvaluationContextProvider evaluationContextProvider ,
106+ Neo4jMappingContext mappingContext , ValueExpressionDelegate delegate ,
110107 Neo4jQueryMethod queryMethod , String cypherTemplate , ProjectionFactory factory ) {
111108
112109 Assert .hasText (cypherTemplate , "Cannot create String based Neo4j query without a cypher template" );
113110
114- return new ReactiveStringBasedNeo4jQuery (neo4jOperations , mappingContext , evaluationContextProvider , queryMethod ,
111+ return new ReactiveStringBasedNeo4jQuery (neo4jOperations , mappingContext , delegate , queryMethod ,
115112 cypherTemplate , Neo4jQueryType .DEFAULT , factory );
116113 }
117114
118115 private ReactiveStringBasedNeo4jQuery (ReactiveNeo4jOperations neo4jOperations , Neo4jMappingContext mappingContext ,
119- QueryMethodEvaluationContextProvider evaluationContextProvider , Neo4jQueryMethod queryMethod ,
116+ ValueExpressionDelegate delegate , Neo4jQueryMethod queryMethod ,
120117 String cypherTemplate , Neo4jQueryType queryType , ProjectionFactory factory ) {
121118
122119 super (neo4jOperations , mappingContext , queryMethod , queryType , factory );
123120
124- cypherTemplate = Neo4jSpelSupport . renderQueryIfExpressionOrReturnQuery ( cypherTemplate , mappingContext , queryMethod . getEntityInformation (), SPEL_EXPRESSION_PARSER );
125- SpelExtractor spelExtractor = SPEL_QUERY_CONTEXT . parse ( cypherTemplate );
126- this .spelEvaluator = new SpelEvaluator ( evaluationContextProvider , queryMethod .getParameters (), spelExtractor );
121+ this . queryRewriter = ValueExpressionQueryRewriter . of ( delegate ,
122+ StringBasedNeo4jQuery :: parameterNameSource , StringBasedNeo4jQuery :: replacementSource );
123+ this .parsedQuery = queryRewriter . parse ( cypherTemplate , queryMethod .getParameters ());
127124 }
128125
129126 @ Override
@@ -134,7 +131,7 @@ protected <T extends Object> PreparedQuery<T> prepareQuery(Class<T> returnedType
134131 Map <String , Object > boundParameters = bindParameters (parameterAccessor );
135132 QueryContext queryContext = new QueryContext (
136133 queryMethod .getRepositoryName () + "." + queryMethod .getName (),
137- spelEvaluator .getQueryString (),
134+ parsedQuery .getQueryString (),
138135 boundParameters
139136 );
140137
@@ -153,7 +150,7 @@ Map<String, Object> bindParameters(Neo4jParameterAccessor parameterAccessor) {
153150 Map <String , Object > resolvedParameters = new HashMap <>();
154151
155152 // Values from the parameter accessor can only get converted after evaluation
156- for (Map .Entry <String , Object > evaluatedParam : spelEvaluator .evaluate (parameterAccessor .getValues ()).entrySet ()) {
153+ for (Map .Entry <String , Object > evaluatedParam : parsedQuery .evaluate (parameterAccessor .getValues ()).entrySet ()) {
157154 Object value = evaluatedParam .getValue ();
158155 if (!(evaluatedParam .getValue () instanceof Neo4jSpelSupport .LiteralReplacement )) {
159156 Neo4jQuerySupport .logParameterIfNull (evaluatedParam .getKey (), value );
0 commit comments