8187443: Forest Consolidation: Move files to unified layout

Reviewed-by: darcy, ihse
This commit is contained in:
Erik Joelsson 2017-09-12 19:03:39 +02:00
parent 270fe13182
commit 3789983e89
56923 changed files with 3 additions and 15727 deletions

View file

@ -0,0 +1,589 @@
/*
* 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) {
try {
sysIn = Main.class.getModule().getResourceAsStream("com/sun/tools/script/shell/init." + ext);
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
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.
*/
URL[] urls = pathToURLs(classPath);
URLClassLoader loader = new URLClassLoader(urls);
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());
}
}

View file

@ -0,0 +1,927 @@
/*
* Copyright (c) 2005, 2013, 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.
*/
/**
* jrunscript JavaScript built-in functions and objects.
*/
/**
* Creates an object that delegates all method calls on
* it to the 'invoke' method on the given delegate object.<br>
*
* Example:
* <pre>
* <code>
* var x = { invoke: function(name, args) { //code...}
* var y = new JSInvoker(x);
* y.func(3, 3); // calls x.invoke('func', args); where args is array of arguments
* </code>
* </pre>
* @param obj object to be wrapped by JSInvoker
* @constructor
*/
function JSInvoker(obj) {
return new JSAdapter({
__get__ : function(name) {
return function() {
return obj.invoke(name, arguments);
}
}
});
}
/**
* This variable represents OS environment. Environment
* variables can be accessed as fields of this object. For
* example, env.PATH will return PATH value configured.
*/
var env = new JSAdapter({
__get__ : function (name) {
return java.lang.System.getenv(name);
},
__has__ : function (name) {
return java.lang.System.getenv().containsKey(name);
},
__getIds__ : function() {
return java.lang.System.getenv().keySet().toArray();
},
__delete__ : function(name) {
println("can't delete env item");
},
__put__ : function (name, value) {
println("can't change env item");
},
toString: function() {
return java.lang.System.getenv().toString();
}
});
/**
* Creates a convenient script object to deal with java.util.Map instances.
* The result script object's field names are keys of the Map. For example,
* scriptObj.keyName can be used to access value associated with given key.<br>
* Example:
* <pre>
* <code>
* var x = java.lang.SystemProperties();
* var y = jmap(x);
* println(y['java.class.path']); // prints java.class.path System property
* delete y['java.class.path']; // remove java.class.path System property
* </code>
* </pre>
*
* @param map java.util.Map instance that will be wrapped
* @constructor
*/
function jmap(map) {
return new JSAdapter({
__get__ : function(name) {
if (map.containsKey(name)) {
return map.get(name);
} else {
return undefined;
}
},
__has__ : function(name) {
return map.containsKey(name);
},
__delete__ : function (name) {
return map.remove(name);
},
__put__ : function(name, value) {
map.put(name, value);
},
__getIds__ : function() {
return map.keySet().toArray();
},
toString: function() {
return map.toString();
}
});
}
/**
* Creates a convenient script object to deal with java.util.List instances.
* The result script object behaves like an array. For example,
* scriptObj[index] syntax can be used to access values in the List instance.
* 'length' field gives size of the List. <br>
*
* Example:
* <pre>
* <code>
* var x = new java.util.ArrayList(4);
* x.add('Java');
* x.add('JavaScript');
* x.add('SQL');
* x.add('XML');
*
* var y = jlist(x);
* println(y[2]); // prints third element of list
* println(y.length); // prints size of the list
*
* @param map java.util.List instance that will be wrapped
* @constructor
*/
function jlist(list) {
function isValid(index) {
return typeof(index) == 'number' &&
index > -1 && index < list.size();
}
return new JSAdapter({
__get__ : function(name) {
if (isValid(name)) {
return list.get(name);
} else if (name == 'length') {
return list.size();
} else {
return undefined;
}
},
__has__ : function (name) {
return isValid(name) || name == 'length';
},
__delete__ : function(name) {
if (isValid(name)) {
list.remove(name);
}
},
__put__ : function(name, value) {
if (isValid(name)) {
list.set(name, value);
}
},
__getIds__: function() {
var res = new Array(list.size());
for (var i = 0; i < res.length; i++) {
res[i] = i;
}
return res;
},
toString: function() {
return list.toString();
}
});
}
/**
* This is java.lang.System properties wrapped by JSAdapter.
* For eg. to access java.class.path property, you can use
* the syntax sysProps["java.class.path"]
*/
var sysProps = new JSAdapter({
__get__ : function (name) {
return java.lang.System.getProperty(name);
},
__has__ : function (name) {
return java.lang.System.getProperty(name) != null;
},
__getIds__ : function() {
return java.lang.System.getProperties().keySet().toArray();
},
__delete__ : function(name) {
java.lang.System.clearProperty(name);
return true;
},
__put__ : function (name, value) {
java.lang.System.setProperty(name, value);
},
toString: function() {
return "<system properties>";
}
});
// stdout, stderr & stdin
var out = java.lang.System.out;
var err = java.lang.System.err;
// can't use 'in' because it is a JavaScript keyword :-(
var inp = java.lang.System["in"];
var BufferedInputStream = java.io.BufferedInputStream;
var BufferedOutputStream = java.io.BufferedOutputStream;
var BufferedReader = java.io.BufferedReader;
var DataInputStream = java.io.DataInputStream;
var File = java.io.File;
var FileInputStream = java.io.FileInputStream;
var FileOutputStream = java.io.FileOutputStream;
var InputStream = java.io.InputStream;
var InputStreamReader = java.io.InputStreamReader;
var OutputStream = java.io.OutputStream;
var Reader = java.io.Reader;
var URL = java.net.URL;
/**
* Generic any object to input stream mapper
* @param str input file name, URL or InputStream
* @return InputStream object
* @private
*/
function inStream(str) {
if (typeof(str) == "string") {
// '-' means standard input
if (str == '-') {
return java.lang.System["in"];
}
// try file first
var file = null;
try {
file = pathToFile(str);
} catch (e) {
}
if (file && file.exists()) {
return new FileInputStream(file);
} else {
try {
// treat the string as URL
return new URL(str).openStream();
} catch (e) {
throw 'file or URL ' + str + ' not found';
}
}
} else {
if (str instanceof InputStream) {
return str;
} else if (str instanceof URL) {
return str.openStream();
} else if (str instanceof File) {
return new FileInputStream(str);
}
}
// everything failed, just give input stream
return java.lang.System["in"];
}
/**
* Generic any object to output stream mapper
*
* @param out output file name or stream
* @return OutputStream object
* @private
*/
function outStream(out) {
if (typeof(out) == "string") {
if (out == '>') {
return java.lang.System.out;
} else {
// treat it as file
return new FileOutputStream(pathToFile(out));
}
} else {
if (out instanceof OutputStream) {
return out;
} else if (out instanceof File) {
return new FileOutputStream(out);
}
}
// everything failed, just return System.out
return java.lang.System.out;
}
/**
* stream close takes care not to close stdin, out & err.
* @private
*/
function streamClose(stream) {
if (stream) {
if (stream != java.lang.System["in"] &&
stream != java.lang.System.out &&
stream != java.lang.System.err) {
try {
stream.close();
} catch (e) {
println(e);
}
}
}
}
/**
* Loads and evaluates JavaScript code from a stream or file or URL<br>
*
* Examples:
* <pre>
* <code>
* load('test.js'); // load script file 'test.js'
* load('http://java.sun.com/foo.js'); // load from a URL
* </code>
* </pre>
*
* @param str input from which script is loaded and evaluated
*/
if (typeof(load) == 'undefined') {
this.load = function(str) {
var stream = inStream(str);
var bstream = new BufferedInputStream(stream);
var reader = new BufferedReader(new InputStreamReader(bstream));
var oldFilename = engine.get(engine.FILENAME);
engine.put(engine.FILENAME, str);
try {
engine.eval(reader);
} finally {
engine.put(engine.FILENAME, oldFilename);
streamClose(stream);
}
}
}
// file system utilities
/**
* Creates a Java byte[] of given length
* @param len size of the array to create
* @private
*/
function javaByteArray(len) {
return java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, len);
}
var curDir = new File('.');
/**
* Print present working directory
*/
function pwd() {
println(curDir.getAbsolutePath());
}
/**
* Changes present working directory to given directory
* @param target directory to change to. optional, defaults to user's HOME
*/
function cd(target) {
if (target == undefined) {
target = sysProps["user.home"];
}
if (!(target instanceof File)) {
target = pathToFile(target);
}
if (target.exists() && target.isDirectory()) {
curDir = target;
} else {
println(target + " is not a directory");
}
}
/**
* Converts path to java.io.File taking care of shell present working dir
*
* @param pathname file path to be converted
* @private
*/
function pathToFile(pathname) {
var tmp = pathname;
if (!(tmp instanceof File)) {
tmp = new File(tmp);
}
if (!tmp.isAbsolute()) {
return new File(curDir, pathname);
} else {
return tmp;
}
}
/**
* Copies a file or URL or stream to another file or stream
*
* @param from input file or URL or stream
* @param to output stream or file
*/
function cp(from, to) {
if (from == to) {
println("file " + from + " cannot be copied onto itself!");
return;
}
var inp = inStream(from);
var out = outStream(to);
var binp = new BufferedInputStream(inp);
var bout = new BufferedOutputStream(out);
var buff = javaByteArray(1024);
var len;
while ((len = binp.read(buff)) > 0 )
bout.write(buff, 0, len);
bout.flush();
streamClose(inp);
streamClose(out);
}
/**
* Shows the content of a file or URL or any InputStream<br>
* Examples:
* <pre>
* <code>
* cat('test.txt'); // show test.txt file contents
* cat('http://java.net'); // show the contents from the URL http://java.net
* </code>
* </pre>
* @param obj input to show
* @param pattern optional. show only the lines matching the pattern
*/
function cat(obj, pattern) {
if (obj instanceof File && obj.isDirectory()) {
ls(obj);
return;
}
var inp = null;
if (!(obj instanceof Reader)) {
inp = inStream(obj);
obj = new BufferedReader(new InputStreamReader(inp));
}
var line;
if (pattern) {
var count = 1;
while ((line=obj.readLine()) != null) {
if (line.match(pattern)) {
println(count + "\t: " + line);
}
count++;
}
} else {
while ((line=obj.readLine()) != null) {
println(line);
}
}
}
/**
* Returns directory part of a filename
*
* @param pathname input path name
* @return directory part of the given file name
*/
function dirname(pathname) {
var dirName = ".";
// Normalize '/' to local file separator before work.
var i = pathname.replace('/', File.separatorChar ).lastIndexOf(
File.separator );
if ( i != -1 )
dirName = pathname.substring(0, i);
return dirName;
}
/**
* Creates a new dir of given name
*
* @param dir name of the new directory
*/
function mkdir(dir) {
dir = pathToFile(dir);
println(dir.mkdir()? "created" : "can not create dir");
}
/**
* Creates the directory named by given pathname, including
* any necessary but nonexistent parent directories.
*
* @param dir input path name
*/
function mkdirs(dir) {
dir = pathToFile(dir);
println(dir.mkdirs()? "created" : "can not create dirs");
}
/**
* Removes a given file
*
* @param pathname name of the file
*/
function rm(pathname) {
var file = pathToFile(pathname);
if (!file.exists()) {
println("file not found: " + pathname);
return false;
}
// note that delete is a keyword in JavaScript!
println(file["delete"]()? "deleted" : "can not delete");
}
/**
* Removes a given directory
*
* @param pathname name of the directory
*/
function rmdir(pathname) {
rm(pathname);
}
/**
* Synonym for 'rm'
*/
function del(pathname) {
rm(pathname);
}
/**
* Moves a file to another
*
* @param from original name of the file
* @param to new name for the file
*/
function mv(from, to) {
println(pathToFile(from).renameTo(pathToFile(to))?
"moved" : "can not move");
}
/**
* Synonym for 'mv'.
*/
function ren(from, to) {
mv(from, to);
}
var months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
/**
* Helper function called by ls
* @private
*/
function printFile(f) {
var sb = new java.lang.StringBuffer();
sb.append(f.isDirectory()? "d" : "-");
sb.append(f.canRead() ? "r": "-" );
sb.append(f.canWrite() ? "w": "-" );
sb.append(" ");
var d = new java.util.Date(f.lastModified());
var c = new java.util.GregorianCalendar();
c.setTime(d);
var day = c.get(java.util.Calendar.DAY_OF_MONTH);
sb.append(months[c.get(java.util.Calendar.MONTH)]
+ " " + day );
if (day < 10) {
sb.append(" ");
}
// to get fixed length 'length' field
var fieldlen = 8;
var len = new java.lang.StringBuffer();
for(var j=0; j<fieldlen; j++)
len.append(" ");
len.insert(0, java.lang.Long.toString(f.length()));
len.setLength(fieldlen);
// move the spaces to the front
var si = len.toString().indexOf(" ");
if ( si != -1 ) {
var pad = len.toString().substring(si);
len.setLength(si);
len.insert(0, pad);
}
sb.append(len.toString());
sb.append(" ");
sb.append(f.getName());
if (f.isDirectory()) {
sb.append('/');
}
println(sb.toString());
}
/**
* Lists the files in a directory
*
* @param dir directory from which to list the files. optional, default to pwd
* @param filter pattern to filter the files listed. optional, default is '.'.
*/
function ls(dir, filter) {
if (dir) {
dir = pathToFile(dir);
} else {
dir = curDir;
}
if (dir.isDirectory()) {
var files = dir.listFiles();
for (var i in files) {
var f = files[i];
if (filter) {
if(!f.getName().match(filter)) {
continue;
}
}
printFile(f);
}
} else {
printFile(dir);
}
}
/**
* Synonym for 'ls'.
*/
function dir(d, filter) {
ls(d, filter);
}
/**
* Unix-like grep, but accepts JavaScript regex patterns
*
* @param pattern to search in files
* @param files one or more files
*/
function grep(pattern, files /*, one or more files */) {
if (arguments.length < 2) return;
for (var i = 1; i < arguments.length; i++) {
println(arguments[i] + ":");
cat(arguments[i], pattern);
}
}
/**
* Find in files. Calls arbitrary callback function
* for each matching file.<br>
*
* Examples:
* <pre>
* <code>
* find('.')
* find('.', '.*\.class', rm); // remove all .class files
* find('.', '.*\.java'); // print fullpath of each .java file
* find('.', '.*\.java', cat); // print all .java files
* </code>
* </pre>
*
* @param dir directory to search files
* @param pattern to search in the files
* @param callback function to call for matching files
*/
function find(dir, pattern, callback) {
dir = pathToFile(dir);
if (!callback) callback = print;
var files = dir.listFiles();
for (var f in files) {
var file = files[f];
if (file.isDirectory()) {
find(file, pattern, callback);
} else {
if (pattern) {
if (file.getName().match(pattern)) {
callback(file);
}
} else {
callback(file);
}
}
}
}
// process utilities
/**
* Exec's a child process, waits for completion &amp; returns exit code
*
* @param cmd command to execute in child process
*/
function exec(cmd) {
var process = java.lang.Runtime.getRuntime().exec(cmd);
var inp = new DataInputStream(process.getInputStream());
var line = null;
while ((line = inp.readLine()) != null) {
println(line);
}
process.waitFor();
$exit = process.exitValue();
}
if (typeof(exit) == 'undefined') {
/**
* Exit the shell program.
*
* @param exitCode integer code returned to OS shell.
* optional, defaults to 0
*/
this.exit = function (code) {
if (code) {
java.lang.System.exit(code + 0);
} else {
java.lang.System.exit(0);
}
}
}
if (typeof(quit) == 'undefined') {
/**
* synonym for exit
*/
this.quit = function (code) {
exit(code);
}
}
// XML utilities
/**
* Converts input to DOM Document object
*
* @param inp file or reader. optional, without this param,
* this function returns a new DOM Document.
* @return returns a DOM Document object
*/
function XMLDocument(inp) {
var factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
var builder = factory.newDocumentBuilder();
if (inp) {
if (typeof(inp) == "string") {
return builder.parse(pathToFile(inp));
} else {
return builder.parse(inp);
}
} else {
return builder.newDocument();
}
}
/**
* Converts arbitrary stream, file, URL to XMLSource
*
* @param inp input stream or file or URL
* @return XMLSource object
*/
function XMLSource(inp) {
if (inp instanceof javax.xml.transform.Source) {
return inp;
} else if (inp instanceof Packages.org.w3c.dom.Document) {
return new javax.xml.transform.dom.DOMSource(inp);
} else {
inp = new BufferedInputStream(inStream(inp));
return new javax.xml.transform.stream.StreamSource(inp);
}
}
/**
* Converts arbitrary stream, file to XMLResult
*
* @param inp output stream or file
* @return XMLResult object
*/
function XMLResult(out) {
if (out instanceof javax.xml.transform.Result) {
return out;
} else if (out instanceof Packages.org.w3c.dom.Document) {
return new javax.xml.transform.dom.DOMResult(out);
} else {
out = new BufferedOutputStream(outStream(out));
return new javax.xml.transform.stream.StreamResult(out);
}
}
/**
* Perform XSLT transform
*
* @param inp Input XML to transform (URL, File or InputStream)
* @param style XSL Stylesheet to be used (URL, File or InputStream). optional.
* @param out Output XML (File or OutputStream
*/
function XSLTransform(inp, style, out) {
switch (arguments.length) {
case 2:
inp = arguments[0];
out = arguments[1];
break;
case 3:
inp = arguments[0];
style = arguments[1];
out = arguments[2];
break;
default:
println("XSL transform requires 2 or 3 arguments");
return;
}
var factory = javax.xml.transform.TransformerFactory.newInstance();
var transformer;
if (style) {
transformer = factory.newTransformer(XMLSource(style));
} else {
transformer = factory.newTransformer();
}
var source = XMLSource(inp);
var result = XMLResult(out);
transformer.transform(source, result);
if (source.getInputStream) {
streamClose(source.getInputStream());
}
if (result.getOutputStream) {
streamClose(result.getOutputStream());
}
}
// miscellaneous utilities
/**
* Prints which command is selected from PATH
*
* @param cmd name of the command searched from PATH
*/
function which(cmd) {
var st = new java.util.StringTokenizer(env.PATH, File.pathSeparator);
while (st.hasMoreTokens()) {
var file = new File(st.nextToken(), cmd);
if (file.exists()) {
println(file.getAbsolutePath());
return;
}
}
}
/**
* Prints IP addresses of given domain name
*
* @param name domain name
*/
function ip(name) {
var addrs = InetAddress.getAllByName(name);
for (var i in addrs) {
println(addrs[i]);
}
}
/**
* Prints current date in current locale
*/
function date() {
println(new Date().toLocaleString());
}
/**
* Echoes the given string arguments
*/
function echo(x) {
for (var i = 0; i < arguments.length; i++) {
println(arguments[i]);
}
}
if (typeof(printf) == 'undefined') {
/**
* This is C-like printf
*
* @param format string to format the rest of the print items
* @param args variadic argument list
*/
this.printf = function (format, args/*, more args*/) {
var array = java.lang.reflect.Array.newInstance(java.lang.Object,
arguments.length - 1);
for (var i = 0; i < array.length; i++) {
array[i] = arguments[i+1];
}
java.lang.System.out.printf(format, array);
}
}
/**
* Reads one or more lines from stdin after printing prompt
*
* @param prompt optional, default is '>'
* @param multiline to tell whether to read single line or multiple lines
*/
function read(prompt, multiline) {
if (!prompt) {
prompt = '>';
}
var inp = java.lang.System["in"];
var reader = new BufferedReader(new InputStreamReader(inp));
if (multiline) {
var line = '';
while (true) {
java.lang.System.err.print(prompt);
java.lang.System.err.flush();
var tmp = reader.readLine();
if (tmp == '' || tmp == null) break;
line += tmp + '\n';
}
return line;
} else {
java.lang.System.err.print(prompt);
java.lang.System.err.flush();
return reader.readLine();
}
}
if (typeof(println) == 'undefined') {
// just synonym to print
this.println = print;
}

