groovyscriptengine.java

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

JAVA
381
字号
    public GroovyScriptEngine(String url, ClassLoader parentClassLoader) throws IOException {
        this(url);
        this.parentClassLoader = parentClassLoader;
    }

    public GroovyScriptEngine(ResourceConnector rc) {
        this.rc = rc;
    }

    public GroovyScriptEngine(ResourceConnector rc, ClassLoader parentClassLoader) {
        this(rc);
        this.parentClassLoader = parentClassLoader;
    }

    /**
     * Get the <code>ClassLoader</code> that will serve as the parent ClassLoader of the
     * {@link GroovyClassLoader} in which scripts will be executed. By default, this is the
     * ClassLoader that loaded the <code>GroovyScriptEngine</code> class.
     *
     * @return parent classloader used to load scripts
     */
    public ClassLoader getParentClassLoader() {
        return parentClassLoader;
    }

    /**
     * @param parentClassLoader ClassLoader to be used as the parent ClassLoader for scripts executed by the engine
     */
    public void setParentClassLoader(ClassLoader parentClassLoader) {
        if (parentClassLoader == null) {
            throw new IllegalArgumentException("The parent class loader must not be null.");
        }
        this.parentClassLoader = parentClassLoader;
    }

    /**
     * Get the class of the scriptName in question, so that you can instantiate Groovy objects with caching and reloading.
     *
     * @param scriptName
     * @return the loaded scriptName as a compiled class
     * @throws ResourceException
     * @throws ScriptException
     */
    public Class loadScriptByName(String scriptName) throws ResourceException, ScriptException {
        return loadScriptByName( scriptName, getClass().getClassLoader());
    }


    /**
     * Get the class of the scriptName in question, so that you can instantiate Groovy objects with caching and reloading.
     *
     * @param scriptName
     * @return the loaded scriptName as a compiled class
     * @throws ResourceException
     * @throws ScriptException
     */
    public Class loadScriptByName(String scriptName, ClassLoader parentClassLoader)
            throws ResourceException, ScriptException {
        scriptName = scriptName.replace('.', File.separatorChar) + ".groovy";
        ScriptCacheEntry entry = updateCacheEntry(scriptName, parentClassLoader);
        return entry.scriptClass;
    }

    /**
     * Locate the class and reload it or any of its dependencies
     *
     * @param scriptName
     * @param parentClassLoader
     * @return the scriptName cache entry
     * @throws ResourceException
     * @throws ScriptException
     */
    private ScriptCacheEntry updateCacheEntry(String scriptName, final ClassLoader parentClassLoader)
            throws ResourceException, ScriptException
    {
        ScriptCacheEntry entry;

        scriptName = scriptName.intern();
        synchronized (scriptName) {

            URLConnection groovyScriptConn = rc.getResourceConnection(scriptName);

            // URL last modified
            long lastModified = groovyScriptConn.getLastModified();
            // Check the cache for the scriptName
            entry = (ScriptCacheEntry) scriptCache.get(scriptName);
            // If the entry isn't null check all the dependencies

            boolean dependencyOutOfDate = false;
            if (entry != null) {

                for (Iterator i = entry.dependencies.keySet().iterator(); i.hasNext();) {
                    URLConnection urlc = null;
                    URL url = (URL) i.next();
                    try {
                        urlc = url.openConnection();
                        urlc.setDoInput(false);
                        urlc.setDoOutput(false);
                        long dependentLastModified = urlc.getLastModified();
                        if (dependentLastModified > ((Long) entry.dependencies.get(url)).longValue()) {
                            dependencyOutOfDate = true;
                            break;
                        }
                    } catch (IOException ioe) {
                        dependencyOutOfDate = true;
                        break;
                    }
                }
            }

            if (entry == null || entry.lastModified < lastModified || dependencyOutOfDate) {
                // Make a new entry
                entry = new ScriptCacheEntry();

                // Closure variable
                final ScriptCacheEntry finalEntry = entry;

                // Compile the scriptName into an object
                GroovyClassLoader groovyLoader =
                        (GroovyClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
                            public Object run() {
                                return new GroovyClassLoader(parentClassLoader) {
                                    protected Class findClass(String className) throws ClassNotFoundException {
                                        String filename = className.replace('.', File.separatorChar) + ".groovy";
                                        URLConnection dependentScriptConn = null;
                                        try {
                                            dependentScriptConn = rc.getResourceConnection(filename);
                                            finalEntry.dependencies.put(
                                                    dependentScriptConn.getURL(),
                                                    new Long(dependentScriptConn.getLastModified()));
                                        } catch (ResourceException e1) {
                                            throw new ClassNotFoundException("Could not read " + className + ": " + e1);
                                        }
                                        try {
                                            return parseClass(dependentScriptConn.getInputStream(), filename);
                                        } catch (CompilationFailedException e2) {
                                            throw new ClassNotFoundException("Syntax error in " + className + ": " + e2);
                                        } catch (IOException e2) {
                                            throw new ClassNotFoundException("Problem reading " + className + ": " + e2);
                                        }
                                    }
                                };
                            }
                        });

                try {
                    entry.scriptClass = groovyLoader.parseClass(groovyScriptConn.getInputStream(), scriptName);
                } catch (Exception e) {
                    throw new ScriptException("Could not parse scriptName: " + scriptName, e);
                }
                entry.lastModified = lastModified;
                scriptCache.put(scriptName, entry);
            }
        }
        return entry;
    }

    /**
     * Run a script identified by name.
     *
     * @param scriptName name of the script to run
     * @param argument a single argument passed as a variable named <code>arg</code> in the binding
     * @return a <code>toString()</code> representation of the result of the execution of the script
     * @throws ResourceException
     * @throws ScriptException
     */
    public String run(String scriptName, String argument) throws ResourceException, ScriptException {
        Binding binding = new Binding();
        binding.setVariable("arg", argument);
        Object result = run(scriptName, binding);
        return result == null ? "" : result.toString();
    }

    /**
     * Run a script identified by name.
     *
     * @param scriptName name of the script to run
     * @param binding binding to pass to the script
     * @return an object
     * @throws ResourceException
     * @throws ScriptException
     */
    public Object run(String scriptName, Binding binding) throws ResourceException, ScriptException {

        ScriptCacheEntry entry = updateCacheEntry(scriptName, getParentClassLoader());
        Script scriptObject = InvokerHelper.createScript(entry.scriptClass, binding);
        return scriptObject.run();
    }
}

⌨️ 快捷键说明

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