samples/autoimports.js

Tue, 22 Mar 2016 21:31:52 -0700

author
asaha
date
Tue, 22 Mar 2016 21:31:52 -0700
changeset 1810
d0fba38a0705
parent 1401
da52a33a5e93
permissions
-rw-r--r--

Added tag jdk8u92-b13 for changeset e2294411edbd

sundar@1401 1 # autoimports script requires -scripting mode
sundar@1401 2
sundar@1401 3 /*
sundar@1401 4 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
sundar@1401 5 *
sundar@1401 6 * Redistribution and use in source and binary forms, with or without
sundar@1401 7 * modification, are permitted provided that the following conditions
sundar@1401 8 * are met:
sundar@1401 9 *
sundar@1401 10 * - Redistributions of source code must retain the above copyright
sundar@1401 11 * notice, this list of conditions and the following disclaimer.
sundar@1401 12 *
sundar@1401 13 * - Redistributions in binary form must reproduce the above copyright
sundar@1401 14 * notice, this list of conditions and the following disclaimer in the
sundar@1401 15 * documentation and/or other materials provided with the distribution.
sundar@1401 16 *
sundar@1401 17 * - Neither the name of Oracle nor the names of its
sundar@1401 18 * contributors may be used to endorse or promote products derived
sundar@1401 19 * from this software without specific prior written permission.
sundar@1401 20 *
sundar@1401 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
sundar@1401 22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
sundar@1401 23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
sundar@1401 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
sundar@1401 25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
sundar@1401 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
sundar@1401 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
sundar@1401 28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
sundar@1401 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
sundar@1401 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
sundar@1401 31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
sundar@1401 32 */
sundar@1401 33
sundar@1401 34 /*
sundar@1401 35 * It is tedious to import Java classes used in a script. Sometimes it is easier
sundar@1401 36 * use simple names of java classes and have a script auto import Java classes.
sundar@1401 37 * You can load this script at the start of an interactive jjs session or at the
sundar@1401 38 * start of your script. This script defines a __noSuchProperty__ hook to auto
sundar@1401 39 * import Java classes as needed and when they are referred to for the first time
sundar@1401 40 * in your script. You can also call the "autoimports" function to print script
sundar@1401 41 * statements that you need to use in your script, i.e., have the function generate
sundar@1401 42 * a script to import Java classes used by your script so far. After running your
sundar@1401 43 * script, you can call autoimports to get the exact Java imports you need and replace
sundar@1401 44 * the autoimports load with the generated import statements (to avoid costly init of
sundar@1401 45 * the autoimports script).
sundar@1401 46 */
sundar@1401 47
sundar@1401 48 (function() {
sundar@1401 49 var ArrayList = Java.type("java.util.ArrayList");
sundar@1401 50 var HashMap = Java.type("java.util.HashMap");
sundar@1401 51 var JarFile = Java.type("java.util.jar.JarFile");
sundar@1401 52 var File = Java.type("java.io.File");
sundar@1401 53 var Files = Java.type("java.nio.file.Files");
sundar@1401 54 var FileSystems = Java.type("java.nio.file.FileSystems");
sundar@1401 55 var System = Java.type("java.lang.System");
sundar@1401 56 var URI = Java.type("java.net.URI");
sundar@1401 57
sundar@1401 58 // initialize a class to package map by iterating all
sundar@1401 59 // classes available in the system by walking through "jrt fs"
sundar@1401 60
sundar@1401 61 var clsToPkg = new HashMap();
sundar@1401 62
sundar@1401 63 // locate rt.jar from sun.boot.class.path
sundar@1401 64 function findRtJar() {
sundar@1401 65 var paths = System.getProperty("sun.boot.class.path").split(File.pathSeparator);
sundar@1401 66 for each (var p in paths) {
sundar@1401 67 if (p.endsWith("rt.jar") && new File(p).exists()) {
sundar@1401 68 return p;
sundar@1401 69 }
sundar@1401 70 }
sundar@1401 71 }
sundar@1401 72
sundar@1401 73
sundar@1401 74 function addToClsToPkg(c, p) {
sundar@1401 75 if (clsToPkg.containsKey(c)) {
sundar@1401 76 var val = clsToPkg.get(c);
sundar@1401 77 if (val instanceof ArrayList) {
sundar@1401 78 val.add(p);
sundar@1401 79 } else {
sundar@1401 80 var al = new ArrayList();
sundar@1401 81 al.add(val);
sundar@1401 82 al.add(p);
sundar@1401 83 clsToPkg.put(c, al);
sundar@1401 84 }
sundar@1401 85 } else {
sundar@1401 86 clsToPkg.put(c, p);
sundar@1401 87 }
sundar@1401 88 }
sundar@1401 89
sundar@1401 90 // handle collision and allow user to choose package
sundar@1401 91 function getPkgOfCls(c) {
sundar@1401 92 var val = clsToPkg.get(c);
sundar@1401 93 if (val instanceof ArrayList) {
sundar@1401 94 var count = 1;
sundar@1401 95 print("Multiple matches for " + c + ", choose package:");
sundar@1401 96 for each (var v in val) {
sundar@1401 97 print(count + ". " + v);
sundar@1401 98 count++;
sundar@1401 99 }
sundar@1401 100 var choice = parseInt(readLine());
sundar@1401 101 if (isNaN(choice) || choice < 1 || choice > val.size()) {
sundar@1401 102 print("invalid choice: " + choice);
sundar@1401 103 return undefined;
sundar@1401 104 }
sundar@1401 105 return val.get(choice - 1);
sundar@1401 106 } else {
sundar@1401 107 return val;
sundar@1401 108 }
sundar@1401 109 }
sundar@1401 110
sundar@1401 111 var rtJar = findRtJar();
sundar@1401 112 var stream = new JarFile(rtJar).stream();
sundar@1401 113 try {
sundar@1401 114 stream.forEach(
sundar@1401 115 function(entry) {
sundar@1401 116 var str = entry.name;
sundar@1401 117 if (str.endsWith(".class")) {
sundar@1401 118 if (str.startsWith("java") ||
sundar@1401 119 str.startsWith("javax") ||
sundar@1401 120 str.startsWith("org")) {
sundar@1401 121 var lastIdx = str.lastIndexOf('/');
sundar@1401 122 if (lastIdx != -1) {
sundar@1401 123 var pkg = str.substring(0, lastIdx).replaceAll('/', '.');
sundar@1401 124 var cls = str.substring(lastIdx + 1, str.lastIndexOf(".class"));
sundar@1401 125 addToClsToPkg(cls, pkg);
sundar@1401 126 }
sundar@1401 127 }
sundar@1401 128 }
sundar@1401 129 });
sundar@1401 130 } finally {
sundar@1401 131 stream.close();
sundar@1401 132 }
sundar@1401 133
sundar@1401 134 var imports = new ArrayList();
sundar@1401 135 var global = this;
sundar@1401 136 var oldNoSuchProp = global.__noSuchProperty__;
sundar@1401 137 this.__noSuchProperty__ = function(name) {
sundar@1401 138 'use strict';
sundar@1401 139
sundar@1401 140 if (clsToPkg.containsKey(name)) {
sundar@1401 141 var pkg = getPkgOfCls(name);
sundar@1401 142 if (pkg) {
sundar@1401 143 var clsName = pkg + "." + name;
sundar@1401 144 imports.add("var " + name + " = Java.type('" + clsName + "');");
sundar@1401 145 return global[name] = Java.type(clsName);
sundar@1401 146 }
sundar@1401 147 } else if (typeof oldNoSuchProp == 'function') {
sundar@1401 148 return oldNoSuchProp.call(this, name);
sundar@1401 149 }
sundar@1401 150
sundar@1401 151 if (typeof this == 'undefined') {
sundar@1401 152 throw new ReferenceError(name);
sundar@1401 153 } else {
sundar@1401 154 return undefined;
sundar@1401 155 }
sundar@1401 156 }
sundar@1401 157
sundar@1401 158 this.autoimports = function() {
sundar@1401 159 for each (var im in imports) {
sundar@1401 160 print(im);
sundar@1401 161 }
sundar@1401 162 }
sundar@1401 163 })();

mercurial