8085937: add autoimports sample script to easily explore Java classes in interactive mode
authorsundar
Mon, 08 Jun 2015 14:10:39 +0530
changeset 31096 a3a697c1edd5
parent 31095 790fc3d576f9
child 31097 996397e0a35c
8085937: add autoimports sample script to easily explore Java classes in interactive mode Reviewed-by: lagergren, attila
nashorn/samples/autoimports.js
nashorn/samples/dateconversion.js
nashorn/samples/secondssince.js
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/autoimports.js	Mon Jun 08 14:10:39 2015 +0530
@@ -0,0 +1,151 @@
+# autoimports script requires -scripting mode
+
+/*
+ * 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.
+ */
+
+/*
+ * It is tedious to import Java classes used in a script. Sometimes it is easier
+ * use simple names of java classes and have a script auto import Java classes. 
+ * You can load this script at the start of an interactive jjs session or at the
+ * start of your script. This script defines a __noSuchProperty__ hook to auto 
+ * import Java classes as needed and when they are referred to for the first time
+ * in your script. You can also call the "autoimports" function to print script 
+ * statements that you need to use in your script, i.e., have the function generate
+ * a script to import Java classes used by your script so far. After running your
+ * script, you can call autoimports to get the exact Java imports you need and replace
+ * the autoimports load with the generated import statements (to avoid costly init of
+ * the autoimports script).
+ */
+
+(function() {
+    var ArrayList = Java.type("java.util.ArrayList");
+    var HashMap = Java.type("java.util.HashMap");
+    var Files = Java.type("java.nio.file.Files");
+    var FileSystems = Java.type("java.nio.file.FileSystems");
+    var URI = Java.type("java.net.URI");
+
+    // initialize a class to package map by iterating all
+    // classes available in the system by walking through "jrt fs"
+    var fs = FileSystems.getFileSystem(URI.create("jrt:/"));
+    var root = fs.getPath('/');
+
+    var clsToPkg = new HashMap();
+
+    function addToClsToPkg(c, p) {
+        if (clsToPkg.containsKey(c)) {
+            var val = clsToPkg.get(c);
+            if (val instanceof ArrayList) {
+                val.add(p);
+            } else {
+                var al = new ArrayList();
+                al.add(val);
+                al.add(p);
+                clsToPkg.put(c, al);
+            }
+        } else {
+            clsToPkg.put(c, p);
+        }
+    }
+
+    // handle collision and allow user to choose package
+    function getPkgOfCls(c) {
+        var val = clsToPkg.get(c);
+        if (val instanceof ArrayList) {
+            var count = 1;
+            print("Multiple matches for " + c + ", choose package:");
+            for each (var v in val) {
+                print(count + ". " + v);
+                count++;
+            }
+            var choice = parseInt(readLine());
+            if (isNaN(choice) || choice < 1 || choice > val.size()) {
+                print("invalid choice: " + choice);
+                return undefined;
+            }
+            return val.get(choice - 1);
+        } else {
+            return val;
+        }
+    }
+
+    Files.walk(root).forEach(function(p) {
+        if (Files.isRegularFile(p)) {
+            var str = p.toString();
+            if (str.endsWith(".class")) {
+                str = str.substring(1);
+                var idx = str.indexOf('/');
+                if (idx != -1) {
+                    str = str.substring(idx + 1);
+                    if (str.startsWith("java") ||
+                        str.startsWith("javax") ||
+                        str.startsWith("org")) {
+                        var lastIdx = str.lastIndexOf('/');
+                        if (lastIdx != -1) {
+                            var pkg = str.substring(0, lastIdx).replaceAll('/', '.');
+                            var cls = str.substring(lastIdx + 1, str.lastIndexOf(".class"));
+                            addToClsToPkg(cls, pkg);
+                        }
+                    }
+                }
+            }
+        } 
+    });
+
+    var imports = new ArrayList();
+    var global = this;
+    var oldNoSuchProp = global.__noSuchProperty__;
+    this.__noSuchProperty__ = function(name) {
+        'use strict';
+
+        if (clsToPkg.containsKey(name)) {
+            var pkg = getPkgOfCls(name);
+            if (pkg) {
+                var clsName = pkg + "." + name;
+                imports.add("var " + name + " = Java.type('" + clsName + "');");
+                return global[name] = Java.type(clsName);
+            }
+        } else if (typeof oldNoSuchProp == 'function') {
+            return oldNoSuchProp.call(this, name);
+        }
+
+        if (typeof this == 'undefined') {
+            throw new ReferenceError(name);
+        } else {
+            return undefined;
+        }
+    }
+
+    this.autoimports = function() {
+        for each (var im in imports) {
+            print(im);
+        }
+    }
+})();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/dateconversion.js	Mon Jun 08 14:10:39 2015 +0530
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+// Converting between #javascript Date and #java8 LocalDateTime with #nashorn
+
+// JavaScript Date with current time
+var d = new Date();
+print(d);
+ 
+// Java 8 java.time classes used
+var Instant = java.time.Instant;
+var LocalDateTime = java.time.LocalDateTime;
+var ZoneId = java.time.ZoneId;
+ 
+// Date.prototype.getTime
+
+// getTime() method returns the numeric value corresponding to the time
+// for the specified date according to universal time. The value returned
+// by the getTime() method is the number of milliseconds since 1 January 1970 00:00:00 UTC.
+// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime
+ 
+// Java Instant.ofEpochMilli to convert time in milliseconds to Instant object
+// https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#ofEpochMilli-long-
+ 
+var instant = Instant.ofEpochMilli(d.getTime());
+ 
+// Instant to LocalDateTime using LocalDateTime.ofInstant
+// https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#ofInstant-java.time.Instant-java.time.ZoneId-
+ 
+var ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+print(ldt);
+ 
+// converting a LocalDateTime to JavaScript Date
+// convert LocalDateTime to Instant first
+// https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#atZone-java.time.ZoneId-
+ 
+var instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
+ 
+// instant to to epoch milliseconds
+// https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#toEpochMilli--
+// and then to JavaScript Date from time in milliseconds
+// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date
+
+var d1 = new Date(instant.toEpochMilli());
+print(d1); 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/secondssince.js	Mon Jun 08 14:10:39 2015 +0530
@@ -0,0 +1,43 @@
+# usage: jjs secondssince.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.
+ */
+
+// Number of seconds elapsed since the specified Instance #nashorn #javascript #java
+// Input date and time in ISO 8601 format
+// Example: 2001-01-01T00:00:00Z for 1 Jan 2001, 0 GMT
+
+var Instant = java.time.Instant;
+var ChronoUnit = java.time.temporal.ChronoUnit;
+print("Enter date time:");
+var sec = Instant.parse(readLine()).
+      until(Instant.now(), ChronoUnit.SECONDS);
+print(sec);