View file

@ -0,0 +1,66 @@
#
# Copyright (c) 2005, 2013, 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.
#
string.script.error=\
script error: {0}
file.script.error=\
script error in file {0} : {1}
file.not.found=\
script file {0} is not found
engine.not.found=\
script engine for language {0} can not be found
engine.info=\
Language {0} {1} implementation "{2}" {3}
encoding.unsupported=\
encoding {0} is not supported
main.usage=\
Usage: {0} [options] [arguments...]\n\
\n\
where [options] include:\n\
\ \-classpath <path> Specify where to find user class files \n\
\ \-cp <path> Specify where to find user class files \n\
\ \-D<name>=<value> Set a system property \n\
\ \-J<flag> Pass <flag> directly to the runtime system \n\
\ \-l <language> Use specified scripting language \n\
\ \-e <script> Evaluate given script \n\
\ \-encoding <encoding> Specify character encoding used by script files \n\
\ \-f <script file> Evaluate given script file \n\
\ \-f - Interactive mode, read script from standard input \n\
\ \ If this is used, this should be the last -f option \n\
\ \-help Print this usage message and exit \n\
\ \-? Print this usage message and exit \n\
\ \-q List all scripting engines available and exit \n\
\ \n\
If [arguments..] are present and if no -e or -f option is used, then first\n\
argument is script file and the rest of the arguments, if any, are passed\n\
as script arguments. If [arguments..] and -e or -f option is used, then all\n\
[arguments..] are passed as script arguments. If [arguments..], -e, -f are\n\
missing, then interactive mode is used.

View file

