blob: 8b6dcef3abdc1160d66188cd93ffdf6ff27cec6d [file] [log] [blame]
// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed 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 com.google.enterprise.adaptor.prebuilt;
import java.io.*;
/**
* Exec helper that allows easy handling of stdin, stdout, and stderr. Normally
* you have to worry about deadlock when dealing with those streams (as
* mentioned briefly in {@link Process}), so this class handles that for you.
*/
public class Command {
// Prevent instantiation.
private Command() {}
/**
* Same as {@code exec(command, null, new byte[0])}.
*
*/
public static Result exec(String[] command) throws IOException,
InterruptedException {
return exec(command, null, new byte[0]);
}
/**
* Same as {@code exec(command, workingDir, new byte[0])}.
*
* @see #exec(String[], File, byte[])
*/
public static Result exec(String[] command, File workingDir)
throws IOException, InterruptedException {
return exec(command, workingDir, new byte[0]);
}
/**
* Same as {@code exec(command, null, stdin)}.
*
* @see #exec(String[], File, byte[])
*/
public static Result exec(String[] command, byte[] stdin) throws IOException,
InterruptedException {
return exec(command, null, stdin);
}
/**
* Create process {@code command} starting in the {@code workingDir} and
* providing {@code stdin} as input. This method blocks until the process
* exits. Stdout and stderr are available via {@link Result#getStdout} and
* {@link Result#getStderr}. Before using them, however, you should generally
* make sure that the process exited with a return code of zero, as other
* return codes typically indicate an error.
*
* @throws IOException if creating process fails
*/
public static Result exec(String[] command, File workingDir, byte[] stdin)
throws IOException, InterruptedException {
ByteArrayOutputStream outBuffer = new ByteArrayOutputStream();
ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
int returnCode = StreamingCommand.exec(command, workingDir,
StreamingCommand.streamInputSource(new ByteArrayInputStream(stdin)),
StreamingCommand.streamOutputSink(outBuffer),
StreamingCommand.streamOutputSink(errBuffer));
byte[] stdout = outBuffer.toByteArray();
byte[] stderr = errBuffer.toByteArray();
return new Result(returnCode, stdout, stderr);
}
/**
* Result data from an invocation
*/
public static class Result {
private final int returnCode;
private final byte[] stdout;
private final byte[] stderr;
/**
* Construct a result. In normal usage, this is unnecessary, but it can be
* helpful in the tests of classes that use {@code Command}.
*/
public Result(int returnCode, byte[] stdout, byte[] stderr) {
if (stdout == null || stderr == null) {
throw new NullPointerException();
}
this.returnCode = returnCode;
this.stdout = stdout;
this.stderr = stderr;
}
public int getReturnCode() {
return returnCode;
}
/**
* Returns internal byte array without copying.
*/
public byte[] getStdout() {
return stdout;
}
/**
* Returns internal byte array without copying.
*/
public byte[] getStderr() {
return stderr;
}
}
}