javashell.js revision 970:f82b83cf73ae
1214501Srpaulo#// Usage: jjs -scripting javashell.js
2214501Srpaulo
3252726Srpaulo/*
4214501Srpaulo * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
5252726Srpaulo *
6252726Srpaulo * Redistribution and use in source and binary forms, with or without
7214501Srpaulo * modification, are permitted provided that the following conditions
8214501Srpaulo * are met:
9214501Srpaulo *
10214501Srpaulo *   - Redistributions of source code must retain the above copyright
11214501Srpaulo *     notice, this list of conditions and the following disclaimer.
12214501Srpaulo *
13214501Srpaulo *   - Redistributions in binary form must reproduce the above copyright
14214501Srpaulo *     notice, this list of conditions and the following disclaimer in the
15214501Srpaulo *     documentation and/or other materials provided with the distribution.
16214501Srpaulo *
17214501Srpaulo *   - Neither the name of Oracle nor the names of its
18214501Srpaulo *     contributors may be used to endorse or promote products derived
19214501Srpaulo *     from this software without specific prior written permission.
20214501Srpaulo *
21214501Srpaulo * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22214501Srpaulo * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23214501Srpaulo * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24214501Srpaulo * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25214501Srpaulo * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26214501Srpaulo * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27214501Srpaulo * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28214501Srpaulo * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29214501Srpaulo * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30214501Srpaulo * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31214501Srpaulo * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32214501Srpaulo */
33214501Srpaulo
34214501Srpaulo// Simple Java "shell" with which you can try out
35214501Srpaulo// your few liner Java code leaving imports, main etc.
36214501Srpaulo// And you can leave even compilation as this script
37214501Srpaulo// takes care boilerplate+compile step for you.
38252726Srpaulo
39214501Srpaulo// Java types used
40252726Srpaulovar Arrays = Java.type("java.util.Arrays");
41252726Srpaulovar BufferedReader = Java.type("java.io.BufferedReader");
42252726Srpaulovar FileWriter = Java.type("java.io.FileWriter");
43252726Srpaulovar LocalDateTime = Java.type("java.time.LocalDateTime");
44252726Srpaulovar InputStreamReader = Java.type("java.io.InputStreamReader");
45252726Srpaulovar PrintWriter = Java.type("java.io.PrintWriter");
46252726Srpaulovar ProcessBuilder = Java.type("java.lang.ProcessBuilder");
47252726Srpaulovar System = Java.type("java.lang.System");
48252726Srpaulo
49252726Srpaulo// read multiple lines of input from stdin till user
50252726Srpaulo// enters an empty line
51252726Srpaulofunction input(endMarker, prompt) {
52252726Srpaulo    if (!endMarker) {
53252726Srpaulo        endMarker = "";
54252726Srpaulo    }
55252726Srpaulo
56252726Srpaulo    if (!prompt) {
57252726Srpaulo        prompt = " >> ";
58252726Srpaulo    }
59252726Srpaulo
60252726Srpaulo    var str = "";
61252726Srpaulo    var reader = new BufferedReader(new InputStreamReader(System.in));
62252726Srpaulo    var line;
63252726Srpaulo    while (true) {
64252726Srpaulo        System.out.print(prompt);
65252726Srpaulo        line = reader.readLine();
66252726Srpaulo        if (line == null || line == endMarker) {
67252726Srpaulo            break;
68252726Srpaulo        }
69252726Srpaulo        str += line + "\n";
70252726Srpaulo    }
71252726Srpaulo    return str;
72252726Srpaulo}
73252726Srpaulo
74252726Srpaulo// write the string to the given file
75252726Srpaulofunction writeTo(file, str) {
76252726Srpaulo    var w = new PrintWriter(new FileWriter(file));
77252726Srpaulo    try {
78252726Srpaulo        w.print(str);
79252726Srpaulo    } finally {
80252726Srpaulo        w.close();
81252726Srpaulo    }
82252726Srpaulo}
83252726Srpaulo
84252726Srpaulo// generate Java code with user's input
85252726Srpaulo// put inside generated main method
86252726Srpaulofunction generate(className) {
87252726Srpaulo    var usercode = input();
88252726Srpaulo    if (usercode == "") {
89252726Srpaulo        return false;
90252726Srpaulo    }
91252726Srpaulo
92252726Srpaulo    var fullcode = <<EOF
93252726Srpaulo// userful imports, add more here if you want
94252726Srpaulo// more imports.
95252726Srpauloimport static java.lang.System.*;
96252726Srpauloimport java.io.*;
97252726Srpauloimport java.net.*;
98252726Srpauloimport java.math.*;
99252726Srpauloimport java.nio.file.*;
100252726Srpauloimport java.time.*;
101252726Srpauloimport java.time.chrono.*;
102252726Srpauloimport java.time.format.*;
103252726Srpauloimport java.time.temporal.*;
104252726Srpauloimport java.time.zone.*;
105252726Srpauloimport java.util.*;
106252726Srpauloimport java.util.concurrent.*;
107252726Srpauloimport java.util.function.*;
108252726Srpauloimport java.util.stream.*;
109252726Srpaulo
110252726Srpaulopublic class ${className} {
111252726Srpaulo   public static void main(String[] args) throws Exception {
112252726Srpaulo       ${usercode}
113252726Srpaulo   }
114252726Srpaulo}
115252726SrpauloEOF
116252726Srpaulo
117252726Srpaulo    writeTo("${className}.java", fullcode);
118252726Srpaulo    return true;
119252726Srpaulo}
120252726Srpaulo
121252726Srpaulo// execute code command
122252726Srpaulofunction exec(args) {
123252726Srpaulo    // build child process and start it!
124252726Srpaulo    new ProcessBuilder(Arrays.asList(args.split(' ')))
125252726Srpaulo         .inheritIO()
126252726Srpaulo         .start()
127252726Srpaulo         .waitFor();
128252726Srpaulo}
129252726Srpaulo
130252726Srpaulo// generate unique name
131252726Srpaulofunction uniqueName() {
132252726Srpaulo    var now = LocalDateTime.now().toString();
133252726Srpaulo    // replace unsafe chars with '_'
134252726Srpaulo    return "JavaShell" + now.replace(/-|:|\./g, '_');
135252726Srpaulo}
136252726Srpaulo
137252726Srpaulo// read-compile-run loop
138252726Srpaulowhile(true) {
139252726Srpaulo    var className = uniqueName();
140252726Srpaulo    if (generate(className)) {
141252726Srpaulo        exec("javac ${className}.java");
142252726Srpaulo        exec("java ${className}");
143252726Srpaulo    } else {
144252726Srpaulo        break;
145252726Srpaulo    }
146252726Srpaulo}
147252726Srpaulo