31
31
import org .springframework .data .mapping .PropertyHandler ;
32
32
import org .springframework .data .mapping .model .BasicPersistentEntity ;
33
33
import org .springframework .data .mapping .model .PersistentPropertyAccessorFactory ;
34
+ import org .springframework .data .spel .EvaluationContextProvider ;
35
+ import org .springframework .data .spel .ExpressionDependencies ;
36
+ import org .springframework .data .util .Lazy ;
34
37
import org .springframework .data .util .TypeInformation ;
35
38
import org .springframework .expression .EvaluationContext ;
36
39
import org .springframework .expression .Expression ;
@@ -74,7 +77,10 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
74
77
private @ Nullable VersionType versionType ;
75
78
private boolean createIndexAndMapping ;
76
79
private final Map <String , ElasticsearchPersistentProperty > fieldNamePropertyCache = new ConcurrentHashMap <>();
80
+
81
+ private EvaluationContextProvider evaluationContextProvider = EvaluationContextProvider .DEFAULT ;;
77
82
private final ConcurrentHashMap <String , Expression > indexNameExpressions = new ConcurrentHashMap <>();
83
+ private final Lazy <EvaluationContext > indexNameEvaluationContext = Lazy .of (this ::getIndexNameEvaluationContext );
78
84
79
85
public SimpleElasticsearchPersistentEntity (TypeInformation <T > typeInformation ) {
80
86
@@ -302,12 +308,20 @@ public ElasticsearchPersistentProperty getSeqNoPrimaryTermProperty() {
302
308
return seqNoPrimaryTermProperty ;
303
309
}
304
310
311
+ @ Nullable
305
312
@ Override
306
313
public ElasticsearchPersistentProperty getJoinFieldProperty () {
307
314
return joinFieldProperty ;
308
315
}
309
316
310
317
// region SpEL handling
318
+
319
+ @ Override
320
+ public void setEvaluationContextProvider (EvaluationContextProvider provider ) {
321
+ super .setEvaluationContextProvider (provider );
322
+ this .evaluationContextProvider = provider ;
323
+ }
324
+
311
325
/**
312
326
* resolves all the names in the IndexCoordinates object. If a name cannot be resolved, the original name is returned.
313
327
*
@@ -316,14 +330,12 @@ public ElasticsearchPersistentProperty getJoinFieldProperty() {
316
330
*/
317
331
private IndexCoordinates resolve (IndexCoordinates indexCoordinates ) {
318
332
319
- EvaluationContext context = getEvaluationContext (null );
320
-
321
333
String [] indexNames = indexCoordinates .getIndexNames ();
322
334
String [] resolvedNames = new String [indexNames .length ];
323
335
324
336
for (int i = 0 ; i < indexNames .length ; i ++) {
325
337
String indexName = indexNames [i ];
326
- resolvedNames [i ] = resolve (context , indexName );
338
+ resolvedNames [i ] = resolve (indexName );
327
339
}
328
340
329
341
return IndexCoordinates .of (resolvedNames );
@@ -332,22 +344,49 @@ private IndexCoordinates resolve(IndexCoordinates indexCoordinates) {
332
344
/**
333
345
* tries to resolve the given name. If this is not successful, the original value is returned
334
346
*
335
- * @param context SpEL evaluation context
336
347
* @param name name to resolve
337
348
* @return the resolved name or the input name if it cannot be resolved
338
349
*/
339
- private String resolve (EvaluationContext context , String name ) {
350
+ private String resolve (String name ) {
340
351
341
352
Assert .notNull (name , "name must not be null" );
342
353
343
- Expression expression = indexNameExpressions .computeIfAbsent (name , s -> {
344
- Expression expr = PARSER .parseExpression (name , ParserContext .TEMPLATE_EXPRESSION );
354
+ Expression expression = getExpressionForIndexName (name );
355
+
356
+ String resolvedName = expression != null ? expression .getValue (indexNameEvaluationContext .get (), String .class ) : null ;
357
+ return resolvedName != null ? resolvedName : name ;
358
+ }
359
+
360
+ /**
361
+ * returns an {@link Expression} for #name if name contains a {@link ParserContext#TEMPLATE_EXPRESSION} otherwise
362
+ * returns {@literal null}.
363
+ *
364
+ * @param name the name to get the expression for
365
+ * @return Expression may be null
366
+ */
367
+ @ Nullable
368
+ private Expression getExpressionForIndexName (String name ) {
369
+ return indexNameExpressions .computeIfAbsent (name , s -> {
370
+ Expression expr = PARSER .parseExpression (s , ParserContext .TEMPLATE_EXPRESSION );
345
371
return expr instanceof LiteralExpression ? null : expr ;
346
372
});
373
+ }
347
374
348
- String resolvedName = expression != null ? expression .getValue (context , String .class ) : null ;
349
- return resolvedName != null ? resolvedName : name ;
375
+ /**
376
+ * build the {@link EvaluationContext} considering {@link ExpressionDependencies} from the name returned by
377
+ * {@link #getIndexName()}.
378
+ *
379
+ * @return EvaluationContext
380
+ */
381
+ private EvaluationContext getIndexNameEvaluationContext () {
382
+
383
+ Expression expression = getExpressionForIndexName (getIndexName ());
384
+ ExpressionDependencies expressionDependencies = expression != null ? ExpressionDependencies .discover (expression )
385
+ : ExpressionDependencies .none ();
386
+
387
+ return evaluationContextProvider .getEvaluationContext (null , expressionDependencies );
350
388
}
389
+
351
390
// endregion
352
391
353
392
@ Override
@@ -363,5 +402,4 @@ public Document getDefaultSettings() {
363
402
.put ("index.refresh_interval" , getRefreshInterval ()).put ("index.store.type" , getIndexStoreType ()).map ();
364
403
return Document .from (map );
365
404
}
366
-
367
405
}
0 commit comments