sundar@1401: # autoimports script requires -scripting mode sundar@1401: sundar@1401: /* sundar@1401: * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. sundar@1401: * sundar@1401: * Redistribution and use in source and binary forms, with or without sundar@1401: * modification, are permitted provided that the following conditions sundar@1401: * are met: sundar@1401: * sundar@1401: * - Redistributions of source code must retain the above copyright sundar@1401: * notice, this list of conditions and the following disclaimer. sundar@1401: * sundar@1401: * - Redistributions in binary form must reproduce the above copyright sundar@1401: * notice, this list of conditions and the following disclaimer in the sundar@1401: * documentation and/or other materials provided with the distribution. sundar@1401: * sundar@1401: * - Neither the name of Oracle nor the names of its sundar@1401: * contributors may be used to endorse or promote products derived sundar@1401: * from this software without specific prior written permission. sundar@1401: * sundar@1401: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS sundar@1401: * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, sundar@1401: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR sundar@1401: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR sundar@1401: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, sundar@1401: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, sundar@1401: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR sundar@1401: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF sundar@1401: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING sundar@1401: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS sundar@1401: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sundar@1401: */ sundar@1401: sundar@1401: /* sundar@1401: * It is tedious to import Java classes used in a script. Sometimes it is easier sundar@1401: * use simple names of java classes and have a script auto import Java classes. sundar@1401: * You can load this script at the start of an interactive jjs session or at the sundar@1401: * start of your script. This script defines a __noSuchProperty__ hook to auto sundar@1401: * import Java classes as needed and when they are referred to for the first time sundar@1401: * in your script. You can also call the "autoimports" function to print script sundar@1401: * statements that you need to use in your script, i.e., have the function generate sundar@1401: * a script to import Java classes used by your script so far. After running your sundar@1401: * script, you can call autoimports to get the exact Java imports you need and replace sundar@1401: * the autoimports load with the generated import statements (to avoid costly init of sundar@1401: * the autoimports script). sundar@1401: */ sundar@1401: sundar@1401: (function() { sundar@1401: var ArrayList = Java.type("java.util.ArrayList"); sundar@1401: var HashMap = Java.type("java.util.HashMap"); sundar@1401: var JarFile = Java.type("java.util.jar.JarFile"); sundar@1401: var File = Java.type("java.io.File"); sundar@1401: var Files = Java.type("java.nio.file.Files"); sundar@1401: var FileSystems = Java.type("java.nio.file.FileSystems"); sundar@1401: var System = Java.type("java.lang.System"); sundar@1401: var URI = Java.type("java.net.URI"); sundar@1401: sundar@1401: // initialize a class to package map by iterating all sundar@1401: // classes available in the system by walking through "jrt fs" sundar@1401: sundar@1401: var clsToPkg = new HashMap(); sundar@1401: sundar@1401: // locate rt.jar from sun.boot.class.path sundar@1401: function findRtJar() { sundar@1401: var paths = System.getProperty("sun.boot.class.path").split(File.pathSeparator); sundar@1401: for each (var p in paths) { sundar@1401: if (p.endsWith("rt.jar") && new File(p).exists()) { sundar@1401: return p; sundar@1401: } sundar@1401: } sundar@1401: } sundar@1401: sundar@1401: sundar@1401: function addToClsToPkg(c, p) { sundar@1401: if (clsToPkg.containsKey(c)) { sundar@1401: var val = clsToPkg.get(c); sundar@1401: if (val instanceof ArrayList) { sundar@1401: val.add(p); sundar@1401: } else { sundar@1401: var al = new ArrayList(); sundar@1401: al.add(val); sundar@1401: al.add(p); sundar@1401: clsToPkg.put(c, al); sundar@1401: } sundar@1401: } else { sundar@1401: clsToPkg.put(c, p); sundar@1401: } sundar@1401: } sundar@1401: sundar@1401: // handle collision and allow user to choose package sundar@1401: function getPkgOfCls(c) { sundar@1401: var val = clsToPkg.get(c); sundar@1401: if (val instanceof ArrayList) { sundar@1401: var count = 1; sundar@1401: print("Multiple matches for " + c + ", choose package:"); sundar@1401: for each (var v in val) { sundar@1401: print(count + ". " + v); sundar@1401: count++; sundar@1401: } sundar@1401: var choice = parseInt(readLine()); sundar@1401: if (isNaN(choice) || choice < 1 || choice > val.size()) { sundar@1401: print("invalid choice: " + choice); sundar@1401: return undefined; sundar@1401: } sundar@1401: return val.get(choice - 1); sundar@1401: } else { sundar@1401: return val; sundar@1401: } sundar@1401: } sundar@1401: sundar@1401: var rtJar = findRtJar(); sundar@1401: var stream = new JarFile(rtJar).stream(); sundar@1401: try { sundar@1401: stream.forEach( sundar@1401: function(entry) { sundar@1401: var str = entry.name; sundar@1401: if (str.endsWith(".class")) { sundar@1401: if (str.startsWith("java") || sundar@1401: str.startsWith("javax") || sundar@1401: str.startsWith("org")) { sundar@1401: var lastIdx = str.lastIndexOf('/'); sundar@1401: if (lastIdx != -1) { sundar@1401: var pkg = str.substring(0, lastIdx).replaceAll('/', '.'); sundar@1401: var cls = str.substring(lastIdx + 1, str.lastIndexOf(".class")); sundar@1401: addToClsToPkg(cls, pkg); sundar@1401: } sundar@1401: } sundar@1401: } sundar@1401: }); sundar@1401: } finally { sundar@1401: stream.close(); sundar@1401: } sundar@1401: sundar@1401: var imports = new ArrayList(); sundar@1401: var global = this; sundar@1401: var oldNoSuchProp = global.__noSuchProperty__; sundar@1401: this.__noSuchProperty__ = function(name) { sundar@1401: 'use strict'; sundar@1401: sundar@1401: if (clsToPkg.containsKey(name)) { sundar@1401: var pkg = getPkgOfCls(name); sundar@1401: if (pkg) { sundar@1401: var clsName = pkg + "." + name; sundar@1401: imports.add("var " + name + " = Java.type('" + clsName + "');"); sundar@1401: return global[name] = Java.type(clsName); sundar@1401: } sundar@1401: } else if (typeof oldNoSuchProp == 'function') { sundar@1401: return oldNoSuchProp.call(this, name); sundar@1401: } sundar@1401: sundar@1401: if (typeof this == 'undefined') { sundar@1401: throw new ReferenceError(name); sundar@1401: } else { sundar@1401: return undefined; sundar@1401: } sundar@1401: } sundar@1401: sundar@1401: this.autoimports = function() { sundar@1401: for each (var im in imports) { sundar@1401: print(im); sundar@1401: } sundar@1401: } sundar@1401: })();