@ -0,0 +1,311 @@
/*
* Copyright (c) 2005, 2013, 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 javax.script;
import java.io.Reader;
import java.util.Map;
import java.util.Iterator;
/**
* Provides a standard implementation for several of the variants of the <code>eval</code>
* method.
* <br><br>
* <code><b>eval(Reader)</b></code><p><code><b>eval(String)</b></code><p>
* <code><b>eval(String, Bindings)</b></code><p><code><b>eval(Reader, Bindings)</b></code>
* <br><br> are implemented using the abstract methods
* <br><br>
* <code><b>eval(Reader,ScriptContext)</b></code> or
* <code><b>eval(String, ScriptContext)</b></code>
* <br><br>
* with a <code>SimpleScriptContext</code>.
* <br><br>
* A <code>SimpleScriptContext</code> is used as the default <code>ScriptContext</code>
* of the <code>AbstractScriptEngine</code>..
*
* @author Mike Grogan
* @since 1.6
*/
public abstract class AbstractScriptEngine implements ScriptEngine {
/**
* The default <code>ScriptContext</code> of this <code>AbstractScriptEngine</code>.
*/
protected ScriptContext context;
/**
* Creates a new instance of AbstractScriptEngine using a <code>SimpleScriptContext</code>
* as its default <code>ScriptContext</code>.
*/
public AbstractScriptEngine() {
context = new SimpleScriptContext();
}
/**
* Creates a new instance using the specified <code>Bindings</code> as the
* <code>ENGINE_SCOPE</code> <code>Bindings</code> in the protected <code>context</code> field.
*
* @param n The specified <code>Bindings</code>.
* @throws NullPointerException if n is null.
*/
public AbstractScriptEngine(Bindings n) {
this();
if (n == null) {
throw new NullPointerException("n is null");
}
context.setBindings(n, ScriptContext.ENGINE_SCOPE);
}
/**
* Sets the value of the protected <code>context</code> field to the specified
* <code>ScriptContext</code>.
*
* @param ctxt The specified <code>ScriptContext</code>.
* @throws NullPointerException if ctxt is null.
*/
public void setContext(ScriptContext ctxt) {
if (ctxt == null) {
throw new NullPointerException("null context");
}
context = ctxt;
}
/**
* Returns the value of the protected <code>context</code> field.
*
* @return The value of the protected <code>context</code> field.
*/
public ScriptContext getContext() {
return context;
}
/**
* Returns the <code>Bindings</code> with the specified scope value in
* the protected <code>context</code> field.
*
* @param scope The specified scope
*
* @return The corresponding <code>Bindings</code>.
*
* @throws IllegalArgumentException if the value of scope is
* invalid for the type the protected <code>context</code> field.
*/
public Bindings getBindings(int scope) {
if (scope == ScriptContext.GLOBAL_SCOPE) {
return context.getBindings(ScriptContext.GLOBAL_SCOPE);
} else if (scope == ScriptContext.ENGINE_SCOPE) {
return context.getBindings(ScriptContext.ENGINE_SCOPE);
} else {
throw new IllegalArgumentException("Invalid scope value.");
}
}
/**
* Sets the <code>Bindings</code> with the corresponding scope value in the
* <code>context</code> field.
*
* @param bindings The specified <code>Bindings</code>.
* @param scope The specified scope.
*
* @throws IllegalArgumentException if the value of scope is
* invalid for the type the <code>context</code> field.
* @throws NullPointerException if the bindings is null and the scope is
* <code>ScriptContext.ENGINE_SCOPE</code>
*/
public void setBindings(Bindings bindings, int scope) {
if (scope == ScriptContext.GLOBAL_SCOPE) {
context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);;
} else if (scope == ScriptContext.ENGINE_SCOPE) {
context.setBindings(bindings, ScriptContext.ENGINE_SCOPE);;
} else {
throw new IllegalArgumentException("Invalid scope value.");
}
}
/**
* Sets the specified value with the specified key in the <code>ENGINE_SCOPE</code>
* <code>Bindings</code> of the protected <code>context</code> field.
*
* @param key The specified key.
* @param value The specified value.
*
* @throws NullPointerException if key is null.
* @throws IllegalArgumentException if key is empty.
*/
public void put(String key, Object value) {
Bindings nn = getBindings(ScriptContext.ENGINE_SCOPE);
if (nn != null) {
nn.put(key, value);
}
}
/**
* Gets the value for the specified key in the <code>ENGINE_SCOPE</code> of the
* protected <code>context</code> field.
*
* @return The value for the specified key.
*
* @throws NullPointerException if key is null.
* @throws IllegalArgumentException if key is empty.
*/
public Object get(String key) {
Bindings nn = getBindings(ScriptContext.ENGINE_SCOPE);
if (nn != null) {
return nn.get(key);
}
return null;
}
/**
* <code>eval(Reader, Bindings)</code> calls the abstract
* <code>eval(Reader, ScriptContext)</code> method, passing it a <code>ScriptContext</code>
* whose Reader, Writers and Bindings for scopes other that <code>ENGINE_SCOPE</code>
* are identical to those members of the protected <code>context</code> field. The specified
* <code>Bindings</code> is used instead of the <code>ENGINE_SCOPE</code>
*
* <code>Bindings</code> of the <code>context</code> field.
*
* @param reader A <code>Reader</code> containing the source of the script.
* @param bindings A <code>Bindings</code> to use for the <code>ENGINE_SCOPE</code>
* while the script executes.
*
* @return The return value from <code>eval(Reader, ScriptContext)</code>
* @throws ScriptException if an error occurs in script.
* @throws NullPointerException if any of the parameters is null.
*/
public Object eval(Reader reader, Bindings bindings ) throws ScriptException {
ScriptContext ctxt = getScriptContext(bindings);
return eval(reader, ctxt);
}
/**
* Same as <code>eval(Reader, Bindings)</code> except that the abstract
* <code>eval(String, ScriptContext)</code> is used.
*
* @param script A <code>String</code> containing the source of the script.
*
* @param bindings A <code>Bindings</code> to use as the <code>ENGINE_SCOPE</code>
* while the script executes.
*
* @return The return value from <code>eval(String, ScriptContext)</code>
* @throws ScriptException if an error occurs in script.
* @throws NullPointerException if any of the parameters is null.
*/
public Object eval(String script, Bindings bindings) throws ScriptException {
ScriptContext ctxt = getScriptContext(bindings);
return eval(script , ctxt);
}
/**
* <code>eval(Reader)</code> calls the abstract
* <code>eval(Reader, ScriptContext)</code> passing the value of the <code>context</code>
* field.
*
* @param reader A <code>Reader</code> containing the source of the script.
* @return The return value from <code>eval(Reader, ScriptContext)</code>
* @throws ScriptException if an error occurs in script.
* @throws NullPointerException if any of the parameters is null.
*/
public Object eval(Reader reader) throws ScriptException {
return eval(reader, context);
}
/**
* Same as <code>eval(Reader)</code> except that the abstract
* <code>eval(String, ScriptContext)</code> is used.
*
* @param script A <code>String</code> containing the source of the script.
* @return The return value from <code>eval(String, ScriptContext)</code>
* @throws ScriptException if an error occurs in script.
* @throws NullPointerException if any of the parameters is null.
*/
public Object eval(String script) throws ScriptException {
return eval(script, context);
}
/**
* Returns a <code>SimpleScriptContext</code>. The <code>SimpleScriptContext</code>:
*<br><br>
* <ul>
* <li>Uses the specified <code>Bindings</code> for its <code>ENGINE_SCOPE</code>
* </li>
* <li>Uses the <code>Bindings</code> returned by the abstract <code>getGlobalScope</code>
* method as its <code>GLOBAL_SCOPE</code>
* </li>
* <li>Uses the Reader and Writer in the default <code>ScriptContext</code> of this
* <code>ScriptEngine</code>
* </li>
* </ul>
* <br><br>
* A <code>SimpleScriptContext</code> returned by this method is used to implement eval methods
* using the abstract <code>eval(Reader,Bindings)</code> and <code>eval(String,Bindings)</code>
* versions.
*
* @param nn Bindings to use for the <code>ENGINE_SCOPE</code>
* @return The <code>SimpleScriptContext</code>
*/
protected ScriptContext getScriptContext(Bindings nn) {
SimpleScriptContext ctxt = new SimpleScriptContext();
Bindings gs = getBindings(ScriptContext.GLOBAL_SCOPE);
if (gs != null) {
ctxt.setBindings(gs, ScriptContext.GLOBAL_SCOPE);
}
if (nn != null) {
ctxt.setBindings(nn,
ScriptContext.ENGINE_SCOPE);
} else {
throw new NullPointerException("Engine scope Bindings may not be null.");
}
ctxt.setReader(context.getReader());
ctxt.setWriter(context.getWriter());
ctxt.setErrorWriter(context.getErrorWriter());
return ctxt;
}
}

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 2005, 2006, 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 javax.script;
import java.util.Map;
/**
* A mapping of key/value pairs, all of whose keys are
* {@code Strings}.
*
* @author Mike Grogan
* @since 1.6
*/
public interface Bindings extends Map<String, Object> {
/**
* Set a named value.
*
* @param name The name associated with the value.
* @param value The value associated with the name.
*
* @return The value previously associated with the given name.
* Returns null if no value was previously associated with the name.
*
* @throws NullPointerException if the name is null.
* @throws IllegalArgumentException if the name is empty String.
*/
public Object put(String name, Object value);
/**
* Adds all the mappings in a given {@code Map} to this {@code Bindings}.
* @param toMerge The {@code Map} to merge with this one.
*
* @throws NullPointerException
* if toMerge map is null or if some key in the map is null.
* @throws IllegalArgumentException
* if some key in the map is an empty String.
*/
public void putAll(Map<? extends String, ? extends Object> toMerge);
/**
* Returns {@code true} if this map contains a mapping for the specified
* key. More formally, returns {@code true} if and only if
* this map contains a mapping for a key {@code k} such that
* {@code (key==null ? k==null : key.equals(k))}. (There can be
* at most one such mapping.)
*
* @param key key whose presence in this map is to be tested.
* @return {@code true} if this map contains a mapping for the specified
* key.
*
* @throws NullPointerException if key is null
* @throws ClassCastException if key is not String
* @throws IllegalArgumentException if key is empty String
*/
public boolean containsKey(Object key);
/**
* Returns the value to which this map maps the specified key. Returns
* {@code null} if the map contains no mapping for this key. A return
* value of {@code null} does not <i>necessarily</i> indicate that the
* map contains no mapping for the key; it's also possible that the map
* explicitly maps the key to {@code null}. The {@code containsKey}
* operation may be used to distinguish these two cases.
*
* <p>More formally, if this map contains a mapping from a key
* {@code k} to a value {@code v} such that
* {@code (key==null ? k==null : key.equals(k))},
* then this method returns {@code v}; otherwise
* it returns {@code null}. (There can be at most one such mapping.)
*
* @param key key whose associated value is to be returned.
* @return the value to which this map maps the specified key, or
* {@code null} if the map contains no mapping for this key.
*
* @throws NullPointerException if key is null
* @throws ClassCastException if key is not String
* @throws IllegalArgumentException if key is empty String
*/
public Object get(Object key);
/**
* Removes the mapping for this key from this map if it is present
* (optional operation). More formally, if this map contains a mapping
* from key {@code k} to value {@code v} such that
* {@code (key==null ? k==null : key.equals(k))}, that mapping
* is removed. (The map can contain at most one such mapping.)
*
* <p>Returns the value to which the map previously associated the key, or
* {@code null} if the map contained no mapping for this key. (A
* {@code null} return can also indicate that the map previously
* associated {@code null} with the specified key if the implementation
* supports {@code null} values.) The map will not contain a mapping for
* the specified key once the call returns.
*
* @param key key whose mapping is to be removed from the map.
* @return previous value associated with specified key, or {@code null}
* if there was no mapping for key.
*
* @throws NullPointerException if key is null
* @throws ClassCastException if key is not String
* @throws IllegalArgumentException if key is empty String
*/
public Object remove(Object key);
}

View file

