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