Use interruptible readLine
This commit is contained in:
parent
52541b0ca8
commit
e4bda0a3c7
@ -26,7 +26,7 @@
|
||||
<dependency>
|
||||
<groupId>it.tdlight</groupId>
|
||||
<artifactId>tdlight-java</artifactId>
|
||||
<version>2.7.8.35</version>
|
||||
<version>2.7.8.36</version>
|
||||
</dependency>
|
||||
|
||||
<!-- TDLight natives -->
|
||||
|
@ -1,27 +1,59 @@
|
||||
package it.tdlight.common.utils;
|
||||
|
||||
import java.io.Console;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class ScannerUtils {
|
||||
|
||||
private static final Object lock = new Object();
|
||||
private static Scanner SCANNER = null;
|
||||
private static final Object LOCK = new Object();
|
||||
private static InputStreamReader scanner = null;
|
||||
|
||||
public static String askParameter(String displayName, String question) {
|
||||
Console console = System.console();
|
||||
if (console != null) {
|
||||
return console.readLine("[%s] %s", displayName, question);
|
||||
} else {
|
||||
synchronized (lock) {
|
||||
if (SCANNER == null) {
|
||||
SCANNER = new Scanner(System.in);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> SCANNER.close()));
|
||||
synchronized (LOCK) {
|
||||
Console console = System.console();
|
||||
if (console != null) {
|
||||
return console.readLine("[%s] %s", displayName, question);
|
||||
} else {
|
||||
if (scanner == null) {
|
||||
scanner = new InputStreamReader(System.in);
|
||||
}
|
||||
System.out.printf("[%s] %s: ", displayName, question);
|
||||
try {
|
||||
return interruptibleReadLine(scanner);
|
||||
} catch (InterruptedException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
System.out.printf("[%s] %s: ", displayName, question);
|
||||
return SCANNER.nextLine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* https://stackoverflow.com/questions/3595926/how-to-interrupt-bufferedreaders-readline
|
||||
*/
|
||||
private static String interruptibleReadLine(Reader reader) throws InterruptedException, IOException {
|
||||
Pattern line = Pattern.compile("^(.*)\\R");
|
||||
Matcher matcher;
|
||||
boolean interrupted;
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
int chr = -1;
|
||||
do {
|
||||
if (reader.ready()) {
|
||||
chr = reader.read();
|
||||
}
|
||||
if (chr > -1) {
|
||||
result.append((char) chr);
|
||||
}
|
||||
matcher = line.matcher(result.toString());
|
||||
interrupted = Thread.interrupted(); // resets flag, call only once
|
||||
} while (!interrupted && !matcher.matches());
|
||||
if (interrupted) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
return (matcher.matches() ? matcher.group(1) : "");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user