@ -0,0 +1,72 @@
/*
* 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 javax.script;
import java.util.Map;
import java.io.Reader;
/**
* The optional interface implemented by ScriptEngines whose methods compile scripts
* to a form that can be executed repeatedly without recompilation.
*
* @author Mike Grogan
* @since 1.6
*/
public interface Compilable {
/**
* Compiles the script (source represented as a <code>String</code>) for
* later execution.
*
* @param script The source of the script, represented as a <code>String</code>.
*
* @return An instance of a subclass of <code>CompiledScript</code> to be executed later using one
* of the <code>eval</code> methods of <code>CompiledScript</code>.
*
* @throws ScriptException if compilation fails.
* @throws NullPointerException if the argument is null.
*
*/
public CompiledScript compile(String script) throws
ScriptException;
/**
* Compiles the script (source read from <code>Reader</code>) for
* later execution. Functionality is identical to
* <code>compile(String)</code> other than the way in which the source is
* passed.
*
* @param script The reader from which the script source is obtained.
*
* @return An instance of a subclass of <code>CompiledScript</code> to be executed
* later using one of its <code>eval</code> methods of <code>CompiledScript</code>.
*
* @throws ScriptException if compilation fails.
* @throws NullPointerException if argument is null.
*/
public CompiledScript compile(Reader script) throws
ScriptException;
}

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 2005, 2013, 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 javax.script;
import java.util.Map;
/**
* Extended by classes that store results of compilations. State
* might be stored in the form of Java classes, Java class files or scripting
* language opcodes. The script may be executed repeatedly
* without reparsing.
* <br><br>
* Each <code>CompiledScript</code> is associated with a <code>ScriptEngine</code> -- A call to an <code>eval</code>
* method of the <code>CompiledScript</code> causes the execution of the script by the
* <code>ScriptEngine</code>. Changes in the state of the <code>ScriptEngine</code> caused by execution
* of the <code>CompiledScript</code> may visible during subsequent executions of scripts by the engine.
*
* @author Mike Grogan
* @since 1.6
*/
public abstract class CompiledScript {
/**
* Executes the program stored in this <code>CompiledScript</code> object.
*
* @param context A <code>ScriptContext</code> that is used in the same way as
* the <code>ScriptContext</code> passed to the <code>eval</code> methods of
* <code>ScriptEngine</code>.
*
* @return The value returned by the script execution, if any. Should return <code>null</code>
* if no value is returned by the script execution.
*
* @throws ScriptException if an error occurs.
* @throws NullPointerException if context is null.
*/
public abstract Object eval(ScriptContext context) throws ScriptException;
/**
* Executes the program stored in the <code>CompiledScript</code> object using
* the supplied <code>Bindings</code> of attributes as the <code>ENGINE_SCOPE</code> of the
* associated <code>ScriptEngine</code> during script execution. If bindings is null,
* then the effect of calling this method is same as that of eval(getEngine().getContext()).
* <p>.
* The <code>GLOBAL_SCOPE</code> <code>Bindings</code>, <code>Reader</code> and <code>Writer</code>
* associated with the default <code>ScriptContext</code> of the associated <code>ScriptEngine</code> are used.
*
* @param bindings The bindings of attributes used for the <code>ENGINE_SCOPE</code>.
*
* @return The return value from the script execution
*
* @throws ScriptException if an error occurs.
*/
public Object eval(Bindings bindings) throws ScriptException {
ScriptContext ctxt = getEngine().getContext();
if (bindings != null) {
SimpleScriptContext tempctxt = new SimpleScriptContext();
tempctxt.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
tempctxt.setBindings(ctxt.getBindings(ScriptContext.GLOBAL_SCOPE),
ScriptContext.GLOBAL_SCOPE);
tempctxt.setWriter(ctxt.getWriter());
tempctxt.setReader(ctxt.getReader());
tempctxt.setErrorWriter(ctxt.getErrorWriter());
ctxt = tempctxt;
}
return eval(ctxt);
}
/**
* Executes the program stored in the <code>CompiledScript</code> object. The
* default <code>ScriptContext</code> of the associated <code>ScriptEngine</code> is used.
* The effect of calling this method is same as that of eval(getEngine().getContext()).
*
* @return The return value from the script execution
*
* @throws ScriptException if an error occurs.
*/
public Object eval() throws ScriptException {
return eval(getEngine().getContext());
}
/**
* Returns the <code>ScriptEngine</code> whose <code>compile</code> method created this <code>CompiledScript</code>.
* The <code>CompiledScript</code> will execute in this engine.
*
* @return The <code>ScriptEngine</code> that created this <code>CompiledScript</code>
*/
public abstract ScriptEngine getEngine();
}

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2005, 2013, 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 javax.script;
/**
* The optional interface implemented by ScriptEngines whose methods allow the invocation of
* procedures in scripts that have previously been executed.
*
* @author Mike Grogan
* @author A. Sundararajan
* @since 1.6
*/
public interface Invocable {
/**
* Calls a method on a script object compiled during a previous script execution,
* which is retained in the state of the <code>ScriptEngine</code>.
*
* @param name The name of the procedure to be called.
*
* @param thiz If the procedure is a member of a class
* defined in the script and thiz is an instance of that class
* returned by a previous execution or invocation, the named method is
* called through that instance.
*
* @param args Arguments to pass to the procedure. The rules for converting
* the arguments to scripting variables are implementation-specific.
*
* @return The value returned by the procedure. The rules for converting the scripting
* variable returned by the script method to a Java Object are implementation-specific.
*
* @throws ScriptException if an error occurs during invocation of the method.
* @throws NoSuchMethodException if method with given name or matching argument types cannot be found.
* @throws NullPointerException if the method name is null.
* @throws IllegalArgumentException if the specified thiz is null or the specified Object is
* does not represent a scripting object.
*/
public Object invokeMethod(Object thiz, String name, Object... args)
throws ScriptException, NoSuchMethodException;
/**
* Used to call top-level procedures and functions defined in scripts.
*
* @param name of the procedure or function to call
* @param args Arguments to pass to the procedure or function
* @return The value returned by the procedure or function
*
* @throws ScriptException if an error occurs during invocation of the method.
* @throws NoSuchMethodException if method with given name or matching argument types cannot be found.
* @throws NullPointerException if method name is null.
*/
public Object invokeFunction(String name, Object... args)
throws ScriptException, NoSuchMethodException;
/**
* Returns an implementation of an interface using functions compiled in
* the interpreter. The methods of the interface
* may be implemented using the <code>invokeFunction</code> method.
*
* @param <T> the type of the interface to return
* @param clasz The <code>Class</code> object of the interface to return.
*
* @return An instance of requested interface - null if the requested interface is unavailable,
* i. e. if compiled functions in the <code>ScriptEngine</code> cannot be found matching
* the ones in the requested interface.
*
* @throws IllegalArgumentException if the specified <code>Class</code> object
* is null or is not an interface.
*/
public <T> T getInterface(Class<T> clasz);
/**
* Returns an implementation of an interface using member functions of
* a scripting object compiled in the interpreter. The methods of the
* interface may be implemented using the <code>invokeMethod</code> method.
*
* @param <T> the type of the interface to return
* @param thiz The scripting object whose member functions are used to implement the methods of the interface.
* @param clasz The <code>Class</code> object of the interface to return.
*
* @return An instance of requested interface - null if the requested interface is unavailable,
* i. e. if compiled methods in the <code>ScriptEngine</code> cannot be found matching
* the ones in the requested interface.
*
* @throws IllegalArgumentException if the specified <code>Class</code> object
* is null or is not an interface, or if the specified Object is
* null or does not represent a scripting object.
*/
public <T> T getInterface(Object thiz, Class<T> clasz);
}

View file

@ -0,0 +1,208 @@
/*
* Copyright (c) 2005, 2013, 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 javax.script;
import java.util.List;
import java.io.Writer;
import java.io.Reader;
/**
* The interface whose implementing classes are used to connect Script Engines
* with objects, such as scoped Bindings, in hosting applications. Each scope is a set
* of named attributes whose values can be set and retrieved using the
* <code>ScriptContext</code> methods. ScriptContexts also expose Readers and Writers
* that can be used by the ScriptEngines for input and output.
*
* @author Mike Grogan
* @since 1.6
*/
public interface ScriptContext {
/**
* EngineScope attributes are visible during the lifetime of a single
* <code>ScriptEngine</code> and a set of attributes is maintained for each
* engine.
*/
public static final int ENGINE_SCOPE = 100;
/**
* GlobalScope attributes are visible to all engines created by same ScriptEngineFactory.
*/
public static final int GLOBAL_SCOPE = 200;
/**
* Associates a <code>Bindings</code> instance with a particular scope in this
* <code>ScriptContext</code>. Calls to the <code>getAttribute</code> and
* <code>setAttribute</code> methods must map to the <code>get</code> and
* <code>put</code> methods of the <code>Bindings</code> for the specified scope.
*
* @param bindings The <code>Bindings</code> to associate with the given scope
* @param scope The scope
*
* @throws IllegalArgumentException If no <code>Bindings</code> is defined for the
* specified scope value in ScriptContexts of this type.
* @throws NullPointerException if value of scope is <code>ENGINE_SCOPE</code> and
* the specified <code>Bindings</code> is null.
*
*/
public void setBindings(Bindings bindings, int scope);
/**
* Gets the <code>Bindings</code> associated with the given scope in this
* <code>ScriptContext</code>.
*
* @return The associated <code>Bindings</code>. Returns <code>null</code> if it has not
* been set.
*
* @param scope The scope
* @throws IllegalArgumentException If no <code>Bindings</code> is defined for the
* specified scope value in <code>ScriptContext</code> of this type.
*/
public Bindings getBindings(int scope);
/**
* Sets the value of an attribute in a given scope. If the scope is <code>GLOBAL_SCOPE</code>
* and no Bindings is set for <code>GLOBAL_SCOPE</code>, then setAttribute call is a no-op.
*
* @param name The name of the attribute to set
* @param value The value of the attribute
* @param scope The scope in which to set the attribute
*
* @throws IllegalArgumentException
* if the name is empty or if the scope is invalid.
* @throws NullPointerException if the name is null.
*/
public void setAttribute(String name, Object value, int scope);
/**
* Gets the value of an attribute in a given scope.
*
* @param name The name of the attribute to retrieve.
* @param scope The scope in which to retrieve the attribute.
* @return The value of the attribute. Returns <code>null</code> is the name
* does not exist in the given scope.
*
* @throws IllegalArgumentException
* if the name is empty or if the value of scope is invalid.
* @throws NullPointerException if the name is null.
*/
public Object getAttribute(String name, int scope);
/**
* Remove an attribute in a given scope.
*
* @param name The name of the attribute to remove
* @param scope The scope in which to remove the attribute
*
* @return The removed value.
* @throws IllegalArgumentException
* if the name is empty or if the scope is invalid.
* @throws NullPointerException if the name is null.
*/
public Object removeAttribute(String name, int scope);
/**
* Retrieves the value of the attribute with the given name in
* the scope occurring earliest in the search order. The order
* is determined by the numeric value of the scope parameter (lowest
* scope values first.)
*
* @param name The name of the attribute to retrieve.
* @return The value of the attribute in the lowest scope for
* which an attribute with the given name is defined. Returns
* null if no attribute with the name exists in any scope.
* @throws NullPointerException if the name is null.
* @throws IllegalArgumentException if the name is empty.
*/
public Object getAttribute(String name);
/**
* Get the lowest scope in which an attribute is defined.
* @param name Name of the attribute
* .
* @return The lowest scope. Returns -1 if no attribute with the given
* name is defined in any scope.
* @throws NullPointerException if name is null.
* @throws IllegalArgumentException if name is empty.
*/
public int getAttributesScope(String name);
/**
* Returns the <code>Writer</code> for scripts to use when displaying output.
*
* @return The <code>Writer</code>.
*/
public Writer getWriter();
/**
* Returns the <code>Writer</code> used to display error output.
*
* @return The <code>Writer</code>
*/
public Writer getErrorWriter();
/**
* Sets the <code>Writer</code> for scripts to use when displaying output.
*
* @param writer The new <code>Writer</code>.
*/
public void setWriter(Writer writer);
/**
* Sets the <code>Writer</code> used to display error output.
*
* @param writer The <code>Writer</code>.
*/
public void setErrorWriter(Writer writer);
/**
* Returns a <code>Reader</code> to be used by the script to read
* input.
*
* @return The <code>Reader</code>.
*/
public Reader getReader();
/**
* Sets the <code>Reader</code> for scripts to read input
* .
* @param reader The new <code>Reader</code>.
*/
public void setReader(Reader reader);
/**
* Returns immutable <code>List</code> of all the valid values for
* scope in the ScriptContext.
*
* @return list of scope values
*/
public List<Integer> getScopes();
}

View file

