001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018 019package org.apache.commons.exec; 020 021/** 022 * A default implementation of 'ExecuteResultHandler' used for asynchronous 023 * process handling. 024 * 025 * @version $Id: DefaultExecuteResultHandler.java 1636057 2014-11-01 21:14:00Z ggregory $ 026 */ 027public class DefaultExecuteResultHandler implements ExecuteResultHandler { 028 029 /** the interval polling the result */ 030 private static final int SLEEP_TIME_MS = 50; 031 032 /** Keep track if the process is still running */ 033 private volatile boolean hasResult; 034 035 /** The exit value of the finished process */ 036 private volatile int exitValue; 037 038 /** Any offending exception */ 039 private volatile ExecuteException exception; 040 041 /** 042 * Constructor. 043 */ 044 public DefaultExecuteResultHandler() { 045 this.hasResult = false; 046 this.exitValue = Executor.INVALID_EXITVALUE; 047 } 048 049 /** 050 * @see org.apache.commons.exec.ExecuteResultHandler#onProcessComplete(int) 051 */ 052 public void onProcessComplete(final int exitValue) { 053 this.exitValue = exitValue; 054 this.exception = null; 055 this.hasResult = true; 056 } 057 058 /** 059 * @see org.apache.commons.exec.ExecuteResultHandler#onProcessFailed(org.apache.commons.exec.ExecuteException) 060 */ 061 public void onProcessFailed(final ExecuteException e) { 062 this.exitValue = e.getExitValue(); 063 this.exception = e; 064 this.hasResult = true; 065 } 066 067 /** 068 * Get the {@code exception} causing the process execution to fail. 069 * 070 * @return Returns the exception. 071 * @throws IllegalStateException if the process has not exited yet 072 */ 073 public ExecuteException getException() { 074 075 if (!hasResult) { 076 throw new IllegalStateException("The process has not exited yet therefore no result is available ..."); 077 } 078 079 return exception; 080 } 081 082 /** 083 * Get the {@code exitValue} of the process. 084 * 085 * @return Returns the exitValue. 086 * @throws IllegalStateException if the process has not exited yet 087 */ 088 public int getExitValue() { 089 090 if (!hasResult) { 091 throw new IllegalStateException("The process has not exited yet therefore no result is available ..."); 092 } 093 094 return exitValue; 095 } 096 097 /** 098 * Has the process exited and a result is available, i.e. exitCode or exception? 099 * 100 * @return true if a result of the execution is available 101 */ 102 public boolean hasResult() { 103 return hasResult; 104 } 105 106 /** 107 * Causes the current thread to wait, if necessary, until the 108 * process has terminated. This method returns immediately if 109 * the process has already terminated. If the process has 110 * not yet terminated, the calling thread will be blocked until the 111 * process exits. 112 * 113 * @exception InterruptedException if the current thread is 114 * {@linkplain Thread#interrupt() interrupted} by another 115 * thread while it is waiting, then the wait is ended and 116 * an {@link InterruptedException} is thrown. 117 */ 118 public void waitFor() throws InterruptedException { 119 120 while (!hasResult()) { 121 Thread.sleep(SLEEP_TIME_MS); 122 } 123 } 124 125 /** 126 * Causes the current thread to wait, if necessary, until the 127 * process has terminated. This method returns immediately if 128 * the process has already terminated. If the process has 129 * not yet terminated, the calling thread will be blocked until the 130 * process exits. 131 * 132 * @param timeout the maximum time to wait in milliseconds 133 * @exception InterruptedException if the current thread is 134 * {@linkplain Thread#interrupt() interrupted} by another 135 * thread while it is waiting, then the wait is ended and 136 * an {@link InterruptedException} is thrown. 137 */ 138 public void waitFor(final long timeout) throws InterruptedException { 139 140 final long until = System.currentTimeMillis() + timeout; 141 142 while (!hasResult() && System.currentTimeMillis() < until) { 143 Thread.sleep(SLEEP_TIME_MS); 144 } 145 } 146}