8074939: Add few sample scripts to demo nashorn parser API
Reviewed-by: attila, hannesw
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/breakcontinue_in_tryfinally.js Wed Mar 11 14:30:40 2015 +0530
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Find break or continue inside try..finally in all scripts
+// in a given directory (recursively). If no directory is specified
+// the current working directory is scanned for scripts.
+
+if (arguments.length == 0) {
+ arguments[0] = ".";
+}
+
+var File = Java.type("java.io.File");
+var file = new File(arguments[0]);
+if (!file.exists()) {
+ print(arguments[0] + " is neither a directory nor a file");
+ exit(1);
+}
+
+var Files = Java.type("java.nio.file.Files");
+var Parser = Java.type("jdk.nashorn.api.tree.Parser");
+var SimpleTreeVisitor = Java.type("jdk.nashorn.api.tree.SimpleTreeVisitorES5_1");
+
+var parser = Parser.create("-scripting", "--const-as-var");
+
+function checkFile(file) {
+ // print("checking " + file);
+ var ast = parser.parse(file, print);
+ if (!ast) {
+ return;
+ }
+
+ // locate 'break/continue' inside try..finally
+ ast.accept(visitor = new (Java.extend(SimpleTreeVisitor)) {
+ lineMap: null,
+ inTryFinally: false,
+
+ printWarning: function(node, msg) {
+ var pos = node.startPosition;
+ var line = this.lineMap.getLineNumber(pos);
+ var column = this.lineMap.getColumnNumber(pos);
+ print(msg + " found in " + file + " @ " + line + ":" + column);
+ },
+
+ visitBreak: function(node, extra) {
+ if (this.inTryFinally) {
+ this.printWarning(node, "break");
+ }
+ },
+
+ visitContinue: function(node, extra) {
+ if (this.inTryFinally) {
+ this.printWarning(node, "continue");
+ }
+ },
+
+ visitCompilationUnit: function(node, extra) {
+ this.lineMap = node.lineMap;
+ Java.super(visitor).visitCompilationUnit(node, extra);
+ },
+
+ visitFunctionDeclaration: function(node, extra) {
+ var oldInTryFinally = this.inTryFinally;
+ this.inTryFinally = false;
+ try {
+ Java.super(visitor).visitFunctionDeclaration(node, extra);
+ } finally {
+ this.inTryFinally = oldInTryFinally;
+ }
+ },
+
+ visitFunctionExpression: function(node, extra) {
+ var oldInTryFinally = this.inTryFinally;
+ this.inTryFinally = false;
+ try {
+ Java.super(visitor).visitFunctionExpression(node, extra);
+ } finally {
+ this.inTryFinally = oldInTryFinally;
+ }
+ },
+
+ visitTry: function(node, extra) {
+ var oldInTryFinally = this.inTryFinally;
+ this.inTryFinally = (node.finallyBlock != null);
+ try {
+ Java.super(visitor).visitTry(node, extra);
+ } finally {
+ this.inTryFinally = oldInTryFinally;
+ }
+ }
+ }, null);
+}
+
+
+if (file.isDirectory()) {
+ Files.walk(file.toPath())
+ .filter(function(p) Files.isRegularFile(p))
+ .filter(function(p) p.toFile().name.endsWith('.js'))
+ .forEach(checkFile);
+} else {
+ checkFile(file);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/cricket.js Wed Mar 11 14:30:40 2015 +0530
@@ -0,0 +1,140 @@
+#// Usage: jjs -scripting cricket.js
+
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Example that demonstrates reading XML Rss feed.
+// XML DOM Document element is wrapped by script
+// "proxy" (JSAdapter constructor)
+
+// Java classes used
+var DocBuilderFac = Java.type("javax.xml.parsers.DocumentBuilderFactory");
+var Node = Java.type("org.w3c.dom.Node");
+
+// constants from Node class
+var ELEMENT_NODE = Node.ELEMENT_NODE;
+var TEXT_NODE = Node.TEXT_NODE;
+
+// parse XML from uri and return Document
+function parseXML(uri) {
+ var docBuilder = DocBuilderFac.newInstance().newDocumentBuilder();
+ return docBuilder["parse(java.lang.String)"](uri);
+}
+
+// get child Elements of given name of the parent element given
+function getChildElements(elem, name) {
+ var nodeList = elem.childNodes;
+ var childElems = [];
+ var len = nodeList.length;
+ for (var i = 0; i < len; i++) {
+ var node = nodeList.item(i);
+ if (node.nodeType == ELEMENT_NODE &&
+ node.tagName == name) {
+ childElems.push(wrapElement(node));
+ }
+ }
+
+ return childElems;
+}
+
+// get concatenated child text content of an Element
+function getElemText(elem) {
+ var nodeList = elem.childNodes;
+ var len = nodeList.length;
+ var text = '';
+ for (var i = 0; i < len; i++) {
+ var node = nodeList.item(i);
+ if (node.nodeType == TEXT_NODE) {
+ text += node.nodeValue;
+ }
+ }
+
+ return text;
+}
+
+// Wrap DOM Element object as a convenient script object
+// using JSAdapter. JSAdapter is like java.lang.reflect.Proxy
+// in that it allows property access, method calls be trapped
+// by 'magic' methods like __get__, __call__.
+function wrapElement(elem) {
+ if (! elem) {
+ return elem;
+ }
+ return new JSAdapter() {
+ // getter to expose child elements and attributes by name
+ __get__: function(name) {
+ if (typeof name == 'string') {
+ if (name.startsWith('@')) {
+ var attr = elem.getAttributeNode(name.substring(1));
+ return !attr? undefined : attr.value;
+ }
+
+ var arr = getChildElements(elem, name);
+ if (arr.length == 1) {
+ // single child element, expose as single element
+ return arr[0];
+ } else {
+ // multiple children of given name, expose as array
+ return arr;
+ }
+ }
+ return undefined;
+ },
+
+ __call__: function(name) {
+ // toString override to get text content of this Element
+ if (name == 'toString' || name == 'valueOf') {
+ return getElemText(elem);
+ }
+ return undefined;
+ }
+ }
+}
+
+function printCricketScore() {
+ var doc = parseXML("http://static.cricinfo.com/rss/livescores.xml");
+ // wrap document root Element as script convenient object
+ var rss = wrapElement(doc.documentElement);
+ print("rss file version " + rss['@version']);
+
+ print(rss.channel.title);
+ print(rss.channel.description);
+ print(rss.channel.pubDate);
+
+ print("=====================");
+
+ var items = rss.channel.item;
+ for each (var i in items) {
+ print(i.description);
+ }
+}
+
+printCricketScore();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/findproto.js Wed Mar 11 14:30:40 2015 +0530
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// __proto__ magic property is non-standard. Use Object.getPrototypeOf
+// and Object.setPrototypeOf instead. This script finds __proto__
+// usage in scripts a given directory (recursively). If no directory
+// is specified the current working directory is scanned for scripts.
+
+if (arguments.length == 0) {
+ arguments[0] = ".";
+}
+
+var File = Java.type("java.io.File");
+var file = new File(arguments[0]);
+if (!file.exists()) {
+ print(arguments[0] + " is neither a file nor a directory");
+ exit(1);
+}
+
+var Files = Java.type("java.nio.file.Files");
+var Parser = Java.type("jdk.nashorn.api.tree.Parser");
+var SimpleTreeVisitor = Java.type("jdk.nashorn.api.tree.SimpleTreeVisitorES5_1");
+
+var parser = Parser.create("-scripting", "--const-as-var");
+var protoFound = false;
+
+function checkFile(file) {
+ // print("checking " + file);
+ var ast = parser.parse(file, print);
+ if (!ast) {
+ return;
+ }
+
+ // locate __proto__ usage and warn
+ ast.accept(visitor = new (Java.extend(SimpleTreeVisitor)) {
+ lineMap: null,
+
+ printWarning: function(node) {
+ var pos = node.startPosition;
+ var line = this.lineMap.getLineNumber(pos);
+ var column = this.lineMap.getColumnNumber(pos);
+ print("WARNING: __proto__ usage in " + file + " @ " + line + ":" + column);
+ },
+
+ checkProto: function(node, name) {
+ if (name == "__proto__") {
+ protoFound = true;
+ this.printWarning(node);
+ }
+ },
+
+ visitCompilationUnit: function(node, extra) {
+ this.lineMap = node.lineMap;
+ Java.super(visitor).visitCompilationUnit(node, extra);
+ },
+
+ visitIdentifier: function(node, extra) {
+ this.checkProto(node, node.name);
+ Java.super(visitor).visitIdentifier(node, extra);
+ },
+
+ visitMemberSelect: function(node, extra) {
+ this.checkProto(node, node.identifier);
+ Java.super(visitor).visitMemberSelect(node, extra);
+ },
+
+ visitProperty: function(node, extra) {
+ this.checkProto(node, node.key);
+ Java.super(visitor).visitProperty(node, extra);
+ }
+ }, null);
+}
+
+if (file.isDirectory()) {
+ Files.walk(file.toPath())
+ .filter(function(p) Files.isRegularFile(p))
+ .filter(function(p) p.toFile().name.endsWith('.js'))
+ .forEach(checkFile);
+} else {
+ checkFile(file);
+}
+
+if (protoFound) {
+ print("__proto__ is non-standard. Use Object.get/setPrototypeOf instead");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/findvardelete.js Wed Mar 11 14:30:40 2015 +0530
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// delete of scope vars is reported as error in strict mode.
+// This script finds scripts that such deletes. Scripts in
+// the specified directory are scanned. If no directory is
+// specified, the current directory is scanned.
+
+if (arguments.length == 0) {
+ arguments[0] = ".";
+}
+
+var File = Java.type("java.io.File");
+var file = new File(arguments[0]);
+if (!file.exists()) {
+ print(arguments[0] + " is neither a directory nor a file");
+ exit(1);
+}
+
+var Files = Java.type("java.nio.file.Files");
+var IdentifierTree = Java.type("jdk.nashorn.api.tree.IdentifierTree");
+var Parser = Java.type("jdk.nashorn.api.tree.Parser");
+var SimpleTreeVisitor = Java.type("jdk.nashorn.api.tree.SimpleTreeVisitorES5_1");
+var Tree = Java.type("jdk.nashorn.api.tree.Tree");
+
+var parser = Parser.create("-scripting", "--const-as-var");
+
+function checkFile(file) {
+ // print("checking " + file);
+ var ast = parser.parse(file, print);
+ if (!ast) {
+ return;
+ }
+
+ // locate __proto__ usage and warn
+ ast.accept(visitor = new (Java.extend(SimpleTreeVisitor)) {
+ lineMap: null,
+
+ printWarning: function(node, varName) {
+ var pos = node.startPosition;
+ var line = this.lineMap.getLineNumber(pos);
+ var column = this.lineMap.getColumnNumber(pos);
+ print("WARNING: delete " + varName + " in " + file + " @ " + line + ":" + column);
+ },
+
+ visitCompilationUnit: function(node, extra) {
+ this.lineMap = node.lineMap;
+ Java.super(visitor).visitCompilationUnit(node, extra);
+ },
+
+ visitUnary: function(node, extra) {
+ if (node.kind == Tree.Kind.DELETE &&
+ node.expression instanceof IdentifierTree) {
+ this.printWarning(node, node.expression.name);
+ }
+ Java.super(visitor).visitUnary(node, extra);
+ },
+
+ }, null);
+}
+
+if (file.isDirectory()) {
+ Files.walk(file.toPath())
+ .filter(function(p) Files.isRegularFile(p))
+ .filter(function(p) p.toFile().name.endsWith('.js'))
+ .forEach(checkFile);
+} else {
+ checkFile(file);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/findwith.js Wed Mar 11 14:30:40 2015 +0530
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// 'with' statement is not considered a good practive. In strict mode,
+// with statements result in early error being thrown.
+
+// This script finds 'with' usage in scripts a given directory (recursively).
+// If no directory is specified the current working directory is scanned
+// for scripts.
+
+if (arguments.length == 0) {
+ arguments[0] = ".";
+}
+
+var File = Java.type("java.io.File");
+var file = new File(arguments[0]);
+if (!file.exists()) {
+ print(arguments[0] + " is neither a directory nor a file");
+ exit(1);
+}
+
+var Files = Java.type("java.nio.file.Files");
+var Parser = Java.type("jdk.nashorn.api.tree.Parser");
+var SimpleTreeVisitor = Java.type("jdk.nashorn.api.tree.SimpleTreeVisitorES5_1");
+
+var parser = Parser.create("-scripting", "--const-as-var");
+var protoFound = false;
+
+function checkFile(file) {
+ // print("checking " + file);
+ var ast = parser.parse(file, print);
+ if (!ast) {
+ return;
+ }
+
+ // locate __proto__ usage and warn
+ ast.accept(visitor = new (Java.extend(SimpleTreeVisitor)) {
+ lineMap: null,
+
+ printWarning: function(node) {
+ var pos = node.startPosition;
+ var line = this.lineMap.getLineNumber(pos);
+ var column = this.lineMap.getColumnNumber(pos);
+ print("WARNING: 'with' usage in " + file + " @ " + line + ":" + column);
+ },
+
+ visitCompilationUnit: function(node, extra) {
+ this.lineMap = node.lineMap;
+ Java.super(visitor).visitCompilationUnit(node, extra);
+ },
+
+ visitWith: function(node, extra) {
+ this.printWarning(node);
+ Java.super(visitor).visitWith(node, extra);
+ }
+ }, null);
+}
+
+if (file.isDirectory()) {
+ Files.walk(file.toPath())
+ .filter(function(p) Files.isRegularFile(p))
+ .filter(function(p) p.toFile().name.endsWith('.js'))
+ .forEach(checkFile);
+} else {
+ checkFile(file);
+}
+
+if (protoFound) {
+ print("__proto__ is non-standard. Use Object.get/setPrototypeOf instead");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/nashornastviewer.js Wed Mar 11 14:30:40 2015 +0530
@@ -0,0 +1,113 @@
+#// Usage: jjs -scripting -fx nashornastviewer.js -- <scriptfile>
+
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+# NOTE: This script requires JDK 9 build to run
+
+if (!$OPTIONS._fx) {
+ print("Usage: jjs -scripting -fx nashornastviewer.js -- <.js file>");
+ exit(1);
+}
+
+// Using JavaFX from Nashorn. See also:
+// http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/javafx.html
+
+// This example shows AST of a script file as a JavaFX
+// tree view in a window. If no file is specified, AST of
+// this script file is shown. This script demonstrates
+// Nashorn Parser API too - http://openjdk.java.net/jeps/236
+
+// JavaFX classes used
+var StackPane = Java.type("javafx.scene.layout.StackPane");
+var Scene = Java.type("javafx.scene.Scene");
+var TreeItem = Java.type("javafx.scene.control.TreeItem");
+var TreeView = Java.type("javafx.scene.control.TreeView");
+
+// Java classes used
+var Enum = Java.type("java.lang.Enum");
+var File = Java.type("java.io.File");
+var List = Java.type("java.util.List");
+var Parser = Java.type("jdk.nashorn.api.tree.Parser");
+var Tree = Java.type("jdk.nashorn.api.tree.Tree");
+
+// Create a javafx TreeItem to view a AST node
+function treeItemForASTNode(ast, name) {
+ var item = new TreeItem(name);
+ // make an iteratable script object from a Tree
+ ast = Object.bindProperties({}, ast);
+ for (var prop in ast) {
+ var node = ast[prop];
+ var type = typeof node;
+
+ if (node == null || type == "function") {
+ // skip nulls and Java methods
+ continue;
+ }
+
+ var subitem = null;
+ if (node instanceof Tree) {
+ subitem = treeItemForASTNode(node, prop);
+ } else if (node instanceof List) {
+ var len = node.size();
+ subitem = new TreeItem(prop);
+ for (var i = 0; i < len; i++) {
+ var li = treeItemForASTNode(node.get(i), String(i));
+ subitem.children.add(li);
+ }
+ } else if (node instanceof Enum || type != 'object') {
+ subitem = new TreeItem(prop + ": " + node);
+ }
+
+ if (subitem) {
+ item.children.add(subitem);
+ }
+ }
+ return item;
+}
+
+// do we have a script file passed? if not, use current script
+var sourceName = arguments.length == 0? __FILE__ : arguments[0];
+
+var parser = Parser.create("-scripting");
+// parse script to get CompilationUnitTree of it
+var ast = parser.parse(new File(sourceName), null);
+
+// JavaFX start method
+function start(stage) {
+ stage.title = "AST Viewer";
+ var rootItem = treeItemForASTNode(ast, sourceName);
+ var tree = new TreeView(rootItem);
+ var root = new StackPane();
+ root.children.add(tree);
+ stage.scene = new Scene(root, 300, 450);
+ stage.show();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/xmlviewer.js Wed Mar 11 14:30:40 2015 +0530
@@ -0,0 +1,103 @@
+#jjs -fx xmlviewer.js [-- <url-of-xml-doc>]
+
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+if (! $OPTIONS._fx) {
+ print("Usage: jjs -fx xmlviewer.js [-- <url-of-xml-doc>]");
+ exit(1);
+}
+
+// Using JavaFX from Nashorn. See also:
+// http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/javafx.html
+
+// Simple sample to view a XML document as a JavaFX tree.
+
+// JavaFX classes used
+var StackPane = Java.type("javafx.scene.layout.StackPane");
+var Scene = Java.type("javafx.scene.Scene");
+var TreeItem = Java.type("javafx.scene.control.TreeItem");
+var TreeView = Java.type("javafx.scene.control.TreeView");
+
+// XML DocumentBuilderFactory
+var DocBuilderFac = Java.type("javax.xml.parsers.DocumentBuilderFactory");
+var Attr = Java.type("org.w3c.dom.Attr");
+var Element = Java.type("org.w3c.dom.Element");
+var Text = Java.type("org.w3c.dom.Text");
+
+// parse XML from uri and return Document
+function parseXML(uri) {
+ var docBuilder = DocBuilderFac.newInstance().newDocumentBuilder();
+ docBuilder.validating = false;
+ return docBuilder["parse(java.lang.String)"](uri);
+}
+
+// Create a javafx TreeItem to view a XML element
+function treeItemForObject(element, name) {
+ var item = new TreeItem(name);
+ item.expanded = true;
+ var attrs = element.attributes;
+ var numAttrs = attrs.length;
+ for (var a = 0; a < numAttrs; a++) {
+ var attr = attrs.item(a);
+ var subitem = new TreeItem(attr.name + " = " + attr.value);
+ item.children.add(subitem);
+ }
+
+ var childNodes = element.childNodes;
+ var numNodes = childNodes.length;
+ for (var n = 0; n < numNodes; n++) {
+ var node = childNodes.item(n);
+ if (node instanceof Element) {
+ var subitem = treeItemForObject(node, node.tagName);
+ item.children.add(subitem);
+ }
+ }
+
+ return item;
+}
+
+// Ofcourse, the best default URL is cricket score :)
+var DEFAULT_URL = "http://synd.cricbuzz.com/j2me/1.0/livematches.xml";
+
+var url = arguments.length == 0? DEFAULT_URL : arguments[0];
+var element = parseXML(url).getDocumentElement();
+
+// JavaFX start method
+function start(stage) {
+ stage.title = "XML Viewer: " + url;
+ var rootItem = treeItemForObject(element, element.tagName);
+ var tree = new TreeView(rootItem);
+ var root = new StackPane();
+ root.children.add(tree);
+ stage.scene = new Scene(root, 300, 450);
+ stage.show();
+}