5555import java .util .HashMap ;
5656import java .util .List ;
5757import java .util .Map ;
58+ import java .util .Set ;
59+ import java .util .function .Function ;
5860
5961/**
6062 * Provides the infrastructure for Lucene expressions as a scripting language for Elasticsearch.
@@ -65,6 +67,41 @@ public class ExpressionScriptEngine implements ScriptEngine {
6567
6668 public static final String NAME = "expression" ;
6769
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+
68105 @ Override
69106 public String getType () {
70107 return NAME ;
@@ -102,37 +139,15 @@ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundE
102139 }
103140 }
104141 });
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 + "]" );
134144 }
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 ();
136151 }
137152
138153 private static BucketAggregationScript .Factory newBucketAggregationScriptFactory (Expression expr ) {
@@ -166,7 +181,7 @@ public Double execute() {
166181 };
167182 }
168183
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 ) {
170185 // NOTE: if we need to do anything complicated with bindings in the future, we can just extend Bindings,
171186 // instead of complicating SimpleBindings (which should stay simple)
172187 SimpleBindings bindings = new SimpleBindings ();
@@ -193,7 +208,7 @@ private NumberSortScript.LeafFactory newSortScript(Expression expr, SearchLookup
193208 return new ExpressionNumberSortScript (expr , bindings , needsScores );
194209 }
195210
196- private TermsSetQueryScript .LeafFactory newTermsSetQueryScript (Expression expr , SearchLookup lookup ,
211+ private static TermsSetQueryScript .LeafFactory newTermsSetQueryScript (Expression expr , SearchLookup lookup ,
197212 @ Nullable Map <String , Object > vars ) {
198213 // NOTE: if we need to do anything complicated with bindings in the future, we can just extend Bindings,
199214 // instead of complicating SimpleBindings (which should stay simple)
@@ -216,7 +231,7 @@ private TermsSetQueryScript.LeafFactory newTermsSetQueryScript(Expression expr,
216231 return new ExpressionTermSetQueryScript (expr , bindings );
217232 }
218233
219- private AggregationScript .LeafFactory newAggregationScript (Expression expr , SearchLookup lookup ,
234+ private static AggregationScript .LeafFactory newAggregationScript (Expression expr , SearchLookup lookup ,
220235 @ Nullable Map <String , Object > vars ) {
221236 // NOTE: if we need to do anything complicated with bindings in the future, we can just extend Bindings,
222237 // instead of complicating SimpleBindings (which should stay simple)
@@ -252,7 +267,7 @@ private AggregationScript.LeafFactory newAggregationScript(Expression expr, Sear
252267 return new ExpressionAggregationScript (expr , bindings , needsScores , specialValue );
253268 }
254269
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 ) {
256271 SimpleBindings bindings = new SimpleBindings ();
257272 for (String variable : expr .variables ) {
258273 try {
@@ -273,7 +288,7 @@ private FieldScript.LeafFactory newFieldScript(Expression expr, SearchLookup loo
273288 * This is a hack for filter scripts, which must return booleans instead of doubles as expression do.
274289 * See https://github.com/elastic/elasticsearch/issues/26429.
275290 */
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 ) {
277292 ScoreScript .LeafFactory searchLeafFactory = newScoreScript (expr , lookup , vars );
278293 return ctx -> {
279294 ScoreScript script = searchLeafFactory .newInstance (ctx );
@@ -290,7 +305,7 @@ public void setDocument(int docid) {
290305 };
291306 }
292307
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 ) {
294309 // NOTE: if we need to do anything complicated with bindings in the future, we can just extend Bindings,
295310 // instead of complicating SimpleBindings (which should stay simple)
296311 SimpleBindings bindings = new SimpleBindings ();
@@ -327,7 +342,7 @@ private ScoreScript.LeafFactory newScoreScript(Expression expr, SearchLookup loo
327342 /**
328343 * converts a ParseException at compile-time or link-time to a ScriptException
329344 */
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 ) {
331346 List <String > stack = new ArrayList <>();
332347 stack .add (portion );
333348 StringBuilder pointer = new StringBuilder ();
0 commit comments