Class JavascriptCompiler

java.lang.Object
org.apache.lucene.expressions.js.JavascriptCompiler

public final class JavascriptCompiler extends Object
An expression compiler for javascript expressions.

Example:

   Expression foo = JavascriptCompiler.compile("((0.3*popularity)/10.0)+(0.7*score)");
 

See the package documentation for the supported syntax and default functions.

You can compile with an alternate set of functions via compile(String, Map). For example:

   Map<String,MethodHandle> functions = new HashMap<>();
   // add all the default functions
   functions.putAll(JavascriptCompiler.DEFAULT_FUNCTIONS);
   // add cbrt()
   functions.put("cbrt", MethodHandles.publicLookup().findStatic(Math.class, "cbrt",
                 MethodType.methodType(double.class, double.class)));
   // call compile with customized function map
   Expression foo = JavascriptCompiler.compile("cbrt(score)+ln(popularity)",
                                               functions);
 

It is possible to pass any MethodHandle as function that only takes double parameters and returns a double. The method does not need to be public, it just needs to be resolved correctly using a private MethodHandles.Lookup instance. Ideally the methods should be static, but you can use MethodHandle.bindTo(Object) to bind it to a receiver.

The parser has a default maximum nesting limit of 1024 (see DEFAULT_MAX_NESTING_DEPTH) which is enforced during parsing. Violating it will cause a ParseException. Please keep in mind that also code like a + b + c + d + ... + z is treated as if it would look like this: (((((a + b) + c) + d) + ...) + z) (because of the nature of the JVM as a stack-based machine).

WARNING: This API is experimental and might change in incompatible ways in the next release.
  • Field Details

    • DEFAULT_MAX_NESTING_DEPTH

      public static final int DEFAULT_MAX_NESTING_DEPTH
      The default maximum depth of nesting (function calls, precedence - also implicit)
      See Also:
    • DEFAULT_FUNCTIONS

      public static final Map<String,MethodHandle> DEFAULT_FUNCTIONS
      The default set of functions available to expressions.

      See the package documentation for a list.

  • Method Details

    • compile

      public static Expression compile(String sourceText) throws ParseException
      Compiles the given expression using default compiler settings.
      Parameters:
      sourceText - The expression to compile
      Returns:
      A new compiled expression
      Throws:
      ParseException - on failure to compile
      IllegalStateException - if the resulting expression class fails to link (e.g., complexity)
    • compile

      public static Expression compile(String sourceText, Map<String,MethodHandle> functions) throws ParseException
      Compiles the given expression with the supplied custom functions using default compiler settings.

      Functions must be public static, return double and can take from zero to 256 double parameters.

      Parameters:
      sourceText - The expression to compile
      functions - map of String names to MethodHandles
      Returns:
      A new compiled expression
      Throws:
      ParseException - on failure to compile
      IllegalArgumentException - if any of the functions does not have correct signature
      IllegalStateException - if the resulting expression class fails to link (e.g., complexity)
    • compile

      public static Expression compile(String sourceText, Map<String,MethodHandle> functions, int maxNestingDepth) throws ParseException
      Compiles the given expression with the supplied custom functions using a custom maximum nesting depth.

      Functions must be public static, return double and can take from zero to 256 double parameters.

      Parameters:
      sourceText - The expression to compile
      functions - map of String names to MethodHandles
      maxNestingDepth - the maximum depth of nesting (function calls, precedence - also implicit)
      Returns:
      A new compiled expression
      Throws:
      ParseException - on failure to compile
      IllegalArgumentException - if any of the functions does not have correct signature
      IllegalStateException - if the resulting expression class fails to link (e.g., complexity)
    • convertLegacyFunctions

      @Deprecated public static Map<String,MethodHandle> convertLegacyFunctions(Map<String,Method> functions) throws IllegalAccessException
      Deprecated.
      Only use this to convert Lucene 9.x or earlier legacy code. For new code use MethodHandle.
      Converts a legacy map with reflective Method functions to Map<String,MethodHandle for use with compile(String, Map).
      Parameters:
      functions - a map with only public and accessible reflective methods
      Returns:
      a new (modifiable) map with the same function declarations, but converted to MethodHandle
      Throws:
      IllegalAccessException - if any of the methods in functions are not accessible by the public MethodHandles.Lookup.