📄 groovyshell.java
字号:
/* $Id: GroovyShell.java,v 1.52 2006/05/30 18:14:45 blackdrag Exp $ Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved. Redistribution and use of this software and associated documentation ("Software"), with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain copyright statements and notices. Redistributions must also contain a copy of this document. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name "groovy" must not be used to endorse or promote products derived from this Software without prior written permission of The Codehaus. For written permission, please contact info@codehaus.org. 4. Products derived from this Software may not be called "groovy" nor may "groovy" appear in their names without prior written permission of The Codehaus. "groovy" is a registered trademark of The Codehaus. 5. Due credit should be given to The Codehaus - http://groovy.codehaus.org/ THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */package groovy.lang;import groovy.ui.GroovyMain;import org.codehaus.groovy.control.CompilationFailedException;import org.codehaus.groovy.control.CompilerConfiguration;import org.codehaus.groovy.runtime.InvokerHelper;import java.io.*;import java.lang.reflect.Constructor;import java.security.AccessController;import java.security.PrivilegedAction;import java.security.PrivilegedActionException;import java.security.PrivilegedExceptionAction;import java.util.List;import java.util.Map;/** * Represents a groovy shell capable of running arbitrary groovy scripts * * @author <a href="mailto:james@coredevelopers.net">James Strachan</a> * @author Guillaume Laforge * @version $Revision: 1.52 $ */public class GroovyShell extends GroovyObjectSupport { public static final String[] EMPTY_ARGS = {}; private Binding context; private int counter; private CompilerConfiguration config; private GroovyClassLoader loader; public static void main(String[] args) { GroovyMain.main(args); } public GroovyShell() { this(null, new Binding()); } public GroovyShell(Binding binding) { this(null, binding); } public GroovyShell(CompilerConfiguration config) { this(new Binding(), config); } public GroovyShell(Binding binding, CompilerConfiguration config) { this(null, binding, config); } public GroovyShell(ClassLoader parent, Binding binding) { this(parent, binding, CompilerConfiguration.DEFAULT); } public GroovyShell(ClassLoader parent) { this(parent, new Binding(), CompilerConfiguration.DEFAULT); } public GroovyShell(ClassLoader parent, Binding binding, final CompilerConfiguration config) { if (binding == null) { throw new IllegalArgumentException("Binding must not be null."); } if (config == null) { throw new IllegalArgumentException("Compiler configuration must not be null."); } final ClassLoader parentLoader = (parent!=null)?parent:GroovyShell.class.getClassLoader(); this.loader = (GroovyClassLoader) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return new GroovyClassLoader(parentLoader,config); } }); this.context = binding; this.config = config; } public void initialiseBinding() { Map map = context.getVariables(); if (map.get("shell")==null) map.put("shell",this); } public void resetLoadedClasses() { loader.clearCache(); } /** * Creates a child shell using a new ClassLoader which uses the parent shell's * class loader as its parent * * @param shell is the parent shell used for the variable bindings and the parent class loader */ public GroovyShell(GroovyShell shell) { this(shell.loader, shell.context); } public Binding getContext() { return context; } public Object getProperty(String property) { Object answer = getVariable(property); if (answer == null) { answer = super.getProperty(property); } return answer; } public void setProperty(String property, Object newValue) { setVariable(property, newValue); try { super.setProperty(property, newValue); } catch (GroovyRuntimeException e) { // ignore, was probably a dynamic property } } /** * A helper method which runs the given script file with the given command line arguments * * @param scriptFile the file of the script to run * @param list the command line arguments to pass in */ public Object run(File scriptFile, List list) throws CompilationFailedException, IOException { String[] args = new String[list.size()]; return run(scriptFile, (String[]) list.toArray(args)); } /** * A helper method which runs the given cl script with the given 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 list the command line arguments to pass in */ public Object run(String scriptText, String fileName, List list) throws CompilationFailedException { String[] args = new String[list.size()]; list.toArray(args); return run(scriptText, fileName, args); } /** * Runs the given script file name with the given command line arguments * * @param scriptFile the file name of the script to run * @param args the command line arguments to pass in */ public Object run(final File scriptFile, String[] args) throws CompilationFailedException, IOException { String scriptName = scriptFile.getName(); int p = scriptName.lastIndexOf("."); if (p++ >= 0) { if (scriptName.substring(p).equals("java")) { System.err.println("error: cannot compile file with .java extension: " + scriptName); throw new CompilationFailedException(0, null); } } // Get the current context classloader and save it on the stack final Thread thread = Thread.currentThread(); //ClassLoader currentClassLoader = thread.getContextClassLoader(); class DoSetContext implements PrivilegedAction { ClassLoader classLoader; public DoSetContext(ClassLoader loader) { classLoader = loader; } public Object run() { thread.setContextClassLoader(classLoader); return null; } } AccessController.doPrivileged(new DoSetContext(loader)); // Parse the script, generate the class, and invoke the main method. This is a little looser than // if you are compiling the script because the JVM isn't executing the main method. Class scriptClass; try { scriptClass = (Class) AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws CompilationFailedException, IOException { return loader.parseClass(scriptFile); } }); } catch (PrivilegedActionException pae) { Exception e = pae.getException(); if (e instanceof CompilationFailedException) { throw (CompilationFailedException) e; } else if (e instanceof IOException) { throw (IOException) e; } else { throw (RuntimeException) pae.getException(); } } return runMainOrTestOrRunnable(scriptClass, args); // Set the context classloader back to what it was. //AccessController.doPrivileged(new DoSetContext(currentClassLoader)); } /** * if (theClass has a main method) { * run the main method * } else if (theClass instanceof GroovyTestCase) { * use the test runner to run it * } else if (theClass implements Runnable) { * if (theClass has a constructor with String[] params) * instanciate theClass with this constructor and run * else if (theClass has a no-args constructor) * instanciate theClass with the no-args constructor and run * } */ private Object runMainOrTestOrRunnable(Class scriptClass, String[] args) { if (scriptClass == null) { return null; } try { // let's find a main method scriptClass.getMethod("main", new Class[]{String[].class}); } catch (NoSuchMethodException e) { // As no main() method was found, let's see if it's a unit test // if it's a unit test extending GroovyTestCase, run it with JUnit's TextRunner if (isUnitTestCase(scriptClass)) { return runTest(scriptClass); } // no main() method, not a unit test, // if it implements Runnable, try to instanciate it else if (Runnable.class.isAssignableFrom(scriptClass)) { Constructor constructor = null; Runnable runnable = null; Throwable reason = null; try { // first, fetch the constructor taking String[] as parameter constructor = scriptClass.getConstructor(new Class[]{(new String[]{}).getClass()}); try { // instanciate a runnable and run it runnable = (Runnable) constructor.newInstance(new Object[]{args});
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -