This is the 23rd day of my participation in the August More Text Challenge.More challenges in August

Use Java custom modules

Modules can be defined in Java as well as AviatorScript. A Java implementation module is just a normal Java class, all of whose static methods are provided as module methods.

Let’s implement the simplest STR module:

@Import(ns = "str") public static class StringModule { public static boolean isBlank(final String s) { return s == null || s.trim().length() == 0; }}Copy the code

Import annotation specifies the namespace name of the module as STR and provides a static method isBlank(s) to determine if the string isBlank.

Next we use addModule to add modules to the execution engine:

 AviatorEvaluator.getInstance().addModule(StringModule.class);
Copy the code

Once added, you can use require to load the module and use it in your script:

 String script = "let str = require('str'); str.isBlank(s) ";

    System.out.println(AviatorEvaluator.execute(script, AviatorEvaluator.newEnv("s", "hello")));
    System.out.println(AviatorEvaluator.execute(script, AviatorEvaluator.newEnv("s", " ")));
    System.out.println(AviatorEvaluator.execute(script, AviatorEvaluator.newEnv("s", null)));
Copy the code

Output:

false
true
true
Copy the code

You can customize modules in a similar way.

Java Scripting API support

In Section 6.3 we saw how to call Java functions in AviatorScript. Here we will show you how to call functions in AviatorScript using the scripting API provided by Java, etc.

AviatorScript with built-in support for * * * * Java Scripting API, and provides a AviatorScriptEngineFactory SPI implementation, As long as your classpath contains a jar reference to aviator, you can use it directly. Let’s look at some examples (all of the sample code is in the source example scripting directory).

Obtaining the Execution Engine

AviatorScript execution engine can be obtained by ScriptEngineManager:

package com.googlecode.aviator.example.scripting; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public class ScriptEngineExample { public static void main(final String[] args) { final ScriptEngineManager sem = new ScriptEngineManager(); ScriptEngine engine = sem.getEngineByName("AviatorScript"); }}Copy the code

We’ll use this engine for various examples.

Configuring the Execution Engine

You can get the underlying AviatorEvaluatorInstance reference from ScriptEngine to configure the engine:

package com.googlecode.aviator.example.scripting; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import com.googlecode.aviator.AviatorEvaluatorInstance; import com.googlecode.aviator.Feature; import com.googlecode.aviator.Options; import com.googlecode.aviator.script.AviatorScriptEngine; public class ConfigureEngine { public static void main(final String[] args) throws Exception { final ScriptEngineManager  sem = new ScriptEngineManager(); ScriptEngine engine = sem.getEngineByName("AviatorScript"); AviatorEvaluatorInstance instance = ((AviatorScriptEngine) engine).getEngine(); // Use compatible feature set instance.setOption(Options.FEATURE_SET, Feature.getCompatibleFeatures()); // Doesn't support if in compatible feature set mode. engine.eval("if(true) { println('support if'); } "); }}Copy the code

The default engine is in the following mode:

  1. Full syntax feature support
  2. Cache compilation mode
  1. Enable reflection – based Java method calls

evaluation

At its simplest, you can simply execute an AviatorScript script by calling the eval(script) method

package com.googlecode.aviator.example.scripting; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public class EvalScriptExample { public static void main(final String[] args) throws Exception { final ScriptEngineManager sem = new ScriptEngineManager(); ScriptEngine engine = sem.getEngineByName("AviatorScript"); engine.eval("print('Hello, World')"); }}Copy the code

This will print Hello World to the console, call print,

If your script is a file, you can also use eval(reader) :

import javax.script.*; public class EvalFile { public static void main(String[] args) throws Exception { // create a script engine manager ScriptEngineManager factory = new ScriptEngineManager(); // create AviatorScript engine ScriptEngine engine = factory.getEngineByName("AviatorScript"); // evaluate AviatorScript code from given file - specified by first argument engine.eval(new java.io.FileReader(args[0])); }}Copy the code

The file name is specified by the first argument executed.

The default engine is in cache expression mode.

Injecting variable

You can inject global variables into the script and execute:

package com.googlecode.aviator.example.scripting; import java.io.File; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public class ScriptVars { public static void main(final String[] args) throws Exception { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("AviatorScript"); File f = new File("test.txt"); // expose File object as variable to script engine.put("file", f); // evaluate a script string. The script accesses "file" // variable and calls method on it engine.eval("print(getAbsolutePath(file))"); }}Copy the code

Here we inject the file f as a global variable through the engine.put method, and then execute the script print(getAbsolutePath(file)) to print the absolute path to the file.

The default engine enables Java reflection based method invocation patterns.