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 }