Created
August 11, 2019 15:37
-
-
Save gnodet/6863cda58b4e202c111553b359238a6c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.jline.example; | |
import java.io.File; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.SequenceInputStream; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Enumeration; | |
import java.util.List; | |
import java.util.StringTokenizer; | |
import org.jline.reader.Completer; | |
import org.jline.reader.EndOfFileException; | |
import org.jline.reader.LineReader; | |
import org.jline.reader.LineReaderBuilder; | |
import org.jline.reader.UserInterruptException; | |
import org.jline.reader.impl.completer.ArgumentCompleter; | |
public class ConsoleRunner { | |
private static LineReader reader; | |
private static InputStream systemIn = System.in; | |
public static LineReader getReader() { return reader; } | |
public static final String property = "jline.history"; | |
public static void main(final String[] args) throws Exception { | |
List<String> argList = new ArrayList<>(Arrays.asList(args)); | |
if (argList.size() == 0) { | |
usage(); | |
return; | |
} | |
String historyFileName = System.getProperty(ConsoleRunner.property, null); | |
// invoke the main() method | |
String mainClass = (String) argList.remove(0); | |
// setup the inpout stream | |
LineReaderBuilder builder = LineReaderBuilder.builder(); | |
if (historyFileName != null) { | |
builder.variable(LineReader.HISTORY_FILE, new File | |
(System.getProperty("user.home"), | |
".jline-" + mainClass | |
+ "." + historyFileName + ".history")); | |
} else { | |
builder.variable(LineReader.HISTORY_FILE, new File | |
(System.getProperty("user.home"), | |
".jline-" + mainClass + ".history")); | |
} | |
String completors = System.getProperty | |
(ConsoleRunner.class.getName() + ".completors", ""); | |
List<Completer> completorList = new ArrayList<>(); | |
for (StringTokenizer tok = new StringTokenizer(completors, ","); | |
tok.hasMoreTokens();) { | |
completorList.add((Completer) Class.forName(tok.nextToken()).newInstance()); | |
} | |
if (completorList.size() > 0) { | |
builder.completer(new ArgumentCompleter(completorList)); | |
} | |
reader = LineReaderBuilder.builder().build(); | |
System.setIn(new ConsoleReaderInputStream(reader)); | |
try { | |
Class.forName(mainClass). | |
getMethod("main", new Class[] { String[].class }). | |
invoke(null, new Object[] { argList.toArray(new String[0]) }); | |
} finally { | |
// just in case this main method is called from another program | |
System.setIn(systemIn); | |
} | |
} | |
private static void usage() { | |
System.out.println("Usage: \n java " + "[-Djline.history='name'] " | |
+ ConsoleRunner.class.getName() | |
+ " <target class name> [args]" | |
+ "\n\nThe -Djline.history option will avoid history" | |
+ "\nmangling when running ConsoleRunner on the same application." | |
+ "\n\nargs will be passed directly to the target class name."); | |
} | |
} | |
class ConsoleReaderInputStream extends SequenceInputStream { | |
public ConsoleReaderInputStream(final LineReader reader) { | |
super(new ConsoleEnumeration(reader)); | |
} | |
private static class ConsoleEnumeration implements Enumeration<ConsoleLineInputStream> { | |
private final LineReader reader; | |
private ConsoleLineInputStream next = null; | |
private ConsoleLineInputStream prev = null; | |
public ConsoleEnumeration(final LineReader reader) { | |
this.reader = reader; | |
} | |
public ConsoleLineInputStream nextElement() { | |
if (next != null) { | |
ConsoleLineInputStream n = next; | |
prev = next; | |
next = null; | |
return n; | |
} | |
return new ConsoleLineInputStream(reader); | |
} | |
public boolean hasMoreElements() { | |
// the last line was null | |
if ((prev != null) && prev.wasNull) { | |
return false; | |
} | |
if (next == null) { | |
next = nextElement(); | |
} | |
return next != null; | |
} | |
} | |
private static class ConsoleLineInputStream extends InputStream { | |
private final LineReader reader; | |
private String line = null; | |
private int index = 0; | |
private boolean eol = false; | |
protected boolean wasNull = false; | |
public ConsoleLineInputStream(final LineReader reader) { | |
this.reader = reader; | |
} | |
public int read() throws IOException { | |
if (eol) { | |
return -1; | |
} | |
if (line == null) { | |
try { | |
line = reader.readLine(); | |
} catch (UserInterruptException | EndOfFileException e) { | |
line = null; | |
} | |
} | |
if (line == null) { | |
wasNull = true; | |
return -1; | |
} | |
if (index >= line.length()) { | |
eol = true; | |
return '\n'; // lines are ended with a newline | |
} | |
return line.charAt(index++); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment