feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
587
jdkSrc/jdk8/com/sun/tools/script/shell/Main.java
Normal file
587
jdkSrc/jdk8/com/sun/tools/script/shell/Main.java
Normal file
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.script.shell;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import javax.script.*;
|
||||
|
||||
/**
|
||||
* This is the main class for Java script shell.
|
||||
*/
|
||||
public class Main {
|
||||
/**
|
||||
* main entry point to the command line tool
|
||||
* @param args command line argument array
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// parse command line options
|
||||
String[] scriptArgs = processOptions(args);
|
||||
|
||||
// process each script command
|
||||
for (Command cmd : scripts) {
|
||||
cmd.run(scriptArgs);
|
||||
}
|
||||
|
||||
System.exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
// Each -e or -f or interactive mode is represented
|
||||
// by an instance of Command.
|
||||
private static interface Command {
|
||||
public void run(String[] arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and processes command line options.
|
||||
* @param args command line argument array
|
||||
*/
|
||||
private static String[] processOptions(String[] args) {
|
||||
// current scripting language selected
|
||||
String currentLanguage = DEFAULT_LANGUAGE;
|
||||
// current script file encoding selected
|
||||
String currentEncoding = null;
|
||||
|
||||
// check for -classpath or -cp first
|
||||
checkClassPath(args);
|
||||
|
||||
// have we seen -e or -f ?
|
||||
boolean seenScript = false;
|
||||
// have we seen -f - already?
|
||||
boolean seenStdin = false;
|
||||
for (int i=0; i < args.length; i++) {
|
||||
String arg = args[i];
|
||||
if (arg.equals("-classpath") ||
|
||||
arg.equals("-cp")) {
|
||||
// handled already, just continue
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// collect non-option arguments and pass these as script arguments
|
||||
if (!arg.startsWith("-")) {
|
||||
int numScriptArgs;
|
||||
int startScriptArg;
|
||||
if (seenScript) {
|
||||
// if we have seen -e or -f already all non-option arguments
|
||||
// are passed as script arguments
|
||||
numScriptArgs = args.length - i;
|
||||
startScriptArg = i;
|
||||
} else {
|
||||
// if we have not seen -e or -f, first non-option argument
|
||||
// is treated as script file name and rest of the non-option
|
||||
// arguments are passed to script as script arguments
|
||||
numScriptArgs = args.length - i - 1;
|
||||
startScriptArg = i + 1;
|
||||
ScriptEngine se = getScriptEngine(currentLanguage);
|
||||
addFileSource(se, args[i], currentEncoding);
|
||||
}
|
||||
// collect script arguments and return to main
|
||||
String[] result = new String[numScriptArgs];
|
||||
System.arraycopy(args, startScriptArg, result, 0, numScriptArgs);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (arg.startsWith("-D")) {
|
||||
String value = arg.substring(2);
|
||||
int eq = value.indexOf('=');
|
||||
if (eq != -1) {
|
||||
System.setProperty(value.substring(0, eq),
|
||||
value.substring(eq + 1));
|
||||
} else {
|
||||
if (!value.equals("")) {
|
||||
System.setProperty(value, "");
|
||||
} else {
|
||||
// do not allow empty property name
|
||||
usage(EXIT_CMD_NO_PROPNAME);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else if (arg.equals("-?") || arg.equals("-help")) {
|
||||
usage(EXIT_SUCCESS);
|
||||
} else if (arg.equals("-e")) {
|
||||
seenScript = true;
|
||||
if (++i == args.length)
|
||||
usage(EXIT_CMD_NO_SCRIPT);
|
||||
|
||||
ScriptEngine se = getScriptEngine(currentLanguage);
|
||||
addStringSource(se, args[i]);
|
||||
continue;
|
||||
} else if (arg.equals("-encoding")) {
|
||||
if (++i == args.length)
|
||||
usage(EXIT_CMD_NO_ENCODING);
|
||||
currentEncoding = args[i];
|
||||
continue;
|
||||
} else if (arg.equals("-f")) {
|
||||
seenScript = true;
|
||||
if (++i == args.length)
|
||||
usage(EXIT_CMD_NO_FILE);
|
||||
ScriptEngine se = getScriptEngine(currentLanguage);
|
||||
if (args[i].equals("-")) {
|
||||
if (seenStdin) {
|
||||
usage(EXIT_MULTIPLE_STDIN);
|
||||
} else {
|
||||
seenStdin = true;
|
||||
}
|
||||
addInteractiveMode(se);
|
||||
} else {
|
||||
addFileSource(se, args[i], currentEncoding);
|
||||
}
|
||||
continue;
|
||||
} else if (arg.equals("-l")) {
|
||||
if (++i == args.length)
|
||||
usage(EXIT_CMD_NO_LANG);
|
||||
currentLanguage = args[i];
|
||||
continue;
|
||||
} else if (arg.equals("-q")) {
|
||||
listScriptEngines();
|
||||
}
|
||||
// some unknown option...
|
||||
usage(EXIT_UNKNOWN_OPTION);
|
||||
}
|
||||
|
||||
if (! seenScript) {
|
||||
ScriptEngine se = getScriptEngine(currentLanguage);
|
||||
addInteractiveMode(se);
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds interactive mode Command
|
||||
* @param se ScriptEngine to use in interactive mode.
|
||||
*/
|
||||
private static void addInteractiveMode(final ScriptEngine se) {
|
||||
scripts.add(new Command() {
|
||||
public void run(String[] args) {
|
||||
setScriptArguments(se, args);
|
||||
processSource(se, "-", null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds script source file Command
|
||||
* @param se ScriptEngine used to evaluate the script file
|
||||
* @param fileName script file name
|
||||
* @param encoding script file encoding
|
||||
*/
|
||||
private static void addFileSource(final ScriptEngine se,
|
||||
final String fileName,
|
||||
final String encoding) {
|
||||
scripts.add(new Command() {
|
||||
public void run(String[] args) {
|
||||
setScriptArguments(se, args);
|
||||
processSource(se, fileName, encoding);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds script string source Command
|
||||
* @param se ScriptEngine to be used to evaluate the script string
|
||||
* @param source Script source string
|
||||
*/
|
||||
private static void addStringSource(final ScriptEngine se,
|
||||
final String source) {
|
||||
scripts.add(new Command() {
|
||||
public void run(String[] args) {
|
||||
setScriptArguments(se, args);
|
||||
String oldFile = setScriptFilename(se, "<string>");
|
||||
try {
|
||||
evaluateString(se, source);
|
||||
} finally {
|
||||
setScriptFilename(se, oldFile);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints list of script engines available and exits.
|
||||
*/
|
||||
private static void listScriptEngines() {
|
||||
List<ScriptEngineFactory> factories = engineManager.getEngineFactories();
|
||||
for (ScriptEngineFactory factory: factories) {
|
||||
getError().println(getMessage("engine.info",
|
||||
new Object[] { factory.getLanguageName(),
|
||||
factory.getLanguageVersion(),
|
||||
factory.getEngineName(),
|
||||
factory.getEngineVersion()
|
||||
}));
|
||||
}
|
||||
System.exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a given source file or standard input.
|
||||
* @param se ScriptEngine to be used to evaluate
|
||||
* @param filename file name, can be null
|
||||
* @param encoding script file encoding, can be null
|
||||
*/
|
||||
private static void processSource(ScriptEngine se, String filename,
|
||||
String encoding) {
|
||||
if (filename.equals("-")) {
|
||||
BufferedReader in = new BufferedReader
|
||||
(new InputStreamReader(getIn()));
|
||||
boolean hitEOF = false;
|
||||
String prompt = getPrompt(se);
|
||||
se.put(ScriptEngine.FILENAME, "<STDIN>");
|
||||
while (!hitEOF) {
|
||||
getError().print(prompt);
|
||||
String source = "";
|
||||
try {
|
||||
source = in.readLine();
|
||||
} catch (IOException ioe) {
|
||||
getError().println(ioe.toString());
|
||||
}
|
||||
if (source == null) {
|
||||
hitEOF = true;
|
||||
break;
|
||||
}
|
||||
Object res = evaluateString(se, source, false);
|
||||
if (res != null) {
|
||||
res = res.toString();
|
||||
if (res == null) {
|
||||
res = "null";
|
||||
}
|
||||
getError().println(res);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(filename);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
getError().println(getMessage("file.not.found",
|
||||
new Object[] { filename }));
|
||||
System.exit(EXIT_FILE_NOT_FOUND);
|
||||
}
|
||||
evaluateStream(se, fis, filename, encoding);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates given script source
|
||||
* @param se ScriptEngine to evaluate the string
|
||||
* @param script Script source string
|
||||
* @param exitOnError whether to exit the process on script error
|
||||
*/
|
||||
private static Object evaluateString(ScriptEngine se,
|
||||
String script, boolean exitOnError) {
|
||||
try {
|
||||
return se.eval(script);
|
||||
} catch (ScriptException sexp) {
|
||||
getError().println(getMessage("string.script.error",
|
||||
new Object[] { sexp.getMessage() }));
|
||||
if (exitOnError)
|
||||
System.exit(EXIT_SCRIPT_ERROR);
|
||||
} catch (Exception exp) {
|
||||
exp.printStackTrace(getError());
|
||||
if (exitOnError)
|
||||
System.exit(EXIT_SCRIPT_ERROR);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate script string source and exit on script error
|
||||
* @param se ScriptEngine to evaluate the string
|
||||
* @param script Script source string
|
||||
*/
|
||||
private static void evaluateString(ScriptEngine se, String script) {
|
||||
evaluateString(se, script, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates script from given reader
|
||||
* @param se ScriptEngine to evaluate the string
|
||||
* @param reader Reader from which is script is read
|
||||
* @param name file name to report in error.
|
||||
*/
|
||||
private static Object evaluateReader(ScriptEngine se,
|
||||
Reader reader, String name) {
|
||||
String oldFilename = setScriptFilename(se, name);
|
||||
try {
|
||||
return se.eval(reader);
|
||||
} catch (ScriptException sexp) {
|
||||
getError().println(getMessage("file.script.error",
|
||||
new Object[] { name, sexp.getMessage() }));
|
||||
System.exit(EXIT_SCRIPT_ERROR);
|
||||
} catch (Exception exp) {
|
||||
exp.printStackTrace(getError());
|
||||
System.exit(EXIT_SCRIPT_ERROR);
|
||||
} finally {
|
||||
setScriptFilename(se, oldFilename);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates given input stream
|
||||
* @param se ScriptEngine to evaluate the string
|
||||
* @param is InputStream from which script is read
|
||||
* @param name file name to report in error
|
||||
*/
|
||||
private static Object evaluateStream(ScriptEngine se,
|
||||
InputStream is, String name,
|
||||
String encoding) {
|
||||
BufferedReader reader = null;
|
||||
if (encoding != null) {
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(is,
|
||||
encoding));
|
||||
} catch (UnsupportedEncodingException uee) {
|
||||
getError().println(getMessage("encoding.unsupported",
|
||||
new Object[] { encoding }));
|
||||
System.exit(EXIT_NO_ENCODING_FOUND);
|
||||
}
|
||||
} else {
|
||||
reader = new BufferedReader(new InputStreamReader(is));
|
||||
}
|
||||
return evaluateReader(se, reader, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints usage message and exits
|
||||
* @param exitCode process exit code
|
||||
*/
|
||||
private static void usage(int exitCode) {
|
||||
getError().println(getMessage("main.usage",
|
||||
new Object[] { PROGRAM_NAME }));
|
||||
System.exit(exitCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets prompt for interactive mode
|
||||
* @return prompt string to use
|
||||
*/
|
||||
private static String getPrompt(ScriptEngine se) {
|
||||
List<String> names = se.getFactory().getNames();
|
||||
return names.get(0) + "> ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatted, localized error message
|
||||
*/
|
||||
private static String getMessage(String key, Object[] params) {
|
||||
return MessageFormat.format(msgRes.getString(key), params);
|
||||
}
|
||||
|
||||
// input stream from where we will read
|
||||
private static InputStream getIn() {
|
||||
return System.in;
|
||||
}
|
||||
|
||||
// stream to print error messages
|
||||
private static PrintStream getError() {
|
||||
return System.err;
|
||||
}
|
||||
|
||||
// get current script engine
|
||||
private static ScriptEngine getScriptEngine(String lang) {
|
||||
ScriptEngine se = engines.get(lang);
|
||||
if (se == null) {
|
||||
se = engineManager.getEngineByName(lang);
|
||||
if (se == null) {
|
||||
getError().println(getMessage("engine.not.found",
|
||||
new Object[] { lang }));
|
||||
System.exit(EXIT_ENGINE_NOT_FOUND);
|
||||
}
|
||||
|
||||
// initialize the engine
|
||||
initScriptEngine(se);
|
||||
// to avoid re-initialization of engine, store it in a map
|
||||
engines.put(lang, se);
|
||||
}
|
||||
return se;
|
||||
}
|
||||
|
||||
// initialize a given script engine
|
||||
private static void initScriptEngine(ScriptEngine se) {
|
||||
// put engine global variable
|
||||
se.put("engine", se);
|
||||
|
||||
// load init.<ext> file from resource
|
||||
List<String> exts = se.getFactory().getExtensions();
|
||||
InputStream sysIn = null;
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
for (String ext : exts) {
|
||||
sysIn = cl.getResourceAsStream("com/sun/tools/script/shell/init." +
|
||||
ext);
|
||||
if (sysIn != null) break;
|
||||
}
|
||||
if (sysIn != null) {
|
||||
evaluateStream(se, sysIn, "<system-init>", null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for -classpath, -cp in command line args. Creates a ClassLoader
|
||||
* and sets it as Thread context loader for current thread.
|
||||
*
|
||||
* @param args command line argument array
|
||||
*/
|
||||
private static void checkClassPath(String[] args) {
|
||||
String classPath = null;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals("-classpath") ||
|
||||
args[i].equals("-cp")) {
|
||||
if (++i == args.length) {
|
||||
// just -classpath or -cp with no value
|
||||
usage(EXIT_CMD_NO_CLASSPATH);
|
||||
} else {
|
||||
classPath = args[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (classPath != null) {
|
||||
/* We create a class loader, configure it with specified
|
||||
* classpath values and set the same as context loader.
|
||||
* Note that ScriptEngineManager uses context loader to
|
||||
* load script engines. So, this ensures that user defined
|
||||
* script engines will be loaded. For classes referred
|
||||
* from scripts, Rhino engine uses thread context loader
|
||||
* but this is script engine dependent. We don't have
|
||||
* script engine independent solution anyway. Unless we
|
||||
* know the class loader used by a specific engine, we
|
||||
* can't configure correct loader.
|
||||
*/
|
||||
ClassLoader parent = Main.class.getClassLoader();
|
||||
URL[] urls = pathToURLs(classPath);
|
||||
URLClassLoader loader = new URLClassLoader(urls, parent);
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
}
|
||||
|
||||
// now initialize script engine manager. Note that this has to
|
||||
// be done after setting the context loader so that manager
|
||||
// will see script engines from user specified classpath
|
||||
engineManager = new ScriptEngineManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for converting a search path string to an array
|
||||
* of directory and JAR file URLs.
|
||||
*
|
||||
* @param path the search path string
|
||||
* @return the resulting array of directory and JAR file URLs
|
||||
*/
|
||||
private static URL[] pathToURLs(String path) {
|
||||
String[] components = path.split(File.pathSeparator);
|
||||
URL[] urls = new URL[components.length];
|
||||
int count = 0;
|
||||
while(count < components.length) {
|
||||
URL url = fileToURL(new File(components[count]));
|
||||
if (url != null) {
|
||||
urls[count++] = url;
|
||||
}
|
||||
}
|
||||
if (urls.length != count) {
|
||||
URL[] tmp = new URL[count];
|
||||
System.arraycopy(urls, 0, tmp, 0, count);
|
||||
urls = tmp;
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory or JAR file URL corresponding to the specified
|
||||
* local file name.
|
||||
*
|
||||
* @param file the File object
|
||||
* @return the resulting directory or JAR file URL, or null if unknown
|
||||
*/
|
||||
private static URL fileToURL(File file) {
|
||||
String name;
|
||||
try {
|
||||
name = file.getCanonicalPath();
|
||||
} catch (IOException e) {
|
||||
name = file.getAbsolutePath();
|
||||
}
|
||||
name = name.replace(File.separatorChar, '/');
|
||||
if (!name.startsWith("/")) {
|
||||
name = "/" + name;
|
||||
}
|
||||
// If the file does not exist, then assume that it's a directory
|
||||
if (!file.isFile()) {
|
||||
name = name + "/";
|
||||
}
|
||||
try {
|
||||
return new URL("file", "", name);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new IllegalArgumentException("file");
|
||||
}
|
||||
}
|
||||
|
||||
private static void setScriptArguments(ScriptEngine se, String[] args) {
|
||||
se.put("arguments", args);
|
||||
se.put(ScriptEngine.ARGV, args);
|
||||
}
|
||||
|
||||
private static String setScriptFilename(ScriptEngine se, String name) {
|
||||
String oldName = (String) se.get(ScriptEngine.FILENAME);
|
||||
se.put(ScriptEngine.FILENAME, name);
|
||||
return oldName;
|
||||
}
|
||||
|
||||
// exit codes
|
||||
private static final int EXIT_SUCCESS = 0;
|
||||
private static final int EXIT_CMD_NO_CLASSPATH = 1;
|
||||
private static final int EXIT_CMD_NO_FILE = 2;
|
||||
private static final int EXIT_CMD_NO_SCRIPT = 3;
|
||||
private static final int EXIT_CMD_NO_LANG = 4;
|
||||
private static final int EXIT_CMD_NO_ENCODING = 5;
|
||||
private static final int EXIT_CMD_NO_PROPNAME = 6;
|
||||
private static final int EXIT_UNKNOWN_OPTION = 7;
|
||||
private static final int EXIT_ENGINE_NOT_FOUND = 8;
|
||||
private static final int EXIT_NO_ENCODING_FOUND = 9;
|
||||
private static final int EXIT_SCRIPT_ERROR = 10;
|
||||
private static final int EXIT_FILE_NOT_FOUND = 11;
|
||||
private static final int EXIT_MULTIPLE_STDIN = 12;
|
||||
|
||||
// default scripting language
|
||||
private static final String DEFAULT_LANGUAGE = "js";
|
||||
// list of scripts to process
|
||||
private static List<Command> scripts;
|
||||
// the script engine manager
|
||||
private static ScriptEngineManager engineManager;
|
||||
// map of engines we loaded
|
||||
private static Map<String, ScriptEngine> engines;
|
||||
// error messages resource
|
||||
private static ResourceBundle msgRes;
|
||||
private static String BUNDLE_NAME = "com.sun.tools.script.shell.messages";
|
||||
private static String PROGRAM_NAME = "jrunscript";
|
||||
|
||||
static {
|
||||
scripts = new ArrayList<Command>();
|
||||
engines = new HashMap<String, ScriptEngine>();
|
||||
msgRes = ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user