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

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

mercurial