001package co.codewizards.cloudstore.client; 002 003import java.io.BufferedReader; 004import java.io.IOException; 005import java.io.InputStreamReader; 006import java.util.concurrent.Callable; 007import java.util.concurrent.ExecutionException; 008import java.util.concurrent.ExecutorService; 009import java.util.concurrent.Executors; 010import java.util.concurrent.Future; 011import java.util.concurrent.TimeUnit; 012import java.util.concurrent.TimeoutException; 013 014public class TimeoutConsoleReader { 015 016 private final String question; 017 private final long timeoutMsec; 018 private final String timeoutAnswer; 019 020 public TimeoutConsoleReader(final String question, final long timeoutMsec, final String timeoutAnswer) { 021 this.question = question; 022 this.timeoutMsec = timeoutMsec; 023 this.timeoutAnswer = timeoutAnswer; 024 } 025 026 public String readLine() throws InterruptedException { 027 final ExecutorService ex = Executors.newSingleThreadExecutor(); 028 String answer = null; 029 try { 030 final Future<String> future = ex.submit(new CallableReader()); 031 try { 032 System.out.println(question); 033 answer = future.get(timeoutMsec, TimeUnit.MILLISECONDS); 034 } catch (final ExecutionException e) { 035 //unexpected, print to System.err 036 e.getCause().printStackTrace(); 037 } catch (final TimeoutException e) { 038 System.err.println(">>> The question was without reply, will cancel."); 039 future.cancel(true); 040 System.err.println(">>> Giving no answer will be interpreted as: " + timeoutAnswer); 041 answer = timeoutAnswer; 042 } 043 } finally { 044 ex.shutdownNow(); 045 } 046 return answer; 047 } 048 049 private class CallableReader implements Callable<String> { 050 @Override 051 public String call() throws IOException { 052 final BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 053 String line = ""; 054 while ("".equals(line)) { 055 try { 056 while (!br.ready()) { 057 Thread.sleep(200); 058 } 059 line = br.readLine(); 060 } catch (final InterruptedException e) { 061 System.err.println("CallableReader() interrupted!"); 062 return timeoutAnswer; 063 } 064 } 065 System.out.println("Your answer was: '" + line + "'"); 066 return line; 067 } 068 } 069}