1 #// Usage: jjs -scripting javashell.js 2 3 /* 4 * Copyright (c) 2014, 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 */ 33 34 // Simple Java "shell" with which you can try out 35 // your few liner Java code leaving imports, main etc. 36 // And you can leave even compilation as this script 37 // takes care boilerplate+compile step for you. 38 39 // Java types used 40 var Arrays = Java.type("java.util.Arrays"); 41 var BufferedReader = Java.type("java.io.BufferedReader"); 42 var FileWriter = Java.type("java.io.FileWriter"); 43 var List = Java.type("java.util.List"); 44 var LocalDateTime = Java.type("java.time.LocalDateTime"); 45 var InputStreamReader = Java.type("java.io.InputStreamReader"); 46 var PrintWriter = Java.type("java.io.PrintWriter"); 47 var ProcessBuilder = Java.type("java.lang.ProcessBuilder"); 48 var System = Java.type("java.lang.System"); 49 50 // read multiple lines of input from stdin till user 51 // enters an empty line 52 function input(endMarker, prompt) { 53 if (!endMarker) { 54 endMarker = ""; 55 } 56 57 if (!prompt) { 58 prompt = " >> "; 59 } 60 61 var str = ""; 62 var reader = new BufferedReader(new InputStreamReader(System.in)); 63 var line; 64 while (true) { 65 System.out.print(prompt); 66 line = reader.readLine(); 67 if (line == null || line == endMarker) { 68 break; 69 } 70 str += line + "\n"; 71 } 72 return str; 73 } 74 75 // write the string to the given file 76 function writeTo(file, str) { 77 var w = new PrintWriter(new FileWriter(file)); 78 try { 79 w.print(str); 80 } finally { 81 w.close(); 82 } 83 } 84 85 // generate Java code with user's input 86 // put inside generated main method 87 function generate(className) { 88 var usercode = input(); 89 if (usercode == "") { 90 return false; 91 } 92 93 var fullcode = <<EOF 94 // userful imports, add more here if you want 95 // more imports. 96 import static java.lang.System.*; 97 import java.io.*; 98 import java.net.*; 99 import java.math.*; 100 import java.nio.file.*; 101 import java.time.*; 102 import java.time.chrono.*; 103 import java.time.format.*; 104 import java.time.temporal.*; 105 import java.time.zone.*; 106 import java.util.*; 107 import java.util.concurrent.*; 108 import java.util.function.*; 109 import java.util.stream.*; 110 111 public class ${className} { 112 public static void main(String[] args) throws Exception { 113 ${usercode} 114 } 115 } 116 EOF 117 118 writeTo("${className}.java", fullcode); 119 return true; 120 } 121 122 // execute code command 123 function exec(args) { 124 // build child process and start it! 125 new ProcessBuilder(Java.to(args.split(' '), List)) 126 .inheritIO() 127 .start() 128 .waitFor(); 129 } 130 131 // generate unique name 132 function uniqueName() { 133 var now = LocalDateTime.now().toString(); 134 // replace unsafe chars with '_' 135 return "JavaShell" + now.replace(/-|:|\./g, '_'); 136 } 137 138 // read-compile-run loop 139 while(true) { 140 var className = uniqueName(); 141 if (generate(className)) { 142 exec("javac ${className}.java"); 143 exec("java ${className}"); 144 } else { 145 break; 146 } 147 }