| /* |
| * 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 timeout 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 timeout) throws InterruptedException { |
| |
| final long until = System.currentTimeMillis() + timeout; |
| |
| while (!hasResult() && System.currentTimeMillis() < until) { |
| Thread.sleep(SLEEP_TIME_MS); |
| } |
| } |
| } |