@ -0,0 +1,333 @@
/*
* Copyright (c) 2005, 2013, 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 javax.script;
import java.io.Reader;
import java.util.Map;
import java.util.Set;
/**
* <code>ScriptEngine</code> is the fundamental interface whose methods must be
* fully functional in every implementation of this specification.
* <br><br>
* These methods provide basic scripting functionality. Applications written to this
* simple interface are expected to work with minimal modifications in every implementation.
* It includes methods that execute scripts, and ones that set and get values.
* <br><br>
* The values are key/value pairs of two types. The first type of pairs consists of
* those whose keys are reserved and defined in this specification or by individual
* implementations. The values in the pairs with reserved keys have specified meanings.
* <br><br>
* The other type of pairs consists of those that create Java language Bindings, the values are
* usually represented in scripts by the corresponding keys or by decorated forms of them.
*
* @author Mike Grogan
* @since 1.6
*/
public interface ScriptEngine {
/**
* Reserved key for a named value that passes
* an array of positional arguments to a script.
*/
public static final String ARGV="javax.script.argv";
/**
* Reserved key for a named value that is
* the name of the file being executed.
*/
public static final String FILENAME = "javax.script.filename";
/**
* Reserved key for a named value that is
* the name of the <code>ScriptEngine</code> implementation.
*/
public static final String ENGINE = "javax.script.engine";
/**
* Reserved key for a named value that identifies
* the version of the <code>ScriptEngine</code> implementation.
*/
public static final String ENGINE_VERSION = "javax.script.engine_version";
/**
* Reserved key for a named value that identifies
* the short name of the scripting language. The name is used by the
* <code>ScriptEngineManager</code> to locate a <code>ScriptEngine</code>
* with a given name in the <code>getEngineByName</code> method.
*/
public static final String NAME = "javax.script.name";
/**
* Reserved key for a named value that is
* the full name of Scripting Language supported by the implementation.
*/
public static final String LANGUAGE = "javax.script.language";
/**
* Reserved key for the named value that identifies
* the version of the scripting language supported by the implementation.
*/
public static final String LANGUAGE_VERSION ="javax.script.language_version";
/**
* Causes the immediate execution of the script whose source is the String
* passed as the first argument. The script may be reparsed or recompiled before
* execution. State left in the engine from previous executions, including
* variable values and compiled procedures may be visible during this execution.
*
* @param script The script to be executed by the script engine.
*
* @param context A <code>ScriptContext</code> exposing sets of attributes in
* different scopes. The meanings of the scopes <code>ScriptContext.GLOBAL_SCOPE</code>,
* and <code>ScriptContext.ENGINE_SCOPE</code> are defined in the specification.
* <br><br>
* The <code>ENGINE_SCOPE</code> <code>Bindings</code> of the <code>ScriptContext</code> contains the
* bindings of scripting variables to application objects to be used during this
* script execution.
*
*
* @return The value returned from the execution of the script.
*
* @throws ScriptException if an error occurs in script. ScriptEngines should create and throw
* <code>ScriptException</code> wrappers for checked Exceptions thrown by underlying scripting
* implementations.
* @throws NullPointerException if either argument is null.
*/
public Object eval(String script, ScriptContext context) throws ScriptException;
/**
* Same as <code>eval(String, ScriptContext)</code> where the source of the script
* is read from a <code>Reader</code>.
*
* @param reader The source of the script to be executed by the script engine.
*
* @param context The <code>ScriptContext</code> passed to the script engine.
*
* @return The value returned from the execution of the script.
*
* @throws ScriptException if an error occurs in script. ScriptEngines should create and throw
* <code>ScriptException</code> wrappers for checked Exceptions thrown by underlying scripting
* implementations.
* @throws NullPointerException if either argument is null.
*/
public Object eval(Reader reader , ScriptContext context) throws ScriptException;
/**
* Executes the specified script. The default <code>ScriptContext</code> for the <code>ScriptEngine</code>
* is used.
*
* @param script The script language source to be executed.
*
* @return The value returned from the execution of the script.
*
* @throws ScriptException if an error occurs in script. ScriptEngines should create and throw
* <code>ScriptException</code> wrappers for checked Exceptions thrown by underlying scripting
* implementations.
* @throws NullPointerException if the argument is null.
*/
public Object eval(String script) throws ScriptException;
/**
* Same as <code>eval(String)</code> except that the source of the script is
* provided as a <code>Reader</code>
*
* @param reader The source of the script.
*
* @return The value returned by the script.
*
* @throws ScriptException if an error occurs in script. ScriptEngines should create and throw
* <code>ScriptException</code> wrappers for checked Exceptions thrown by underlying scripting
* implementations.
* @throws NullPointerException if the argument is null.
*/
public Object eval(Reader reader) throws ScriptException;
/**
* Executes the script using the <code>Bindings</code> argument as the <code>ENGINE_SCOPE</code>
* <code>Bindings</code> of the <code>ScriptEngine</code> during the script execution. The
* <code>Reader</code>, <code>Writer</code> and non-<code>ENGINE_SCOPE</code> <code>Bindings</code> of the
* default <code>ScriptContext</code> are used. The <code>ENGINE_SCOPE</code>
* <code>Bindings</code> of the <code>ScriptEngine</code> is not changed, and its
* mappings are unaltered by the script execution.
*
* @param script The source for the script.
*
* @param n The <code>Bindings</code> of attributes to be used for script execution.
*
* @return The value returned by the script.
*
* @throws ScriptException if an error occurs in script. ScriptEngines should create and throw
* <code>ScriptException</code> wrappers for checked Exceptions thrown by underlying scripting
* implementations.
* @throws NullPointerException if either argument is null.
*/
public Object eval(String script, Bindings n) throws ScriptException;
/**
* Same as <code>eval(String, Bindings)</code> except that the source of the script
* is provided as a <code>Reader</code>.
*
* @param reader The source of the script.
* @param n The <code>Bindings</code> of attributes.
*
* @return The value returned by the script.
*
* @throws ScriptException if an error occurs in script. ScriptEngines should create and throw
* <code>ScriptException</code> wrappers for checked Exceptions thrown by underlying scripting
* implementations.
* @throws NullPointerException if either argument is null.
*/
public Object eval(Reader reader , Bindings n) throws ScriptException;
/**
* Sets a key/value pair in the state of the ScriptEngine that may either create
* a Java Language Binding to be used in the execution of scripts or be used in some
* other way, depending on whether the key is reserved. Must have the same effect as
* <code>getBindings(ScriptContext.ENGINE_SCOPE).put</code>.
*
* @param key The name of named value to add
* @param value The value of named value to add.
*
* @throws NullPointerException if key is null.
* @throws IllegalArgumentException if key is empty.
*/
public void put(String key, Object value);
/**
* Retrieves a value set in the state of this engine. The value might be one
* which was set using <code>setValue</code> or some other value in the state
* of the <code>ScriptEngine</code>, depending on the implementation. Must have the same effect
* as <code>getBindings(ScriptContext.ENGINE_SCOPE).get</code>
*
* @param key The key whose value is to be returned
* @return the value for the given key
*
* @throws NullPointerException if key is null.
* @throws IllegalArgumentException if key is empty.
*/
public Object get(String key);
/**
* Returns a scope of named values. The possible scopes are:
* <br><br>
* <ul>
* <li><code>ScriptContext.GLOBAL_SCOPE</code> - The set of named values representing global
* scope. If this <code>ScriptEngine</code> is created by a <code>ScriptEngineManager</code>,
* then the manager sets global scope bindings. This may be <code>null</code> if no global
* scope is associated with this <code>ScriptEngine</code></li>
* <li><code>ScriptContext.ENGINE_SCOPE</code> - The set of named values representing the state of
* this <code>ScriptEngine</code>. The values are generally visible in scripts using
* the associated keys as variable names.</li>
* <li>Any other value of scope defined in the default <code>ScriptContext</code> of the <code>ScriptEngine</code>.
* </li>
* </ul>
* <br><br>
* The <code>Bindings</code> instances that are returned must be identical to those returned by the
* <code>getBindings</code> method of <code>ScriptContext</code> called with corresponding arguments on
* the default <code>ScriptContext</code> of the <code>ScriptEngine</code>.
*
* @param scope Either <code>ScriptContext.ENGINE_SCOPE</code> or <code>ScriptContext.GLOBAL_SCOPE</code>
* which specifies the <code>Bindings</code> to return. Implementations of <code>ScriptContext</code>
* may define additional scopes. If the default <code>ScriptContext</code> of the <code>ScriptEngine</code>
* defines additional scopes, any of them can be passed to get the corresponding <code>Bindings</code>.
*
* @return The <code>Bindings</code> with the specified scope.
*
* @throws IllegalArgumentException if specified scope is invalid
*
*/
public Bindings getBindings(int scope);
/**
* Sets a scope of named values to be used by scripts. The possible scopes are:
*<br><br>
* <ul>
* <li><code>ScriptContext.ENGINE_SCOPE</code> - The specified <code>Bindings</code> replaces the
* engine scope of the <code>ScriptEngine</code>.
* </li>
* <li><code>ScriptContext.GLOBAL_SCOPE</code> - The specified <code>Bindings</code> must be visible
* as the <code>GLOBAL_SCOPE</code>.
* </li>
* <li>Any other value of scope defined in the default <code>ScriptContext</code> of the <code>ScriptEngine</code>.
*</li>
* </ul>
* <br><br>
* The method must have the same effect as calling the <code>setBindings</code> method of
* <code>ScriptContext</code> with the corresponding value of <code>scope</code> on the default
* <code>ScriptContext</code> of the <code>ScriptEngine</code>.
*
* @param bindings The <code>Bindings</code> for the specified scope.
* @param scope The specified scope. Either <code>ScriptContext.ENGINE_SCOPE</code>,
* <code>ScriptContext.GLOBAL_SCOPE</code>, or any other valid value of scope.
*
* @throws IllegalArgumentException if the scope is invalid
* @throws NullPointerException if the bindings is null and the scope is
* <code>ScriptContext.ENGINE_SCOPE</code>
*/
public void setBindings(Bindings bindings, int scope);
/**
* Returns an uninitialized <code>Bindings</code>.
*
* @return A <code>Bindings</code> that can be used to replace the state of this <code>ScriptEngine</code>.
**/
public Bindings createBindings();
/**
* Returns the default <code>ScriptContext</code> of the <code>ScriptEngine</code> whose Bindings, Reader
* and Writers are used for script executions when no <code>ScriptContext</code> is specified.
*
* @return The default <code>ScriptContext</code> of the <code>ScriptEngine</code>.
*/
public ScriptContext getContext();
/**
* Sets the default <code>ScriptContext</code> of the <code>ScriptEngine</code> whose Bindings, Reader
* and Writers are used for script executions when no <code>ScriptContext</code> is specified.
*
* @param context A <code>ScriptContext</code> that will replace the default <code>ScriptContext</code> in
* the <code>ScriptEngine</code>.
* @throws NullPointerException if context is null.
*/
public void setContext(ScriptContext context);
/**
* Returns a <code>ScriptEngineFactory</code> for the class to which this <code>ScriptEngine</code> belongs.
*
* @return The <code>ScriptEngineFactory</code>
*/
public ScriptEngineFactory getFactory();
}

View file

