package co.codewizards.cloudstore.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class TimeoutConsoleReader {
private final String question;
private final long timeoutMsec;
private final String timeoutAnswer;
public TimeoutConsoleReader(final String question, final long timeoutMsec, final String timeoutAnswer) {
this.question = question;
this.timeoutMsec = timeoutMsec;
this.timeoutAnswer = timeoutAnswer;
}
public String readLine() throws InterruptedException {
final ExecutorService ex = Executors.newSingleThreadExecutor();
String answer = null;
try {
final Future<String> future = ex.submit(new CallableReader());
try {
System.out.println(question);
answer = future.get(timeoutMsec, TimeUnit.MILLISECONDS);
} catch (final ExecutionException e) {
//unexpected, print to System.err
e.getCause().printStackTrace();
} catch (final TimeoutException e) {
System.err.println(">>> The question was without reply, will cancel.");
future.cancel(true);
System.err.println(">>> Giving no answer will be interpreted as: " + timeoutAnswer);
answer = timeoutAnswer;
}
} finally {
ex.shutdownNow();
}
return answer;
}
private class CallableReader implements Callable<String> {
@Override
public String call() throws IOException {
final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = "";
while ("".equals(line)) {
try {
while (!br.ready()) {
Thread.sleep(200);
}
line = br.readLine();
} catch (final InterruptedException e) {
System.err.println("CallableReader() interrupted!");
return timeoutAnswer;
}
}
System.out.println("Your answer was: '" + line + "'");
return line;
}
}
}