blob: d47cfe772becd28fb264eec17fe0604a9c3e3d2d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.commons.exec;
/**
* A default implementation of 'ExecuteResultHandler' used for asynchronous
* process handling.
*
*/
public class DefaultExecuteResultHandler implements ExecuteResultHandler {
/** the interval polling the result */
private static final int SLEEP_TIME_MS = 50;
/** Keep track if the process is still running */
private volatile boolean hasResult;
/** The exit value of the finished process */
private volatile int exitValue;
/** Any offending exception */
private volatile ExecuteException exception;
/**
* Constructor.
*/
public DefaultExecuteResultHandler() {
this.hasResult = false;
this.exitValue = Executor.INVALID_EXITVALUE;
}
/**
* @see org.apache.commons.exec.ExecuteResultHandler#onProcessComplete(int)
*/
@Override
public void onProcessComplete(final int exitValue) {
this.exitValue = exitValue;
this.exception = null;
this.hasResult = true;
}
/**
* @see org.apache.commons.exec.ExecuteResultHandler#onProcessFailed(org.apache.commons.exec.ExecuteException)
*/
@Override
public void onProcessFailed(final ExecuteException e) {
this.exitValue = e.getExitValue();
this.exception = e;
this.hasResult = true;
}
/**
* Get the {@code exception} causing the process execution to fail.
*
* @return Returns the exception.
* @throws IllegalStateException if the process has not exited yet
*/
public ExecuteException getException() {
if (!hasResult) {
throw new IllegalStateException("The process has not exited yet therefore no result is available ...");
}
return exception;
}
/**
* Get the {@code exitValue} of the process.
*
* @return Returns the exitValue.
* @throws IllegalStateException if the process has not exited yet
*/
public int getExitValue() {
if (!hasResult) {
throw new IllegalStateException("The process has not exited yet therefore no result is available ...");
}
return exitValue;
}
/**
* Has the process exited and a result is available, i.e. exitCode or exception?
*
* @return true if a result of the execution is available
*/
public boolean hasResult() {
return hasResult;
}
/**
* Causes the current thread to wait, if necessary, until the
* process has terminated. This method returns immediately if
* the process has already terminated. If the process has
* not yet terminated, the calling thread will be blocked until the
* process exits.
*
* @throws InterruptedException if the current thread is
* {@linkplain Thread#interrupt() interrupted} by another
* thread while it is waiting, then the wait is ended and
* an {@link InterruptedException} is thrown.
*/
public void waitFor() throws InterruptedException {
while (!hasResult()) {
Thread.sleep(SLEEP_TIME_MS);
}
}
/**
* Causes the current thread to wait, if necessary, until the
* process has terminated. This method returns immediately if
* the process has already terminated. If the process has
* not yet terminated, the calling thread will be blocked until the
* process exits.
*
* @param timeoutMillis the maximum time to wait in milliseconds
* @throws InterruptedException if the current thread is
* {@linkplain Thread#interrupt() interrupted} by another
* thread while it is waiting, then the wait is ended and
* an {@link InterruptedException} is thrown.
*/
public void waitFor(final long timeoutMillis) throws InterruptedException {
final long untilMillis = System.currentTimeMillis() + timeoutMillis;
while (!hasResult() && System.currentTimeMillis() < untilMillis) {
Thread.sleep(SLEEP_TIME_MS);
}
}
}