Java run dynamic script

To summarize here the main Java integrated for Groovy.

Groovy can be perfectly integrated with Java to expand our applications, such as Java + jexl alternative formula to achieve expression calculations or other functions. In Ofbiz also integrated Groovy to perform some queries, and more are beginning to use Groovy instead of the original bsh. Here are just a preliminary summary of how we apply Groovy expand our applications in Java project.
1. GroovyShell calculation expression
using Binding object variables passed expression and returns the result calculated by the expression GroovyShell. In the following example:
public class GroovyShellExample {
    public static void main (String args []) {
        the Binding Binding the Binding new new = ();
        binding.setVariable ( "X", 10);
        binding.setVariable ( "Language", "Groovy");

        GroovyShell shell = new GroovyShell(binding);
        Object value = shell.evaluate("println \"Welcome to $language\"; y = x * 2; z = x * 3; return x ");

        System.err.println(value +", " + value.equals(10));
        System.err.println(binding.getVariable("y") +", " + binding.getVariable("y").equals(20));
        System.err.println(binding.getVariable("z") +", " + binding.getVariable("z").equals(30));
    }
}
运行结果如下:
Welcome to Groovy
10, true
20, true
30, true

2. Use GroovyScriptEngine scripting engine load Groovy scripts
GroovyScriptEngine from the specified location (file system, URL, database, etc.) to load Groovy scripts, and as the script changes can reload them. And GroovyShell Like, GroovyScriptEngine can also pass into the value of the variable returns the results of the script. So that we can put some of the available formula or calculation condition is written in Groovy scripts to perform computing applications. When these conditions change or calculation formulas, we can more easily change the calculation. Such as:
public class GroovyScriptEngineExample {
    public static void main (String args []) {
        the try {
            String [] = Roots new new String [] { "the src \\ \\ \\ Sample."}; // define the root Groovy script engine path
            GroovyScriptEngine = new new GroovyScriptEngine Engine (Roots);
            the Binding Binding the Binding new new = ();
            binding.setVariable ( "Language", "Groovy");
            Object value = engine.run ( "SimpleScript.groovy", Binding);
            Assert value. equals ( "The End");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
SimpleScript.groovy脚本如下:
//SimpleScript.groovy
println "Welcome to $language"
return "The End"

Results are as follows:
is available for purchase to Groovy

3. Use GroovyClassLoader Groovy dynamically loaded classes
embodiment is now shown how to use the load GroovyClassLoader Groovy class and calls a method of the class
Package Sample;
public class GroovyClassLoaderExample {
    public static void main (String args []) {
        the try {
            GroovyClassLoader Loader = new new GroovyClassLoader ();
            Class fileCreator = loader.parseClass (new new File ( "GroovySimpleFileCreator.groovy"));
            with the supplied GroovyObject = Object (with the supplied GroovyObject) fileCreator.newInstance ();
            object.invokeMethod ( "CreateFile", "C: \\ \\ TEMP emptyFile.txt ");
        } the catch (Exception E) {
            e.printStackTrace ();
        }
    }
}
GroovySimpleFileCreator.groovy following documents:
Package Sample;
GroovySimpleFileCreator {class
    public CreateFile (String fileName) {
        File File = new new File (fileName);
        file.createNewFile ();
    }
}
using GroovyClassLoader another scenario is: the presence of a Java interface and a Groovy the Java class that implements the interface. In this case, the class may be achieved by the application GroovyClassLoader Groovy loading, so that the interface method can be called directly.
The interface is defined as follows:
Package Sample;
public interface the IFoo {
    Object RUN (Object foo);
}
Package Sample;
public class InvokeGroovy {
    public static void main (String [] args) {
        .. ClassLoader Cl = new new InvokeGroovy () getClass () getClassLoader ();
        GroovyClassLoader groovyCl = new new GroovyClassLoader (Cl);
        the try {
            // read from a file, the interface implemented IFoo groovy groovy classes written in a file
            // Class groovyClass = groovyCl.parseClass (new new File ( "./ the src / Sample / Foo.groovy"));
            // Direct using Groovy strings, the correct result can be obtained
            class groovyClass = groovyCl.parseClass ( "package sample ; \ r \ n class foo implements IFoo {public Object run (Object foo) {return 2 + 2> 1}}"); / / this return to true
            the IFoo foo = (the IFoo) groovyClass.newInstance ();
            System.out.println (foo.run (new new Integer (2)));
        } the catch (Exception E) {
            e.printStackTrace ();
        }
    }
}

4. Using JAVA script API
Java SE 6 introduces support for the Java Specification Request (JSR) 223 of, JSR 223 aims to define a unified standard, so that Java applications can be fixed through a set of interfaces to interact with a variety of scripting engine, so as to achieve the purpose of calling various scripting languages on the Java platform. Each script is a script interpreter engine, responsible for running the script, get the results. ScriptEngine interface provides a number of variants of the eval function is used to run the script of this function is to get a script, running script, and finally return output.
The following example shows an example of using the JAVA script API run Groovy:
public class GroovyJSR223Example {
    public static void main (String args []) {
        the try {
            the ScriptEngineManager the ScriptEngineManager Factory new new = ();
            the ScriptEngine = factory.getEngineByName Engine ( "Groovy") ;
            String HelloLanguage = "Hello DEF (Language) {return \" the Hello $ Language \ "}";
            engine.eval (HelloLanguage);
            the Invocable INV = (the Invocable) Engine;
            Object [] = {the params new new String ( "Groovy")};
            Object inv.invokeFunction Result = ( "Hello", the params);
            Assert result.equals ( "Groovy the Hello");
            System.err.println (Result);
        } the catch (Exception E) {
            // the TODO Auto-Generated Block the catch
            e.printStackTrace ();
        }
    }
}
the Java script API Groovy addition operation, but can also run other script, such as JavaScript, BSH like.

The following reference << Java SE 6 new features: support for scripting languages >> http://www.ibm.com/developerworks/cn/java/j-lo-jse66/
javax.script.ScriptContext interfaces and javax.script. Bindings interface defines the context of the script engine
   Bindings Interface:? Java applications and scripts through these - the exchange of data on "key value."
   ? ScriptContext Interface: ScriptEngine will be able to obtain the required attribute values from its internal Bindings by ScriptContext instance. The interface contains two ScriptContext default level Bindings reference to the instance, and the global level are level .ScriptContext engine also allows the user to redirect the input and output of the engine during execution stream.
{class Redirectory public
    public static void main (String [] args) throws Exception {
        the ScriptEngineManager the ScriptEngineManager Manager new new = ();
        the ScriptEngine = manager.getEngineByName Engine ( "JavaScript");

        PipedReader pr = new PipedReader();
        PipedWriter pw = new PipedWriter(pr);
        PrintWriter writer = new PrintWriter(pw);
        engine.getContext().setWriter(writer);

        Script = String "the println ( 'the JavaScript from the Hello')";
        engine.eval (Script);
       
        the BufferedReader the BufferedReader br = new new (PR);
        System.out.println (br.readLine ());
    }
}
There are three levels of local access attribute can be, respectively, in ScriptEngineManager Bindings, Bindings ScriptEngine corresponding instance ScriptContext contained, and when an incoming call eval function Bingdings. Function calls from the closer, the smaller the scope, the higher the priority. Examples can be seen in the access priority of each attribute:
public class the scopeTest {
    public static void main (String [] args) throws Exception {
        String = Script "the println (Greeting)";
        the ScriptEngineManager the ScriptEngineManager Manager new new = ();
        the ScriptEngine = manager.getEngineByName Engine ( "JavaScript");
       
        // the Attribute from the ScriptEngineManager
        manager.put("greeting", "Hello from ScriptEngineManager");
        engine.eval(script);

        //Attribute from ScriptEngine
        engine.put("greeting", "Hello from ScriptEngine");
        engine.eval(script);

        //Attribute from eval method
        ScriptContext context = new SimpleScriptContext();
        context.setAttribute("greeting", "Hello from eval method", ScriptContext.ENGINE_SCOPE);
        engine.eval(script,context);
    }
}

In the Java scripting API There are two scripting engine can choose whether to implement the interface of the two interfaces are not mandatory to achieve that not all of the scripting engine can support these two functions:
   ? Invocable Interface: allows Java Platform Invoke function or method in the script. Invocable interface also allows Java applications to return from a direct interface to these functions through this interface instance to call a script function or method, so that we may need to interface object from a script dynamically generates Java applications.
   ? Compilable Interface: allows Java platform compiler script for multiple calls.
Function call script in the following example:
public class CompilableTest {
    public static void main (String [] args) throws the ScriptException, a NoSuchMethodException {
        String Script = "function Greeting (Message) {the println (Message);}";
        the ScriptEngineManager Manager = new new the ScriptEngineManager ();
        the ScriptEngine = manager.getEngineByName Engine ( "JavaScript");
        engine.eval (Script);

        if (engine instanceof Invocable) {
            Invocable invocable = (Invocable) engine;
            invocable.invokeFunction("greeting", "hi");
            // It may through NoSuchMethodException
            try {
                invocable.invokeFunction("nogreeing");
            } catch (NoSuchMethodException e) {
                // expected
            }
        }
    }
}
下例演示了如何使用 Compiable 接口来调用脚本:
public class CompilableTest {
    public static void main(String[] args) throws ScriptException {
        String script = " println (greeting); greeting= 'Good Afternoon!' ";
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");
        engine.put("greeting", "Good Morning!");
       
        if (engine instanceof Compilable) {
            Compilable compilable = (Compilable) engine;
            CompiledScript compiledScript = compilable.compile(script);
            compiledScript.eval();
            compiledScript.eval();
        }
    }
}

To summarize here the main Java integrated for Groovy.

Groovy can be perfectly integrated with Java to expand our applications, such as Java + jexl alternative formula to achieve expression calculations or other functions. In Ofbiz also integrated Groovy to perform some queries, and more are beginning to use Groovy instead of the original bsh. Here are just a preliminary summary of how we apply Groovy expand our applications in Java project.
1. GroovyShell calculation expression
using Binding object variables passed expression and returns the result calculated by the expression GroovyShell. In the following example:
public class GroovyShellExample {
    public static void main (String args []) {
        the Binding Binding the Binding new new = ();
        binding.setVariable ( "X", 10);
        binding.setVariable ( "Language", "Groovy");

        GroovyShell shell = new GroovyShell(binding);
        Object value = shell.evaluate("println \"Welcome to $language\"; y = x * 2; z = x * 3; return x ");

        System.err.println(value +", " + value.equals(10));
        System.err.println(binding.getVariable("y") +", " + binding.getVariable("y").equals(20));
        System.err.println(binding.getVariable("z") +", " + binding.getVariable("z").equals(30));
    }
}
运行结果如下:
Welcome to Groovy
10, true
20, true
30, true

2. Use GroovyScriptEngine scripting engine load Groovy scripts
GroovyScriptEngine from the specified location (file system, URL, database, etc.) to load Groovy scripts, and as the script changes can reload them. And GroovyShell Like, GroovyScriptEngine can also pass into the value of the variable returns the results of the script. So that we can put some of the available formula or calculation condition is written in Groovy scripts to perform computing applications. When these conditions change or calculation formulas, we can more easily change the calculation. Such as:
public class GroovyScriptEngineExample {
    public static void main (String args []) {
        the try {
            String [] = Roots new new String [] { "the src \\ \\ \\ Sample."}; // define the root Groovy script engine path
            GroovyScriptEngine = new new GroovyScriptEngine Engine (Roots);
            the Binding Binding the Binding new new = ();
            binding.setVariable ( "Language", "Groovy");
            Object value = engine.run ( "SimpleScript.groovy", Binding);
            Assert value. equals ( "The End");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
SimpleScript.groovy脚本如下:
//SimpleScript.groovy
println "Welcome to $language"
return "The End"

Results are as follows:
is available for purchase to Groovy

3. Use GroovyClassLoader Groovy dynamically loaded classes
embodiment is now shown how to use the load GroovyClassLoader Groovy class and calls a method of the class
Package Sample;
public class GroovyClassLoaderExample {
    public static void main (String args []) {
        the try {
            GroovyClassLoader Loader = new new GroovyClassLoader ();
            Class fileCreator = loader.parseClass (new new File ( "GroovySimpleFileCreator.groovy"));
            with the supplied GroovyObject = Object (with the supplied GroovyObject) fileCreator.newInstance ();
            object.invokeMethod ( "CreateFile", "C: \\ \\ TEMP emptyFile.txt ");
        } the catch (Exception E) {
            e.printStackTrace ();
        }
    }
}
GroovySimpleFileCreator.groovy following documents:
Package Sample;
GroovySimpleFileCreator {class
    public CreateFile (String fileName) {
        File File = new new File (fileName);
        file.createNewFile ();
    }
}
using GroovyClassLoader another scenario is: the presence of a Java interface and a Groovy the Java class that implements the interface. In this case, the class may be achieved by the application GroovyClassLoader Groovy loading, so that the interface method can be called directly.
The interface is defined as follows:
Package Sample;
public interface the IFoo {
    Object RUN (Object foo);
}
Package Sample;
public class InvokeGroovy {
    public static void main (String [] args) {
        .. ClassLoader Cl = new new InvokeGroovy () getClass () getClassLoader ();
        GroovyClassLoader groovyCl = new new GroovyClassLoader (Cl);
        the try {
            // read from a file, the interface implemented IFoo groovy groovy classes written in a file
            // Class groovyClass = groovyCl.parseClass (new new File ( "./ the src / Sample / Foo.groovy"));
            // Direct using Groovy strings, the correct result can be obtained
            class groovyClass = groovyCl.parseClass ( "package sample ; \ r \ n class foo implements IFoo {public Object run (Object foo) {return 2 + 2> 1}}"); / / this return to true
            the IFoo foo = (the IFoo) groovyClass.newInstance ();
            System.out.println (foo.run (new new Integer (2)));
        } the catch (Exception E) {
            e.printStackTrace ();
        }
    }
}

4. Using JAVA script API
Java SE 6 introduces support for the Java Specification Request (JSR) 223 of, JSR 223 aims to define a unified standard, so that Java applications can be fixed through a set of interfaces to interact with a variety of scripting engine, so as to achieve the purpose of calling various scripting languages on the Java platform. Each script is a script interpreter engine, responsible for running the script, get the results. ScriptEngine interface provides a number of variants of the eval function is used to run the script of this function is to get a script, running script, and finally return output.
The following example shows an example of using the JAVA script API run Groovy:
public class GroovyJSR223Example {
    public static void main (String args []) {
        the try {
            the ScriptEngineManager the ScriptEngineManager Factory new new = ();
            the ScriptEngine = factory.getEngineByName Engine ( "Groovy") ;
            String HelloLanguage = "Hello DEF (Language) {return \" the Hello $ Language \ "}";
            engine.eval (HelloLanguage);
            the Invocable INV = (the Invocable) Engine;
            Object [] = {the params new new String ( "Groovy")};
            Object inv.invokeFunction Result = ( "Hello", the params);
            Assert result.equals ( "Groovy the Hello");
            System.err.println (Result);
        } the catch (Exception E) {
            // the TODO Auto-Generated Block the catch
            e.printStackTrace ();
        }
    }
}
the Java script API Groovy addition operation, but can also run other script, such as JavaScript, BSH like.

The following reference << Java SE 6 new features: support for scripting languages >> http://www.ibm.com/developerworks/cn/java/j-lo-jse66/
javax.script.ScriptContext interfaces and javax.script. Bindings interface defines the context of the script engine
   Bindings Interface:? Java applications and scripts through these - the exchange of data on "key value."
   ? ScriptContext Interface: ScriptEngine will be able to obtain the required attribute values from its internal Bindings by ScriptContext instance. The interface contains two ScriptContext default level Bindings reference to the instance, and the global level are level .ScriptContext engine also allows the user to redirect the input and output of the engine during execution stream.
{class Redirectory public
    public static void main (String [] args) throws Exception {
        the ScriptEngineManager the ScriptEngineManager Manager new new = ();
        the ScriptEngine = manager.getEngineByName Engine ( "JavaScript");

        PipedReader pr = new PipedReader();
        PipedWriter pw = new PipedWriter(pr);
        PrintWriter writer = new PrintWriter(pw);
        engine.getContext().setWriter(writer);

        Script = String "the println ( 'the JavaScript from the Hello')";
        engine.eval (Script);
       
        the BufferedReader the BufferedReader br = new new (PR);
        System.out.println (br.readLine ());
    }
}
There are three levels of local access attribute can be, respectively, in ScriptEngineManager Bindings, Bindings ScriptEngine corresponding instance ScriptContext contained, and when an incoming call eval function Bingdings. Function calls from the closer, the smaller the scope, the higher the priority. Examples can be seen in the access priority of each attribute:
public class the scopeTest {
    public static void main (String [] args) throws Exception {
        String = Script "the println (Greeting)";
        the ScriptEngineManager the ScriptEngineManager Manager new new = ();
        the ScriptEngine = manager.getEngineByName Engine ( "JavaScript");
       
        // the Attribute from the ScriptEngineManager
        manager.put("greeting", "Hello from ScriptEngineManager");
        engine.eval(script);

        //Attribute from ScriptEngine
        engine.put("greeting", "Hello from ScriptEngine");
        engine.eval(script);

        //Attribute from eval method
        ScriptContext context = new SimpleScriptContext();
        context.setAttribute("greeting", "Hello from eval method", ScriptContext.ENGINE_SCOPE);
        engine.eval(script,context);
    }
}

In the Java scripting API There are two scripting engine can choose whether to implement the interface of the two interfaces are not mandatory to achieve that not all of the scripting engine can support these two functions:
   ? Invocable Interface: allows Java Platform Invoke function or method in the script. Invocable interface also allows Java applications to return from a direct interface to these functions through this interface instance to call a script function or method, so that we may need to interface object from a script dynamically generates Java applications.
   ? Compilable Interface: allows Java platform compiler script for multiple calls.
Function call script in the following example:
public class CompilableTest {
    public static void main (String [] args) throws the ScriptException, a NoSuchMethodException {
        String Script = "function Greeting (Message) {the println (Message);}";
        the ScriptEngineManager Manager = new new the ScriptEngineManager ();
        the ScriptEngine = manager.getEngineByName Engine ( "JavaScript");
        engine.eval (Script);

        if (engine instanceof Invocable) {
            Invocable invocable = (Invocable) engine;
            invocable.invokeFunction("greeting", "hi");
            // It may through NoSuchMethodException
            try {
                invocable.invokeFunction("nogreeing");
            } catch (NoSuchMethodException e) {
                // expected
            }
        }
    }
}
下例演示了如何使用 Compiable 接口来调用脚本:
public class CompilableTest {
    public static void main(String[] args) throws ScriptException {
        String script = " println (greeting); greeting= 'Good Afternoon!' ";
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");
        engine.put("greeting", "Good Morning!");
       
        if (engine instanceof Compilable) {
            Compilable compilable = (Compilable) engine;
            CompiledScript compiledScript = compilable.compile(script);
            compiledScript.eval();
            compiledScript.eval();
        }
    }
}

Guess you like

Origin www.cnblogs.com/wpcnblog/p/10973448.html