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
021import java.io.File;
022import java.io.IOException;
023import java.util.Map;
024
025/**
026 * The main abstraction to start an external process.
027 *
028 * The interface allows to
029 * <ul>
030 *  <li>set a current working directory for the subprocess</li>
031 *  <li>provide a set of environment variables passed to the subprocess</li>
032 *  <li>capture the subprocess output of stdout and stderr using an ExecuteStreamHandler</li>
033 *  <li>kill long-running processes using an ExecuteWatchdog</li>
034 *  <li>define a set of expected exit values</li>
035 *  <li>terminate any started processes when the main process is terminating using a ProcessDestroyer</li>
036 * </ul>
037 *
038 * The following example shows the basic usage:
039 *
040 * <pre>
041 * Executor exec = new DefaultExecutor();
042 * CommandLine cl = new CommandLine("ls -l");
043 * int exitvalue = exec.execute(cl);
044 * </pre>
045 *
046 * @version $Id: Executor.java 1557338 2014-01-11 10:34:22Z sebb $
047 */
048
049public interface Executor {
050
051    /** Invalid exit code. */
052    int INVALID_EXITVALUE = 0xdeadbeef;
053
054    /**
055     * Define the <code>exitValue</code> of the process to be considered
056     * successful. If a different exit value is returned by
057     * the process then {@link org.apache.commons.exec.Executor#execute(CommandLine)}
058     * will throw an {@link org.apache.commons.exec.ExecuteException} 
059     *
060     * @param value the exit code representing successful execution
061     */
062    void setExitValue(final int value);
063
064    /**
065     * Define a list of <code>exitValue</code> of the process to be considered
066     * successful. The caller can pass one of the following values
067     * <ul>
068     *  <li>an array of exit values to be considered successful</li>
069     *  <li>an empty array for auto-detect of successful exit codes relying on {@link org.apache.commons.exec.Executor#isFailure(int)}</li>
070     *  <li>null to indicate to skip checking of exit codes</li>
071     * </ul>
072     *
073     * If an undefined exit value is returned by the process then
074     * {@link org.apache.commons.exec.Executor#execute(CommandLine)}  will
075     * throw an {@link org.apache.commons.exec.ExecuteException}.
076     *
077     * @param values a list of the exit codes
078     */
079    void setExitValues(final int[] values);
080
081    /**
082     * Checks whether <code>exitValue</code> signals a failure. If no
083     * exit values are set than the default conventions of the OS is
084     * used. e.g. most OS regard an exit code of '0' as successful
085     * execution and everything else as failure.
086     *
087     * @param exitValue the exit value (return code) to be checked
088     * @return <code>true</code> if <code>exitValue</code> signals a failure
089     */
090    boolean isFailure(final int exitValue);
091
092    /**
093     * Get the StreamHandler used for providing input and
094     * retrieving the output.
095     * 
096     * @return the StreamHandler 
097     */
098    ExecuteStreamHandler getStreamHandler();
099
100    /**
101     * Set a custom the StreamHandler used for providing
102     * input and retrieving the output. If you don't provide
103     * a proper stream handler the executed process might block
104     * when writing to stdout and/or stderr (see
105     * {@link java.lang.Process Process}).
106     *
107     * @param streamHandler the stream handler
108     */
109    void setStreamHandler(ExecuteStreamHandler streamHandler);
110
111    /**
112     * Get the watchdog used to kill of processes running,
113     * typically, too long time.
114     *
115     * @return the watchdog
116     */
117    ExecuteWatchdog getWatchdog();
118
119    /**
120     * Set the watchdog used to kill of processes running, 
121     * typically, too long time.
122     *
123     * @param watchDog the watchdog
124     */
125    void setWatchdog(ExecuteWatchdog watchDog);
126
127    /**
128     * Set the handler for cleanup of started processes if the main process
129     * is going to terminate.
130     *
131     * @return the ProcessDestroyer
132     */
133    ProcessDestroyer getProcessDestroyer();
134
135    /**
136     * Get the handler for cleanup of started processes if the main process
137     * is going to terminate.
138     *
139     * @param processDestroyer the ProcessDestroyer
140     */
141    void setProcessDestroyer(ProcessDestroyer processDestroyer);
142
143    /**
144     * Get the working directory of the created process.
145     *
146     * @return the working directory
147     */
148    File getWorkingDirectory();
149
150    /**
151     * Set the working directory of the created process. The
152     * working directory must exist when you start the process.
153     *
154     * @param dir the working directory
155     */
156    void setWorkingDirectory(File dir);
157
158    /**
159     * Methods for starting synchronous execution. The child process inherits
160     * all environment variables of the parent process.
161     *
162     * @param command the command to execute
163     * @return process exit value
164     * @throws ExecuteException execution of subprocess failed or the
165     *          subprocess returned a exit value indicating a failure
166     *          {@link Executor#setExitValue(int)}.
167     */
168    int execute(CommandLine command)
169        throws ExecuteException, IOException;
170
171    /**
172     * Methods for starting synchronous execution.
173     *
174     * @param command the command to execute
175     * @param environment The environment for the new process. If null, the
176     *          environment of the current process is used.
177     * @return process exit value
178     * @throws ExecuteException execution of subprocess failed or the
179     *          subprocess returned a exit value indicating a failure
180     *          {@link Executor#setExitValue(int)}.
181     */
182    int execute(CommandLine command, Map<String, String> environment)
183        throws ExecuteException, IOException;
184    
185    /**
186     * Methods for starting asynchronous execution. The child process inherits
187     * all environment variables of the parent process. Result provided to
188     * callback handler.
189     *
190     * @param command the command to execute
191     * @param handler capture process termination and exit code
192     * @throws ExecuteException execution of subprocess failed
193     */
194    void execute(CommandLine command, ExecuteResultHandler handler)
195        throws ExecuteException, IOException;
196
197    /**
198     * Methods for starting asynchronous execution. The child process inherits
199     * all environment variables of the parent process. Result provided to
200     * callback handler.
201     *
202     * @param command the command to execute
203     * @param environment The environment for the new process. If null, the
204     *          environment of the current process is used.
205     * @param handler capture process termination and exit code 
206     * @throws ExecuteException execution of subprocess failed     
207     */
208    void execute(CommandLine command, Map<String, String> environment, ExecuteResultHandler handler)
209        throws ExecuteException, IOException;
210}