@ -0,0 +1,232 @@
/*
* Copyright (c) 2005, 2016, 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 javax.script;
import java.util.List;
/**
* <code>ScriptEngineFactory</code> is used to describe and instantiate
* <code>ScriptEngines</code>.
* <br><br>
* Each class implementing <code>ScriptEngine</code> has a corresponding
* factory that exposes metadata describing the engine class.
* <br><br>The <code>ScriptEngineManager</code>
* uses the service-provider loader mechanism described in the
* {@link java.util.ServiceLoader} class to obtain
* instances of {@code ScriptEngineFactory} instances.
* See {@link ScriptEngineManager#ScriptEngineManager()} and
* {@link ScriptEngineManager#ScriptEngineManager(java.lang.ClassLoader)}.
*
* @since 1.6
*/
public interface ScriptEngineFactory {
/**
* Returns the full name of the <code>ScriptEngine</code>. For
* instance an implementation based on the Mozilla Rhino Javascript engine
* might return <i>Rhino Mozilla Javascript Engine</i>.
* @return The name of the engine implementation.
*/
public String getEngineName();
/**
* Returns the version of the <code>ScriptEngine</code>.
* @return The <code>ScriptEngine</code> implementation version.
*/
public String getEngineVersion();
/**
* Returns an immutable list of filename extensions, which generally identify scripts
* written in the language supported by this <code>ScriptEngine</code>.
* The array is used by the <code>ScriptEngineManager</code> to implement its
* <code>getEngineByExtension</code> method.
* @return The list of extensions.
*/
public List<String> getExtensions();
/**
* Returns an immutable list of mimetypes, associated with scripts that
* can be executed by the engine. The list is used by the
* <code>ScriptEngineManager</code> class to implement its
* <code>getEngineByMimetype</code> method.
* @return The list of mime types.
*/
public List<String> getMimeTypes();
/**
* Returns an immutable list of short names for the <code>ScriptEngine</code>, which may be used to
* identify the <code>ScriptEngine</code> by the <code>ScriptEngineManager</code>.
* For instance, an implementation based on the Mozilla Rhino Javascript engine might
* return list containing {&quot;javascript&quot;, &quot;rhino&quot;}.
* @return an immutable list of short names
*/
public List<String> getNames();
/**
* Returns the name of the scripting language supported by this
* <code>ScriptEngine</code>.
* @return The name of the supported language.
*/
public String getLanguageName();
/**
* Returns the version of the scripting language supported by this
* <code>ScriptEngine</code>.
* @return The version of the supported language.
*/
public String getLanguageVersion();
/**
* Returns the value of an attribute whose meaning may be implementation-specific.
* Keys for which the value is defined in all implementations are:
* <ul>
* <li>ScriptEngine.ENGINE</li>
* <li>ScriptEngine.ENGINE_VERSION</li>
* <li>ScriptEngine.LANGUAGE</li>
* <li>ScriptEngine.LANGUAGE_VERSION</li>
* <li>ScriptEngine.NAME</li>
* </ul>
* <p>
* The values for these keys are the Strings returned by <code>getEngineName</code>,
* <code>getEngineVersion</code>, <code>getLanguageName</code>,
* <code>getLanguageVersion</code> for the first four keys respectively. For NAME, one of the Strings
* returned by <code>getNames</code> is returned.<br><br>
* A reserved key, <code><b>THREADING</b></code>, whose value describes the behavior of the engine
* with respect to concurrent execution of scripts and maintenance of state is also defined.
* These values for the <code><b>THREADING</b></code> key are:<br><br>
* <ul>
* <li><code>null</code> - The engine implementation is not thread safe, and cannot
* be used to execute scripts concurrently on multiple threads.
* <li><code>&quot;MULTITHREADED&quot;</code> - The engine implementation is internally
* thread-safe and scripts may execute concurrently although effects of script execution
* on one thread may be visible to scripts on other threads.
* <li><code>&quot;THREAD-ISOLATED&quot;</code> - The implementation satisfies the requirements
* of &quot;MULTITHREADED&quot;, and also, the engine maintains independent values
* for symbols in scripts executing on different threads.
* <li><code>&quot;STATELESS&quot;</code> - The implementation satisfies the requirements of
* <code>&quot;THREAD-ISOLATED&quot;</code>. In addition, script executions do not alter the
* mappings in the <code>Bindings</code> which is the engine scope of the
* <code>ScriptEngine</code>. In particular, the keys in the <code>Bindings</code>
* and their associated values are the same before and after the execution of the script.
* </ul>
* <br><br>
* Implementations may define implementation-specific keys.
*
* @param key The name of the parameter
* @return The value for the given parameter. Returns <code>null</code> if no
* value is assigned to the key.
*
* @throws NullPointerException if the key is null.
*/
public Object getParameter(String key);
/**
* Returns a String which can be used to invoke a method of a Java object using the syntax
* of the supported scripting language. For instance, an implementation for a Javascript
* engine might be;
*
* <pre>{@code
* public String getMethodCallSyntax(String obj,
* String m, String... args) {
* String ret = obj;
* ret += "." + m + "(";
* for (int i = 0; i < args.length; i++) {
* ret += args[i];
* if (i < args.length - 1) {
* ret += ",";
* }
* }
* ret += ")";
* return ret;
* }
* } </pre>
*
* @param obj The name representing the object whose method is to be invoked. The
* name is the one used to create bindings using the <code>put</code> method of
* <code>ScriptEngine</code>, the <code>put</code> method of an <code>ENGINE_SCOPE</code>
* <code>Bindings</code>,or the <code>setAttribute</code> method
* of <code>ScriptContext</code>. The identifier used in scripts may be a decorated form of the
* specified one.
*
* @param m The name of the method to invoke.
* @param args names of the arguments in the method call.
*
* @return The String used to invoke the method in the syntax of the scripting language.
*/
public String getMethodCallSyntax(String obj, String m, String... args);
/**
* Returns a String that can be used as a statement to display the specified String using
* the syntax of the supported scripting language. For instance, the implementation for a Perl
* engine might be;
*
* <pre><code>
* public String getOutputStatement(String toDisplay) {
* return "print(" + toDisplay + ")";
* }
* </code></pre>
*
* @param toDisplay The String to be displayed by the returned statement.
* @return The string used to display the String in the syntax of the scripting language.
*
*
*/
public String getOutputStatement(String toDisplay);
/**
* Returns a valid scripting language executable program with given statements.
* For instance an implementation for a PHP engine might be:
*
* <pre>{@code
* public String getProgram(String... statements) {
* String retval = "<?\n";
* int len = statements.length;
* for (int i = 0; i < len; i++) {
* retval += statements[i] + ";\n";
* }
* return retval += "?>";
* }
* }</pre>
*
* @param statements The statements to be executed. May be return values of
* calls to the <code>getMethodCallSyntax</code> and <code>getOutputStatement</code> methods.
* @return The Program
*
* @throws NullPointerException if the <code>statements</code> array or any of its elements is null
*/
public String getProgram(String... statements);
/**
* Returns an instance of the <code>ScriptEngine</code> associated with this
* <code>ScriptEngineFactory</code>. A new ScriptEngine is generally
* returned, but implementations may pool, share or reuse engines.
*
* @return A new <code>ScriptEngine</code> instance.
*/
public ScriptEngine getScriptEngine();
}

View file

@ -0,0 +1,416 @@
/*
* Copyright (c) 2005, 2013, 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 javax.script;
import java.util.*;
import java.security.*;
import java.util.ServiceLoader;
import java.util.ServiceConfigurationError;
/**
* The <code>ScriptEngineManager</code> implements a discovery and instantiation
* mechanism for <code>ScriptEngine</code> classes and also maintains a
* collection of key/value pairs storing state shared by all engines created
* by the Manager. This class uses the service provider mechanism described in the
* {@link java.util.ServiceLoader} class to enumerate all the
* implementations of <code>ScriptEngineFactory</code>. <br><br>
* The <code>ScriptEngineManager</code> provides a method to return a list of all these factories
* as well as utility methods which look up factories on the basis of language name, file extension
* and mime type.
* <p>
* The <code>Bindings</code> of key/value pairs, referred to as the "Global Scope" maintained
* by the manager is available to all instances of <code>ScriptEngine</code> created
* by the <code>ScriptEngineManager</code>. The values in the <code>Bindings</code> are
* generally exposed in all scripts.
*
* @author Mike Grogan
* @author A. Sundararajan
* @since 1.6
*/
public class ScriptEngineManager {
private static final boolean DEBUG = false;
/**
* The effect of calling this constructor is the same as calling
* <code>ScriptEngineManager(Thread.currentThread().getContextClassLoader())</code>.
*
* @see java.lang.Thread#getContextClassLoader
*/
public ScriptEngineManager() {
ClassLoader ctxtLoader = Thread.currentThread().getContextClassLoader();
init(ctxtLoader);
}
/**
* This constructor loads the implementations of
* <code>ScriptEngineFactory</code> visible to the given
* <code>ClassLoader</code> using the service provider mechanism.<br><br>
* If loader is <code>null</code>, the script engine factories that are
* bundled with the platform are loaded. <br>
*
* @param loader ClassLoader used to discover script engine factories.
*/
public ScriptEngineManager(ClassLoader loader) {
init(loader);
}
private void init(final ClassLoader loader) {
globalScope = new SimpleBindings();
engineSpis = new HashSet<ScriptEngineFactory>();
nameAssociations = new HashMap<String, ScriptEngineFactory>();
extensionAssociations = new HashMap<String, ScriptEngineFactory>();
mimeTypeAssociations = new HashMap<String, ScriptEngineFactory>();
initEngines(loader);
}
private ServiceLoader<ScriptEngineFactory> getServiceLoader(final ClassLoader loader) {
if (loader != null) {
return ServiceLoader.load(ScriptEngineFactory.class, loader);
} else {
return ServiceLoader.loadInstalled(ScriptEngineFactory.class);
}
}
private void initEngines(final ClassLoader loader) {
Iterator<ScriptEngineFactory> itr = null;
try {
ServiceLoader<ScriptEngineFactory> sl = AccessController.doPrivileged(
new PrivilegedAction<ServiceLoader<ScriptEngineFactory>>() {
@Override
public ServiceLoader<ScriptEngineFactory> run() {
return getServiceLoader(loader);
}
});
itr = sl.iterator();
} catch (ServiceConfigurationError err) {
System.err.println("Can't find ScriptEngineFactory providers: " +
err.getMessage());
if (DEBUG) {
err.printStackTrace();
}
// do not throw any exception here. user may want to
// manage his/her own factories using this manager
// by explicit registratation (by registerXXX) methods.
return;
}
try {
while (itr.hasNext()) {
try {
ScriptEngineFactory fact = itr.next();
engineSpis.add(fact);
} catch (ServiceConfigurationError err) {
System.err.println("ScriptEngineManager providers.next(): "
+ err.getMessage());
if (DEBUG) {
err.printStackTrace();
}
// one factory failed, but check other factories...
continue;
}
}
} catch (ServiceConfigurationError err) {
System.err.println("ScriptEngineManager providers.hasNext(): "
+ err.getMessage());
if (DEBUG) {
err.printStackTrace();
}
// do not throw any exception here. user may want to
// manage his/her own factories using this manager
// by explicit registratation (by registerXXX) methods.
return;
}
}
/**
* <code>setBindings</code> stores the specified <code>Bindings</code>
* in the <code>globalScope</code> field. ScriptEngineManager sets this
* <code>Bindings</code> as global bindings for <code>ScriptEngine</code>
* objects created by it.
*
* @param bindings The specified <code>Bindings</code>
* @throws IllegalArgumentException if bindings is null.
*/
public void setBindings(Bindings bindings) {
if (bindings == null) {
throw new IllegalArgumentException("Global scope cannot be null.");
}
globalScope = bindings;
}
/**
* <code>getBindings</code> returns the value of the <code>globalScope</code> field.
* ScriptEngineManager sets this <code>Bindings</code> as global bindings for
* <code>ScriptEngine</code> objects created by it.
*
* @return The globalScope field.
*/
public Bindings getBindings() {
return globalScope;
}
/**
* Sets the specified key/value pair in the Global Scope.
* @param key Key to set
* @param value Value to set.
* @throws NullPointerException if key is null.
* @throws IllegalArgumentException if key is empty string.
*/
public void put(String key, Object value) {
globalScope.put(key, value);
}
/**
* Gets the value for the specified key in the Global Scope
* @param key The key whose value is to be returned.
* @return The value for the specified key.
*/
public Object get(String key) {
return globalScope.get(key);
}
/**
* Looks up and creates a <code>ScriptEngine</code> for a given name.
* The algorithm first searches for a <code>ScriptEngineFactory</code> that has been
* registered as a handler for the specified name using the <code>registerEngineName</code>
* method.
* <br><br> If one is not found, it searches the set of <code>ScriptEngineFactory</code> instances
* stored by the constructor for one with the specified name. If a <code>ScriptEngineFactory</code>
* is found by either method, it is used to create instance of <code>ScriptEngine</code>.
* @param shortName The short name of the <code>ScriptEngine</code> implementation.
* returned by the <code>getNames</code> method of its <code>ScriptEngineFactory</code>.
* @return A <code>ScriptEngine</code> created by the factory located in the search. Returns null
* if no such factory was found. The <code>ScriptEngineManager</code> sets its own <code>globalScope</code>
* <code>Bindings</code> as the <code>GLOBAL_SCOPE</code> <code>Bindings</code> of the newly
* created <code>ScriptEngine</code>.
* @throws NullPointerException if shortName is null.
*/
public ScriptEngine getEngineByName(String shortName) {
if (shortName == null) throw new NullPointerException();
//look for registered name first
Object obj;
if (null != (obj = nameAssociations.get(shortName))) {
ScriptEngineFactory spi = (ScriptEngineFactory)obj;
try {
ScriptEngine engine = spi.getScriptEngine();
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
return engine;
} catch (Exception exp) {
if (DEBUG) exp.printStackTrace();
}
}
for (ScriptEngineFactory spi : engineSpis) {
List<String> names = null;
try {
names = spi.getNames();
} catch (Exception exp) {
if (DEBUG) exp.printStackTrace();
}
if (names != null) {
for (String name : names) {
if (shortName.equals(name)) {
try {
ScriptEngine engine = spi.getScriptEngine();
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
return engine;
} catch (Exception exp) {
if (DEBUG) exp.printStackTrace();
}
}
}
}
}
return null;
}
/**
* Look up and create a <code>ScriptEngine</code> for a given extension. The algorithm
* used by <code>getEngineByName</code> is used except that the search starts
* by looking for a <code>ScriptEngineFactory</code> registered to handle the
* given extension using <code>registerEngineExtension</code>.
* @param extension The given extension
* @return The engine to handle scripts with this extension. Returns <code>null</code>
* if not found.
* @throws NullPointerException if extension is null.
*/
public ScriptEngine getEngineByExtension(String extension) {
if (extension == null) throw new NullPointerException();
//look for registered extension first
Object obj;
if (null != (obj = extensionAssociations.get(extension))) {
ScriptEngineFactory spi = (ScriptEngineFactory)obj;
try {
ScriptEngine engine = spi.getScriptEngine();
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
return engine;
} catch (Exception exp) {
if (DEBUG) exp.printStackTrace();
}
}
for (ScriptEngineFactory spi : engineSpis) {
List<String> exts = null;
try {
exts = spi.getExtensions();
} catch (Exception exp) {
if (DEBUG) exp.printStackTrace();
}
if (exts == null) continue;
for (String ext : exts) {
if (extension.equals(ext)) {
try {
ScriptEngine engine = spi.getScriptEngine();
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
return engine;
} catch (Exception exp) {
if (DEBUG) exp.printStackTrace();
}
}
}
}
return null;
}
/**
* Look up and create a <code>ScriptEngine</code> for a given mime type. The algorithm
* used by <code>getEngineByName</code> is used except that the search starts
* by looking for a <code>ScriptEngineFactory</code> registered to handle the
* given mime type using <code>registerEngineMimeType</code>.
* @param mimeType The given mime type
* @return The engine to handle scripts with this mime type. Returns <code>null</code>
* if not found.
* @throws NullPointerException if mimeType is null.
*/
public ScriptEngine getEngineByMimeType(String mimeType) {
if (mimeType == null) throw new NullPointerException();
//look for registered types first
Object obj;
if (null != (obj = mimeTypeAssociations.get(mimeType))) {
ScriptEngineFactory spi = (ScriptEngineFactory)obj;
try {
ScriptEngine engine = spi.getScriptEngine();
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
return engine;
} catch (Exception exp) {
if (DEBUG) exp.printStackTrace();
}
}
for (ScriptEngineFactory spi : engineSpis) {
List<String> types = null;
try {
types = spi.getMimeTypes();
} catch (Exception exp) {
if (DEBUG) exp.printStackTrace();
}
if (types == null) continue;
for (String type : types) {
if (mimeType.equals(type)) {
try {
ScriptEngine engine = spi.getScriptEngine();
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
return engine;
} catch (Exception exp) {
if (DEBUG) exp.printStackTrace();
}
}
}
}
return null;
}
/**
* Returns a list whose elements are instances of all the <code>ScriptEngineFactory</code> classes
* found by the discovery mechanism.
* @return List of all discovered <code>ScriptEngineFactory</code>s.
*/
public List<ScriptEngineFactory> getEngineFactories() {
List<ScriptEngineFactory> res = new ArrayList<ScriptEngineFactory>(engineSpis.size());
for (ScriptEngineFactory spi : engineSpis) {
res.add(spi);
}
return Collections.unmodifiableList(res);
}
/**
* Registers a <code>ScriptEngineFactory</code> to handle a language
* name. Overrides any such association found using the Discovery mechanism.
* @param name The name to be associated with the <code>ScriptEngineFactory</code>.
* @param factory The class to associate with the given name.
* @throws NullPointerException if any of the parameters is null.
*/
public void registerEngineName(String name, ScriptEngineFactory factory) {
if (name == null || factory == null) throw new NullPointerException();
nameAssociations.put(name, factory);
}
/**
* Registers a <code>ScriptEngineFactory</code> to handle a mime type.
* Overrides any such association found using the Discovery mechanism.
*
* @param type The mime type to be associated with the
* <code>ScriptEngineFactory</code>.
*
* @param factory The class to associate with the given mime type.
* @throws NullPointerException if any of the parameters is null.
*/
public void registerEngineMimeType(String type, ScriptEngineFactory factory) {
if (type == null || factory == null) throw new NullPointerException();
mimeTypeAssociations.put(type, factory);
}
/**
* Registers a <code>ScriptEngineFactory</code> to handle an extension.
* Overrides any such association found using the Discovery mechanism.
*
* @param extension The extension type to be associated with the
* <code>ScriptEngineFactory</code>.
* @param factory The class to associate with the given extension.
* @throws NullPointerException if any of the parameters is null.
*/
public void registerEngineExtension(String extension, ScriptEngineFactory factory) {
if (extension == null || factory == null) throw new NullPointerException();
extensionAssociations.put(extension, factory);
}
/** Set of script engine factories discovered. */
private HashSet<ScriptEngineFactory> engineSpis;
/** Map of engine name to script engine factory. */
private HashMap<String, ScriptEngineFactory> nameAssociations;
/** Map of script file extension to script engine factory. */
private HashMap<String, ScriptEngineFactory> extensionAssociations;
/** Map of script MIME type to script engine factory. */
private HashMap<String, ScriptEngineFactory> mimeTypeAssociations;
/** Global bindings associated with script engines created by this manager. */
private Bindings globalScope;
}

