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 + -
显示快捷键?