Add prompt with timeout

Signed-off-by: Emmanuel Bigeon <emmanuel@bigeon.fr>
This commit is contained in:
Emmanuel Bigeon 2017-04-20 13:23:28 -04:00
parent 8322454f72
commit b93c2b5220
4 changed files with 73 additions and 16 deletions

View File

@ -74,12 +74,25 @@ public interface ConsoleManager extends AutoCloseable {
* @throws InterruptedIOException if the prompt was interrupted */
String prompt() throws IOException;
/** @param timeout the time to wait in milliseconds
* @return the user inputed string, null if the timeout was reached
* @throws IOException if the manager is closed or could not read the prompt
* @throws InterruptedIOException if the prompt was interrupted */
String prompt(long timeout) throws IOException;
/** @param message the message to prompt the user
* @return the user inputed string
* @throws IOException if the manager is closed or could not read the prompt
* @throws InterruptedIOException if the prompt was interrupted */
String prompt(String message) throws IOException;
/** @param timeout the time to wait in milliseconds
* @param message the message to prompt the user
* @return the user inputed string, null if the timeout was reached
* @throws IOException if the manager is closed or could not read the prompt
* @throws InterruptedIOException if the prompt was interrupted */
String prompt(String message, long timeout) throws IOException;
/** <p>
* Set a prompting prefix.
*

View File

@ -121,11 +121,23 @@ public final class PipedConsoleManager
.prompt(innerManager.getPrompt() + System.lineSeparator());
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.manager.ConsoleManager#prompt(long) */
@Override
public String prompt(long timeout) throws IOException {
return innerManager.prompt(timeout);
}
@Override
public String prompt(String message) throws IOException {
return innerManager.prompt(message + System.lineSeparator());
}
@Override
public String prompt(String message, long timeout) throws IOException {
return innerManager.prompt(message + System.lineSeparator(), timeout);
}
@Override
public void setPrompt(String prompt) {
innerManager.setPrompt(prompt);

View File

@ -69,8 +69,7 @@ public class ReadingRunnable implements Runnable {
/** @param obj the object to lock on
* @param start the object to notify when ready to wait
* @param message the message to wait for */
public ToWaitRunnable(Object obj, Object start,
String message) {
public ToWaitRunnable(Object obj, Object start, String message) {
this.obj = obj;
this.start = start;
this.message = message;
@ -91,8 +90,8 @@ public class ReadingRunnable implements Runnable {
return;
}
} catch (InterruptedException e) {
LOGGER.log(Level.SEVERE,
THREAD_INTERRUPTION_EXCEPTION, e);
LOGGER.log(Level.SEVERE, THREAD_INTERRUPTION_EXCEPTION,
e);
}
}
}
@ -126,13 +125,9 @@ public class ReadingRunnable implements Runnable {
private final Object lock = new Object();
/** The waiting status for a message */
private boolean waiting;
/**
* The blocker for a given message
*/
/** The blocker for a given message */
private final Map<String, Object> messageBlocker = new HashMap<>();
/**
* The lock
*/
/** The lock */
private final Object messageBlockerLock = new Object();
/** The message being delivered */
private String delivering;
@ -195,18 +190,17 @@ public class ReadingRunnable implements Runnable {
public String getMessage() throws IOException {
synchronized (lock) {
if (!running) {
throw new IOException(CLOSED_PIPE);
throw new IOException(CLOSED_PIPE);
}
waiting = true;
while (messages.isEmpty()) {
try {
lock.wait(TIMEOUT);
} catch (InterruptedException e) {
LOGGER.log(Level.SEVERE, THREAD_INTERRUPTION_EXCEPTION,
e);
LOGGER.log(Level.SEVERE, THREAD_INTERRUPTION_EXCEPTION, e);
}
if (messages.isEmpty() && !running) {
throw new IOException(CLOSED_PIPE);
throw new IOException(CLOSED_PIPE);
}
}
LOGGER.finest("Polled: " + messages.peek()); //$NON-NLS-1$
@ -216,6 +210,28 @@ public class ReadingRunnable implements Runnable {
}
}
public String getNextMessage(long timeout) throws IOException {
synchronized (lock) {
if (!running) {
throw new IOException(CLOSED_PIPE);
}
waiting = true;
try {
lock.wait(timeout);
} catch (InterruptedException e) {
LOGGER.log(Level.SEVERE, THREAD_INTERRUPTION_EXCEPTION, e);
}
if (messages.isEmpty() && !running) {
throw new IOException(CLOSED_PIPE);
}
waiting = false;
if (messages.isEmpty()) {
return null;
}
return messages.poll();
}
}
/** @param running the running to set */
public void setRunning(boolean running) {
synchronized (lock) {
@ -235,7 +251,7 @@ public class ReadingRunnable implements Runnable {
public boolean hasMessage() throws IOException {
synchronized (lock) {
if (!running) {
throw new IOException(CLOSED_PIPE);
throw new IOException(CLOSED_PIPE);
}
return !messages.isEmpty();
}
@ -283,7 +299,7 @@ public class ReadingRunnable implements Runnable {
try {
start.wait(TIMEOUT);
} catch (InterruptedException e) {
LOGGER.log(Level.SEVERE, THREAD_INTERRUPTION_EXCEPTION,
LOGGER.log(Level.SEVERE, THREAD_INTERRUPTION_EXCEPTION,
e);
}
}

View File

@ -136,6 +136,13 @@ public final class SystemConsoleManager implements ConsoleManager { // NOSONAR
return prompt(prompt);
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.manager.ConsoleManager#prompt(long) */
@Override
public String prompt(long timeout) throws IOException {
return prompt(prompt, timeout);
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.ConsoleManager#prompt(java.lang.String) */
@Override
@ -145,6 +152,15 @@ public final class SystemConsoleManager implements ConsoleManager { // NOSONAR
return reading.getMessage();
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.ConsoleManager#prompt(java.lang.String) */
@Override
public String prompt(String message, long timeout) throws IOException {
checkOpen();
out.print(message);
return reading.getNextMessage(timeout);
}
/** @param prompt the prompt to set */
@Override
public void setPrompt(String prompt) {