View file

@ -0,0 +1,154 @@
/*
* Copyright (c) 2005, 2011, 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 javax.script;
/**
* The generic <code>Exception</code> class for the Scripting APIs. Checked
* exception types thrown by underlying scripting implementations must be wrapped in instances of
* <code>ScriptException</code>. The class has members to store line and column numbers and
* filenames if this information is available.
*
* @author Mike Grogan
* @since 1.6
*/
public class ScriptException extends Exception {
private static final long serialVersionUID = 8265071037049225001L;
private String fileName;
private int lineNumber;
private int columnNumber;
/**
* Creates a <code>ScriptException</code> with a String to be used in its message.
* Filename, and line and column numbers are unspecified.
*
* @param s The String to use in the message.
*/
public ScriptException(String s) {
super(s);
fileName = null;
lineNumber = -1;
columnNumber = -1;
}
/**
* Creates a <code>ScriptException</code> wrapping an <code>Exception</code> thrown by an underlying
* interpreter. Line and column numbers and filename are unspecified.
*
* @param e The wrapped <code>Exception</code>.
*/
public ScriptException(Exception e) {
super(e);
fileName = null;
lineNumber = -1;
columnNumber = -1;
}
/**
* Creates a <code>ScriptException</code> with message, filename and linenumber to
* be used in error messages.
*
* @param message The string to use in the message
*
* @param fileName The file or resource name describing the location of a script error
* causing the <code>ScriptException</code> to be thrown.
*
* @param lineNumber A line number describing the location of a script error causing
* the <code>ScriptException</code> to be thrown.
*/
public ScriptException(String message, String fileName, int lineNumber) {
super(message);
this.fileName = fileName;
this.lineNumber = lineNumber;
this.columnNumber = -1;
}
/**
* <code>ScriptException</code> constructor specifying message, filename, line number
* and column number.
* @param message The message.
* @param fileName The filename
* @param lineNumber the line number.
* @param columnNumber the column number.
*/
public ScriptException(String message,
String fileName,
int lineNumber,
int columnNumber) {
super(message);
this.fileName = fileName;
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
}
/**
* Returns a message containing the String passed to a constructor as well as
* line and column numbers and filename if any of these are known.
* @return The error message.
*/
public String getMessage() {
String ret = super.getMessage();
if (fileName != null) {
ret += (" in " + fileName);
if (lineNumber != -1) {
ret += " at line number " + lineNumber;
}
if (columnNumber != -1) {
ret += " at column number " + columnNumber;
}
}
return ret;
}
/**
* Get the line number on which an error occurred.
* @return The line number. Returns -1 if a line number is unavailable.
*/
public int getLineNumber() {
return lineNumber;
}
/**
* Get the column number on which an error occurred.
* @return The column number. Returns -1 if a column number is unavailable.
*/
public int getColumnNumber() {
return columnNumber;
}
/**
* Get the source of the script causing the error.
* @return The file name of the script or some other string describing the script
* source. May return some implementation-defined string such as <i>&lt;unknown&gt;</i>
* if a description of the source is unavailable.
*/
public String getFileName() {
return fileName;
}
}

View file

@ -0,0 +1,224 @@
/*
* 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 javax.script;
import java.util.Map;
import java.util.HashMap;
import java.util.Collection;
import java.util.Set;
/**
* A simple implementation of Bindings backed by
* a {@code HashMap} or some other specified {@code Map}.
*
* @author Mike Grogan
* @since 1.6
*/
public class SimpleBindings implements Bindings {
/**
* The {@code Map} field stores the attributes.
*/
private Map<String,Object> map;
/**
* Constructor uses an existing {@code Map} to store the values.
* @param m The {@code Map} backing this {@code SimpleBindings}.
* @throws NullPointerException if m is null
*/
public SimpleBindings(Map<String,Object> m) {
if (m == null) {
throw new NullPointerException();
}
this.map = m;
}
/**
* Default constructor uses a {@code HashMap}.
*/
public SimpleBindings() {
this(new HashMap<String,Object>());
}
/**
* Sets the specified key/value in the underlying {@code map} field.
*
* @param name Name of value
* @param value Value to set.
*
* @return Previous value for the specified key. Returns null if key was previously
* unset.
*
* @throws NullPointerException if the name is null.
* @throws IllegalArgumentException if the name is empty.
*/
public Object put(String name, Object value) {
checkKey(name);
return map.put(name,value);
}
/**
* {@code putAll} is implemented using {@code Map.putAll}.
*
* @param toMerge The {@code Map} of values to add.
*
* @throws NullPointerException
* if toMerge map is null or if some key in the map is null.
* @throws IllegalArgumentException
* if some key in the map is an empty String.
*/
public void putAll(Map<? extends String, ? extends Object> toMerge) {
if (toMerge == null) {
throw new NullPointerException("toMerge map is null");
}
for (Map.Entry<? extends String, ? extends Object> entry : toMerge.entrySet()) {
String key = entry.getKey();
checkKey(key);
put(key, entry.getValue());
}
}
/** {@inheritDoc} */
public void clear() {
map.clear();
}
/**
* Returns {@code true} if this map contains a mapping for the specified
* key. More formally, returns {@code true} if and only if
* this map contains a mapping for a key {@code k} such that
* {@code (key==null ? k==null : key.equals(k))}. (There can be
* at most one such mapping.)
*
* @param key key whose presence in this map is to be tested.
* @return {@code true} if this map contains a mapping for the specified
* key.
*
* @throws NullPointerException if key is null
* @throws ClassCastException if key is not String
* @throws IllegalArgumentException if key is empty String
*/
public boolean containsKey(Object key) {
checkKey(key);
return map.containsKey(key);
}
/** {@inheritDoc} */
public boolean containsValue(Object value) {
return map.containsValue(value);
}
/** {@inheritDoc} */
public Set<Map.Entry<String, Object>> entrySet() {
return map.entrySet();
}
/**
* Returns the value to which this map maps the specified key. Returns
* {@code null} if the map contains no mapping for this key. A return
* value of {@code null} does not <i>necessarily</i> indicate that the
* map contains no mapping for the key; it's also possible that the map
* explicitly maps the key to {@code null}. The {@code containsKey}
* operation may be used to distinguish these two cases.
*
* <p>More formally, if this map contains a mapping from a key
* {@code k} to a value {@code v} such that
* {@code (key==null ? k==null : key.equals(k))},
* then this method returns {@code v}; otherwise
* it returns {@code null}. (There can be at most one such mapping.)
*
* @param key key whose associated value is to be returned.
* @return the value to which this map maps the specified key, or
* {@code null} if the map contains no mapping for this key.
*
* @throws NullPointerException if key is null
* @throws ClassCastException if key is not String
* @throws IllegalArgumentException if key is empty String
*/
public Object get(Object key) {
checkKey(key);
return map.get(key);
}
/** {@inheritDoc} */
public boolean isEmpty() {
return map.isEmpty();
}
/** {@inheritDoc} */
public Set<String> keySet() {
return map.keySet();
}
/**
* Removes the mapping for this key from this map if it is present
* (optional operation). More formally, if this map contains a mapping
* from key {@code k} to value {@code v} such that
* {@code (key==null ? k==null : key.equals(k))}, that mapping
* is removed. (The map can contain at most one such mapping.)
*
* <p>Returns the value to which the map previously associated the key, or
* {@code null} if the map contained no mapping for this key. (A
* {@code null} return can also indicate that the map previously
* associated {@code null} with the specified key if the implementation
* supports {@code null} values.) The map will not contain a mapping for
* the specified key once the call returns.
*
* @param key key whose mapping is to be removed from the map.
* @return previous value associated with specified key, or {@code null}
* if there was no mapping for key.
*
* @throws NullPointerException if key is null
* @throws ClassCastException if key is not String
* @throws IllegalArgumentException if key is empty String
*/
public Object remove(Object key) {
checkKey(key);
return map.remove(key);
}
/** {@inheritDoc} */
public int size() {
return map.size();
}
/** {@inheritDoc} */
public Collection<Object> values() {
return map.values();
}
private void checkKey(Object key) {
if (key == null) {
throw new NullPointerException("key can not be null");
}
if (!(key instanceof String)) {
throw new ClassCastException("key should be a String");
}
if (key.equals("")) {
throw new IllegalArgumentException("key can not be empty");
}
}
}

