groovyshell.java

来自「Groovy动态语言 运行在JVM中的动态语言 可以方便的处理业务逻辑变化大的业」· Java 代码 · 共 571 行 · 第 1/2 页

JAVA
571
字号
                    } catch (Throwable t) {
                        reason = t;
                    }
                } catch (NoSuchMethodException e1) {
                    try {
                        // otherwise, find the default constructor
                        constructor = scriptClass.getConstructor(new Class[]{});
                        try {
                            // instanciate a runnable and run it
                            runnable = (Runnable) constructor.newInstance(new Object[]{});
                        } catch (Throwable t) {
                            reason = t;
                        }
                    } catch (NoSuchMethodException nsme) {
                        reason = nsme;
                    }
                }
                if (constructor != null && runnable != null) {
                    runnable.run();
                } else {
                    throw new GroovyRuntimeException("This script or class could not be run. ", reason);
                }
            } else {
                throw new GroovyRuntimeException("This script or class could not be run. \n" +
                        "It should either: \n" +
                        "- have a main method, \n" +
                        "- be a class extending GroovyTestCase, \n" +
                        "- or implement the Runnable interface.");
            }
            return null;
        }
        // if that main method exist, invoke it
        return InvokerHelper.invokeMethod(scriptClass, "main", new Object[]{args});
    }

    /**
     * Run the specified class extending GroovyTestCase as a unit test.
     * This is done through reflection, to avoid adding a dependency to the JUnit framework.
     * Otherwise, developers embedding Groovy and using GroovyShell to load/parse/compile
     * groovy scripts and classes would have to add another dependency on their classpath.
     *
     * @param scriptClass the class to be run as a unit test
     */
    private Object runTest(Class scriptClass) {
        try {
            Object testSuite = InvokerHelper.invokeConstructorOf("junit.framework.TestSuite",new Object[]{scriptClass});
            return InvokerHelper.invokeStaticMethod("junit.textui.TestRunner", "run", new Object[]{testSuite});
        } catch (ClassNotFoundException e) {
            throw new GroovyRuntimeException("Failed to run the unit test. JUnit is not on the Classpath.");
        }
    }

    /**
     * Utility method to check through reflection if the parsed class extends GroovyTestCase.
     *
     * @param scriptClass the class we want to know if it extends GroovyTestCase
     * @return true if the class extends groovy.util.GroovyTestCase
     */
    private boolean isUnitTestCase(Class scriptClass) {
        // check if the parsed class is a GroovyTestCase,
        // so that it is possible to run it as a JUnit test
        boolean isUnitTestCase = false;
        try {
            try {
                Class testCaseClass = this.loader.loadClass("groovy.util.GroovyTestCase");
                // if scriptClass extends testCaseClass
                if (testCaseClass.isAssignableFrom(scriptClass)) {
                    isUnitTestCase = true;
                }
            } catch (ClassNotFoundException e) {
                // fall through
            }
        } catch (Throwable e) {
            // fall through
        }
        return isUnitTestCase;
    }

    /**
     * Runs the given script text with command line arguments
     *
     * @param scriptText is the text content of the script
     * @param fileName   is the logical file name of the script (which is used to create the class name of the script)
     * @param args       the command line arguments to pass in
     */
    public Object run(String scriptText, String fileName, String[] args) throws CompilationFailedException {
        try {
            return run(new ByteArrayInputStream(scriptText.getBytes(config.getSourceEncoding())), fileName, args);
        } catch (UnsupportedEncodingException e) {
            throw new CompilationFailedException(0, null, e);
        }
    }

    /**
     * Runs the given script with command line arguments
     *
     * @param in       the stream reading the script
     * @param fileName is the logical file name of the script (which is used to create the class name of the script)
     * @param args     the command line arguments to pass in
     */
    public Object run(final InputStream in, final String fileName, String[] args) throws CompilationFailedException {
        GroovyCodeSource gcs = (GroovyCodeSource) AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                return new GroovyCodeSource(in, fileName, "/groovy/shell");
            }
        });
        Class scriptClass = parseClass(gcs);
        return runMainOrTestOrRunnable(scriptClass, args);
    }

    public Object getVariable(String name) {
        return context.getVariables().get(name);
    }

    public void setVariable(String name, Object value) {
        context.setVariable(name, value);
    }

    /**
     * Evaluates some script against the current Binding and returns the result
     *
     * @param codeSource
     * @throws CompilationFailedException
     * @throws CompilationFailedException
     */
    public Object evaluate(GroovyCodeSource codeSource) throws CompilationFailedException {
        Script script = parse(codeSource);
        return script.run();
    }

    /**
     * Evaluates some script against the current Binding and returns the result
     *
     * @param scriptText the text of the script
     * @param fileName   is the logical file name of the script (which is used to create the class name of the script)
     */
    public Object evaluate(String scriptText, String fileName) throws CompilationFailedException {
        try {
            return evaluate(new ByteArrayInputStream(scriptText.getBytes(config.getSourceEncoding())), fileName);
        } catch (UnsupportedEncodingException e) {
            throw new CompilationFailedException(0, null, e);
        }
    }

    /**
     * Evaluates some script against the current Binding and returns the result.
     * The .class file created from the script is given the supplied codeBase
     */
    public Object evaluate(String scriptText, String fileName, String codeBase) throws CompilationFailedException {
        try {
            return evaluate(new GroovyCodeSource(new ByteArrayInputStream(scriptText.getBytes(config.getSourceEncoding())), fileName, codeBase));
        } catch (UnsupportedEncodingException e) {
            throw new CompilationFailedException(0, null, e);
        }
    }

    /**
     * Evaluates some script against the current Binding and returns the result
     *
     * @param file is the file of the script (which is used to create the class name of the script)
     */
    public Object evaluate(File file) throws CompilationFailedException, IOException {
        return evaluate(new GroovyCodeSource(file));
    }

    /**
     * Evaluates some script against the current Binding and returns the result
     *
     * @param scriptText the text of the script
     */
    public Object evaluate(String scriptText) throws CompilationFailedException {
        try {
            return evaluate(new ByteArrayInputStream(scriptText.getBytes(config.getSourceEncoding())), generateScriptName());
        } catch (UnsupportedEncodingException e) {
            throw new CompilationFailedException(0, null, e);
        }
    }

    /**
     * Evaluates some script against the current Binding and returns the result
     *
     * @param in the stream reading the script
     */
    public Object evaluate(InputStream in) throws CompilationFailedException {
        return evaluate(in, generateScriptName());
    }

    /**
     * Evaluates some script against the current Binding and returns the result
     *
     * @param in       the stream reading the script
     * @param fileName is the logical file name of the script (which is used to create the class name of the script)
     */
    public Object evaluate(InputStream in, String fileName) throws CompilationFailedException {
        Script script = null;
        try {
            script = parse(in, fileName);
            return script.run();
        } finally {
            if (script != null) {
                InvokerHelper.removeClass(script.getClass());
            }
        }
    }

    /**
     * Parses the given script and returns it ready to be run
     *
     * @param in       the stream reading the script
     * @param fileName is the logical file name of the script (which is used to create the class name of the script)
     * @return the parsed script which is ready to be run via @link Script.run()
     */
    public Script parse(final InputStream in, final String fileName) throws CompilationFailedException {
        GroovyCodeSource gcs = (GroovyCodeSource) AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                return new GroovyCodeSource(in, fileName, "/groovy/shell");
            }
        });
        return parse(gcs);
    }

    /**
     * Parses the groovy code contained in codeSource and returns a java class.
     */
    private Class parseClass(final GroovyCodeSource codeSource) throws CompilationFailedException {
        // Don't cache scripts
        return loader.parseClass(codeSource, false);
    }

    /**
     * Parses the given script and returns it ready to be run.  When running in a secure environment
     * (-Djava.security.manager) codeSource.getCodeSource() determines what policy grants should be
     * given to the script.
     *
     * @param codeSource
     * @return ready to run script
     */
    public Script parse(final GroovyCodeSource codeSource) throws CompilationFailedException {
        return InvokerHelper.createScript(parseClass(codeSource), context);
    }

    /**
     * Parses the given script and returns it ready to be run
     *
     * @param file is the file of the script (which is used to create the class name of the script)
     */
    public Script parse(File file) throws CompilationFailedException, IOException {
        return parse(new GroovyCodeSource(file));
    }

    /**
     * Parses the given script and returns it ready to be run
     *
     * @param scriptText the text of the script
     */
    public Script parse(String scriptText) throws CompilationFailedException {
        try {
            return parse(new ByteArrayInputStream(scriptText.getBytes(config.getSourceEncoding())), generateScriptName());
        } catch (UnsupportedEncodingException e) {
            throw new CompilationFailedException(0, null, e);
        }
    }

    public Script parse(String scriptText, String fileName) throws CompilationFailedException {
        try {
            return parse(new ByteArrayInputStream(scriptText.getBytes(config.getSourceEncoding())), fileName);
        } catch (UnsupportedEncodingException e) {
            throw new CompilationFailedException(0, null, e);
        }
    }

    /**
     * Parses the given script and returns it ready to be run
     *
     * @param in the stream reading the script
     */
    public Script parse(InputStream in) throws CompilationFailedException {
        return parse(in, generateScriptName());
    }

    protected synchronized String generateScriptName() {
        return "Script" + (++counter) + ".groovy";
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?