55
55
import java .util .HashMap ;
56
56
import java .util .List ;
57
57
import java .util .Map ;
58
+ import java .util .Set ;
59
+ import java .util .function .Function ;
58
60
59
61
/**
60
62
* Provides the infrastructure for Lucene expressions as a scripting language for Elasticsearch.
@@ -65,6 +67,41 @@ public class ExpressionScriptEngine implements ScriptEngine {
65
67
66
68
public static final String NAME = "expression" ;
67
69
70
+ private static Map <ScriptContext <?>, Function <Expression ,Object >> contexts = Map .of (
71
+ BucketAggregationScript .CONTEXT ,
72
+ ExpressionScriptEngine ::newBucketAggregationScriptFactory ,
73
+
74
+ BucketAggregationSelectorScript .CONTEXT ,
75
+ (Expression expr ) -> {
76
+ BucketAggregationScript .Factory factory = newBucketAggregationScriptFactory (expr );
77
+ BucketAggregationSelectorScript .Factory wrappedFactory = parameters -> new BucketAggregationSelectorScript (parameters ) {
78
+ @ Override
79
+ public boolean execute () {
80
+ return factory .newInstance (getParams ()).execute ().doubleValue () == 1.0 ;
81
+ }
82
+ };
83
+ return wrappedFactory ;
84
+ },
85
+
86
+ FilterScript .CONTEXT ,
87
+ (Expression expr ) -> (FilterScript .Factory ) (p , lookup ) -> newFilterScript (expr , lookup , p ),
88
+
89
+ ScoreScript .CONTEXT ,
90
+ (Expression expr ) -> (ScoreScript .Factory ) (p , lookup ) -> newScoreScript (expr , lookup , p ),
91
+
92
+ TermsSetQueryScript .CONTEXT ,
93
+ (Expression expr ) -> (TermsSetQueryScript .Factory ) (p , lookup ) -> newTermsSetQueryScript (expr , lookup , p ),
94
+
95
+ AggregationScript .CONTEXT ,
96
+ (Expression expr ) -> (AggregationScript .Factory ) (p , lookup ) -> newAggregationScript (expr , lookup , p ),
97
+
98
+ NumberSortScript .CONTEXT ,
99
+ (Expression expr ) -> (NumberSortScript .Factory ) (p , lookup ) -> newSortScript (expr , lookup , p ),
100
+
101
+ FieldScript .CONTEXT ,
102
+ (Expression expr ) -> (FieldScript .Factory ) (p , lookup ) -> newFieldScript (expr , lookup , p )
103
+ );
104
+
68
105
@ Override
69
106
public String getType () {
70
107
return NAME ;
@@ -102,37 +139,15 @@ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundE
102
139
}
103
140
}
104
141
});
105
- if (context .instanceClazz .equals (BucketAggregationScript .class )) {
106
- return context .factoryClazz .cast (newBucketAggregationScriptFactory (expr ));
107
- } else if (context .instanceClazz .equals (BucketAggregationSelectorScript .class )) {
108
- BucketAggregationScript .Factory factory = newBucketAggregationScriptFactory (expr );
109
- BucketAggregationSelectorScript .Factory wrappedFactory = parameters -> new BucketAggregationSelectorScript (parameters ) {
110
- @ Override
111
- public boolean execute () {
112
- return factory .newInstance (getParams ()).execute ().doubleValue () == 1.0 ;
113
- }
114
- };
115
- return context .factoryClazz .cast (wrappedFactory );
116
- } else if (context .instanceClazz .equals (FilterScript .class )) {
117
- FilterScript .Factory factory = (p , lookup ) -> newFilterScript (expr , lookup , p );
118
- return context .factoryClazz .cast (factory );
119
- } else if (context .instanceClazz .equals (ScoreScript .class )) {
120
- ScoreScript .Factory factory = (p , lookup ) -> newScoreScript (expr , lookup , p );
121
- return context .factoryClazz .cast (factory );
122
- } else if (context .instanceClazz .equals (TermsSetQueryScript .class )) {
123
- TermsSetQueryScript .Factory factory = (p , lookup ) -> newTermsSetQueryScript (expr , lookup , p );
124
- return context .factoryClazz .cast (factory );
125
- } else if (context .instanceClazz .equals (AggregationScript .class )) {
126
- AggregationScript .Factory factory = (p , lookup ) -> newAggregationScript (expr , lookup , p );
127
- return context .factoryClazz .cast (factory );
128
- } else if (context .instanceClazz .equals (NumberSortScript .class )) {
129
- NumberSortScript .Factory factory = (p , lookup ) -> newSortScript (expr , lookup , p );
130
- return context .factoryClazz .cast (factory );
131
- } else if (context .instanceClazz .equals (FieldScript .class )) {
132
- FieldScript .Factory factory = (p , lookup ) -> newFieldScript (expr , lookup , p );
133
- return context .factoryClazz .cast (factory );
142
+ if (contexts .containsKey (context ) == false ) {
143
+ throw new IllegalArgumentException ("expression engine does not know how to handle script context [" + context .name + "]" );
134
144
}
135
- throw new IllegalArgumentException ("expression engine does not know how to handle script context [" + context .name + "]" );
145
+ return context .factoryClazz .cast (contexts .get (context ).apply (expr ));
146
+ }
147
+
148
+ @ Override
149
+ public Set <ScriptContext <?>> getSupportedContexts () {
150
+ return contexts .keySet ();
136
151
}
137
152
138
153
private static BucketAggregationScript .Factory newBucketAggregationScriptFactory (Expression expr ) {
@@ -166,7 +181,7 @@ public Double execute() {
166
181
};
167
182
}
168
183
169
- private NumberSortScript .LeafFactory newSortScript (Expression expr , SearchLookup lookup , @ Nullable Map <String , Object > vars ) {
184
+ private static NumberSortScript .LeafFactory newSortScript (Expression expr , SearchLookup lookup , @ Nullable Map <String , Object > vars ) {
170
185
// NOTE: if we need to do anything complicated with bindings in the future, we can just extend Bindings,
171
186
// instead of complicating SimpleBindings (which should stay simple)
172
187
SimpleBindings bindings = new SimpleBindings ();
@@ -193,7 +208,7 @@ private NumberSortScript.LeafFactory newSortScript(Expression expr, SearchLookup
193
208
return new ExpressionNumberSortScript (expr , bindings , needsScores );
194
209
}
195
210
196
- private TermsSetQueryScript .LeafFactory newTermsSetQueryScript (Expression expr , SearchLookup lookup ,
211
+ private static TermsSetQueryScript .LeafFactory newTermsSetQueryScript (Expression expr , SearchLookup lookup ,
197
212
@ Nullable Map <String , Object > vars ) {
198
213
// NOTE: if we need to do anything complicated with bindings in the future, we can just extend Bindings,
199
214
// instead of complicating SimpleBindings (which should stay simple)
@@ -216,7 +231,7 @@ private TermsSetQueryScript.LeafFactory newTermsSetQueryScript(Expression expr,
216
231
return new ExpressionTermSetQueryScript (expr , bindings );
217
232
}
218
233
219
- private AggregationScript .LeafFactory newAggregationScript (Expression expr , SearchLookup lookup ,
234
+ private static AggregationScript .LeafFactory newAggregationScript (Expression expr , SearchLookup lookup ,
220
235
@ Nullable Map <String , Object > vars ) {
221
236
// NOTE: if we need to do anything complicated with bindings in the future, we can just extend Bindings,
222
237
// instead of complicating SimpleBindings (which should stay simple)
@@ -252,7 +267,7 @@ private AggregationScript.LeafFactory newAggregationScript(Expression expr, Sear
252
267
return new ExpressionAggregationScript (expr , bindings , needsScores , specialValue );
253
268
}
254
269
255
- private FieldScript .LeafFactory newFieldScript (Expression expr , SearchLookup lookup , @ Nullable Map <String , Object > vars ) {
270
+ private static FieldScript .LeafFactory newFieldScript (Expression expr , SearchLookup lookup , @ Nullable Map <String , Object > vars ) {
256
271
SimpleBindings bindings = new SimpleBindings ();
257
272
for (String variable : expr .variables ) {
258
273
try {
@@ -273,7 +288,7 @@ private FieldScript.LeafFactory newFieldScript(Expression expr, SearchLookup loo
273
288
* This is a hack for filter scripts, which must return booleans instead of doubles as expression do.
274
289
* See https://github.com/elastic/elasticsearch/issues/26429.
275
290
*/
276
- private FilterScript .LeafFactory newFilterScript (Expression expr , SearchLookup lookup , @ Nullable Map <String , Object > vars ) {
291
+ private static FilterScript .LeafFactory newFilterScript (Expression expr , SearchLookup lookup , @ Nullable Map <String , Object > vars ) {
277
292
ScoreScript .LeafFactory searchLeafFactory = newScoreScript (expr , lookup , vars );
278
293
return ctx -> {
279
294
ScoreScript script = searchLeafFactory .newInstance (ctx );
@@ -290,7 +305,7 @@ public void setDocument(int docid) {
290
305
};
291
306
}
292
307
293
- private ScoreScript .LeafFactory newScoreScript (Expression expr , SearchLookup lookup , @ Nullable Map <String , Object > vars ) {
308
+ private static ScoreScript .LeafFactory newScoreScript (Expression expr , SearchLookup lookup , @ Nullable Map <String , Object > vars ) {
294
309
// NOTE: if we need to do anything complicated with bindings in the future, we can just extend Bindings,
295
310
// instead of complicating SimpleBindings (which should stay simple)
296
311
SimpleBindings bindings = new SimpleBindings ();
@@ -327,7 +342,7 @@ private ScoreScript.LeafFactory newScoreScript(Expression expr, SearchLookup loo
327
342
/**
328
343
* converts a ParseException at compile-time or link-time to a ScriptException
329
344
*/
330
- private ScriptException convertToScriptException (String message , String source , String portion , Throwable cause ) {
345
+ private static ScriptException convertToScriptException (String message , String source , String portion , Throwable cause ) {
331
346
List <String > stack = new ArrayList <>();
332
347
stack .add (portion );
333
348
StringBuilder pointer = new StringBuilder ();
0 commit comments