View file

@ -0,0 +1,334 @@
/*
* Copyright (c) 2005, 2013, 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 javax.script;
import java.util.*;
import java.io.*;
/**
* Simple implementation of ScriptContext.
*
* @author Mike Grogan
* @since 1.6
*/
public class SimpleScriptContext implements ScriptContext {
/**
* This is the writer to be used to output from scripts.
* By default, a <code>PrintWriter</code> based on <code>System.out</code>
* is used. Accessor methods getWriter, setWriter are used to manage
* this field.
* @see java.lang.System#out
* @see java.io.PrintWriter
*/
protected Writer writer;
/**
* This is the writer to be used to output errors from scripts.
* By default, a <code>PrintWriter</code> based on <code>System.err</code> is
* used. Accessor methods getErrorWriter, setErrorWriter are used to manage
* this field.
* @see java.lang.System#err
* @see java.io.PrintWriter
*/
protected Writer errorWriter;
/**
* This is the reader to be used for input from scripts.
* By default, a <code>InputStreamReader</code> based on <code>System.in</code>
* is used and default charset is used by this reader. Accessor methods
* getReader, setReader are used to manage this field.
* @see java.lang.System#in
* @see java.io.InputStreamReader
*/
protected Reader reader;
/**
* This is the engine scope bindings.
* By default, a <code>SimpleBindings</code> is used. Accessor
* methods setBindings, getBindings are used to manage this field.
* @see SimpleBindings
*/
protected Bindings engineScope;
/**
* This is the global scope bindings.
* By default, a null value (which means no global scope) is used. Accessor
* methods setBindings, getBindings are used to manage this field.
*/
protected Bindings globalScope;
/**
* Create a {@code SimpleScriptContext}.
*/
public SimpleScriptContext() {
engineScope = new SimpleBindings();
globalScope = null;
reader = new InputStreamReader(System.in);
writer = new PrintWriter(System.out , true);
errorWriter = new PrintWriter(System.err, true);
}
/**
* Sets a <code>Bindings</code> of attributes for the given scope. If the value
* of scope is <code>ENGINE_SCOPE</code> the given <code>Bindings</code> replaces the
* <code>engineScope</code> field. If the value
* of scope is <code>GLOBAL_SCOPE</code> the given <code>Bindings</code> replaces the
* <code>globalScope</code> field.
*
* @param bindings The <code>Bindings</code> of attributes to set.
* @param scope The value of the scope in which the attributes are set.
*
* @throws IllegalArgumentException if scope is invalid.
* @throws NullPointerException if the value of scope is <code>ENGINE_SCOPE</code> and
* the specified <code>Bindings</code> is null.
*/
public void setBindings(Bindings bindings, int scope) {
switch (scope) {
case ENGINE_SCOPE:
if (bindings == null) {
throw new NullPointerException("Engine scope cannot be null.");
}
engineScope = bindings;
break;
case GLOBAL_SCOPE:
globalScope = bindings;
break;
default:
throw new IllegalArgumentException("Invalid scope value.");
}
}
/**
* Retrieves the value of the attribute with the given name in
* the scope occurring earliest in the search order. The order
* is determined by the numeric value of the scope parameter (lowest
* scope values first.)
*
* @param name The name of the attribute to retrieve.
* @return The value of the attribute in the lowest scope for
* which an attribute with the given name is defined. Returns
* null if no attribute with the name exists in any scope.
* @throws NullPointerException if the name is null.
* @throws IllegalArgumentException if the name is empty.
*/
public Object getAttribute(String name) {
checkName(name);
if (engineScope.containsKey(name)) {
return getAttribute(name, ENGINE_SCOPE);
} else if (globalScope != null && globalScope.containsKey(name)) {
return getAttribute(name, GLOBAL_SCOPE);
}
return null;
}
/**
* Gets the value of an attribute in a given scope.
*
* @param name The name of the attribute to retrieve.
* @param scope The scope in which to retrieve the attribute.
* @return The value of the attribute. Returns <code>null</code> is the name
* does not exist in the given scope.
*
* @throws IllegalArgumentException
* if the name is empty or if the value of scope is invalid.
* @throws NullPointerException if the name is null.
*/
public Object getAttribute(String name, int scope) {
checkName(name);
switch (scope) {
case ENGINE_SCOPE:
return engineScope.get(name);
case GLOBAL_SCOPE:
if (globalScope != null) {
return globalScope.get(name);
}
return null;
default:
throw new IllegalArgumentException("Illegal scope value.");
}
}
/**
* Remove an attribute in a given scope.
*
* @param name The name of the attribute to remove
* @param scope The scope in which to remove the attribute
*
* @return The removed value.
* @throws IllegalArgumentException
* if the name is empty or if the scope is invalid.
* @throws NullPointerException if the name is null.
*/
public Object removeAttribute(String name, int scope) {
checkName(name);
switch (scope) {
case ENGINE_SCOPE:
if (getBindings(ENGINE_SCOPE) != null) {
return getBindings(ENGINE_SCOPE).remove(name);
}
return null;
case GLOBAL_SCOPE:
if (getBindings(GLOBAL_SCOPE) != null) {
return getBindings(GLOBAL_SCOPE).remove(name);
}
return null;
default:
throw new IllegalArgumentException("Illegal scope value.");
}
}
/**
* Sets the value of an attribute in a given scope. If the scope is <code>GLOBAL_SCOPE</code>
* and no Bindings is set for <code>GLOBAL_SCOPE</code>, then setAttribute call is a no-op.
*
* @param name The name of the attribute to set
* @param value The value of the attribute
* @param scope The scope in which to set the attribute
*
* @throws IllegalArgumentException
* if the name is empty or if the scope is invalid.
* @throws NullPointerException if the name is null.
*/
public void setAttribute(String name, Object value, int scope) {
checkName(name);
switch (scope) {
case ENGINE_SCOPE:
engineScope.put(name, value);
return;
case GLOBAL_SCOPE:
if (globalScope != null) {
globalScope.put(name, value);
}
return;
default:
throw new IllegalArgumentException("Illegal scope value.");
}
}
/** {@inheritDoc} */
public Writer getWriter() {
return writer;
}
/** {@inheritDoc} */
public Reader getReader() {
return reader;
}
/** {@inheritDoc} */
public void setReader(Reader reader) {
this.reader = reader;
}
/** {@inheritDoc} */
public void setWriter(Writer writer) {
this.writer = writer;
}
/** {@inheritDoc} */
public Writer getErrorWriter() {
return errorWriter;
}
/** {@inheritDoc} */
public void setErrorWriter(Writer writer) {
this.errorWriter = writer;
}
/**
* Get the lowest scope in which an attribute is defined.
* @param name Name of the attribute
* .
* @return The lowest scope. Returns -1 if no attribute with the given
* name is defined in any scope.
* @throws NullPointerException if name is null.
* @throws IllegalArgumentException if name is empty.
*/
public int getAttributesScope(String name) {
checkName(name);
if (engineScope.containsKey(name)) {
return ENGINE_SCOPE;
} else if (globalScope != null && globalScope.containsKey(name)) {
return GLOBAL_SCOPE;
} else {
return -1;
}
}
/**
* Returns the value of the <code>engineScope</code> field if specified scope is
* <code>ENGINE_SCOPE</code>. Returns the value of the <code>globalScope</code> field if the specified scope is
* <code>GLOBAL_SCOPE</code>.
*
* @param scope The specified scope
* @return The value of either the <code>engineScope</code> or <code>globalScope</code> field.
* @throws IllegalArgumentException if the value of scope is invalid.
*/
public Bindings getBindings(int scope) {
if (scope == ENGINE_SCOPE) {
return engineScope;
} else if (scope == GLOBAL_SCOPE) {
return globalScope;
} else {
throw new IllegalArgumentException("Illegal scope value.");
}
}
/** {@inheritDoc} */
public List<Integer> getScopes() {
return scopes;
}
private void checkName(String name) {
Objects.requireNonNull(name);
if (name.isEmpty()) {
throw new IllegalArgumentException("name cannot be empty");
}
}
private static List<Integer> scopes;
static {
scopes = new ArrayList<Integer>(2);
scopes.add(ENGINE_SCOPE);
scopes.add(GLOBAL_SCOPE);
scopes = Collections.unmodifiableList(scopes);
}
}

View file

@ -0,0 +1,94 @@
/*
* 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.
*/
/**
<p>The scripting API consists of interfaces and classes that define
Java&trade; Scripting Engines and provides
a framework for their use in Java applications. This API is intended
for use by application programmers who wish to execute programs
written in scripting languages in their Java applications. The
scripting language programs are usually provided by the end-users of
the applications.
</p>
<p>The main areas of functionality of <code>javax.script</code>
package include
</p>
<ol>
<li><p><b>Script execution</b>: Scripts
are streams of characters used as sources for programs executed by
script engines. Script execution uses
{@link javax.script.ScriptEngine#eval eval} methods of
{@link javax.script.ScriptEngine ScriptEngine} and methods of the
{@link javax.script.Invocable Invocable} interface.
</p>
<li><p><b>Binding</b>: This facility
allows Java objects to be exposed to script programs as named
variables. {@link javax.script.Bindings Bindings} and
{@link javax.script.ScriptContext ScriptContext}
classes are used for this purpose.
</p>
<li><p><b>Compilation</b>: This
functionality allows the intermediate code generated by the
front-end of a script engine to be stored and executed repeatedly.
This benefits applications that execute the same script multiple
times. These applications can gain efficiency since the engines'
front-ends only need to execute once per script rather than once per
script execution. Note that this functionality is optional and
script engines may choose not to implement it. Callers need to check
for availability of the {@link javax.script.Compilable Compilable}
interface using an <I>instanceof</I> check.
</p>
<li><p><b>Invocation</b>: This
functionality allows the reuse of intermediate code generated by a
script engine's front-end. Whereas Compilation allows entire scripts
represented by intermediate code to be re-executed, Invocation
functionality allows individual procedures/methods in the scripts to
be re-executed. As in the case with compilation, not all script
engines are required to provide this facility. Caller has to check
for {@link javax.script.Invocable Invocable} availability.
</p>
<li><p><b>Script engine discovery</b>: Applications
written to the Scripting API might have specific requirements on
script engines. Some may require a specific scripting language
and/or version while others may require a specific implementation
engine and/or version. Script engines are packaged in a specified
way so that engines can be discovered at runtime and queried for
attributes. The Engine discovery mechanism is based on the service-provider
loading facility described in the {@link java.util.ServiceLoader} class.
{@link javax.script.ScriptEngineManager ScriptEngineManager}
includes
{@link javax.script.ScriptEngineManager#getEngineFactories getEngineFactories} method to get all
{@link javax.script.ScriptEngineFactory ScriptEngineFactory} instances
discovered using this mechanism. <code>ScriptEngineFactory</code> has
methods to query attributes about script engine.
</p>
</ol>
@since 1.6
*/
package javax.script;

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2014, 2017, 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.
*/
/**
* Defines the Scripting API.
*
* <p> The JDK implementation of this module includes a language-independent
* command-line script shell, <em>{@index jrunscript jrunscript tool}</em>,
* that supports executing JavaScript and other languages if its corresponding
* script engine is installed.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd> {@extLink jrunscript_tool_reference jrunscript}</dd>
* </dl>
*
* @uses javax.script.ScriptEngineFactory
*
* @moduleGraph
* @since 9
*/
module java.scripting {
exports javax.script;
uses javax.script.ScriptEngineFactory;
}