Temporarily include bndlib 1.47 for testing purposes (not yet on central)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1185095 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/libg/command/Command.java b/bundleplugin/src/main/java/aQute/libg/command/Command.java
new file mode 100644
index 0000000..bae82eb
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/command/Command.java
@@ -0,0 +1,194 @@
+package aQute.libg.command;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import aQute.libg.reporter.*;
+
+public class Command {
+
+ boolean trace;
+ Reporter reporter;
+ List<String> arguments = new ArrayList<String>();
+ long timeout = 0;
+ File cwd = new File("").getAbsoluteFile();
+ static Timer timer = new Timer();
+ Process process;
+ volatile boolean timedout;
+
+ public int execute(Appendable stdout, Appendable stderr) throws Exception {
+ return execute((InputStream) null, stdout, stderr);
+ }
+
+ public int execute(String input, Appendable stdout, Appendable stderr) throws Exception {
+ InputStream in = new ByteArrayInputStream(input.getBytes("UTF-8"));
+ return execute(in, stdout, stderr);
+ }
+
+ public int execute(InputStream in, Appendable stdout, Appendable stderr) throws Exception {
+ int result;
+ if (reporter != null) {
+ reporter.trace("executing cmd: %s", arguments);
+ }
+
+ String args[] = arguments.toArray(new String[arguments.size()]);
+
+ process = Runtime.getRuntime().exec(args, null, cwd);
+
+ // Make sure the command will not linger when we go
+ Runnable r = new Runnable() {
+ public void run() {
+ process.destroy();
+ }
+ };
+ Thread hook = new Thread(r, arguments.toString());
+ Runtime.getRuntime().addShutdownHook(hook);
+ TimerTask timer = null;
+ OutputStream stdin = process.getOutputStream();
+ final InputStreamHandler handler = in != null ? new InputStreamHandler(in, stdin) : null;
+
+ if (timeout != 0) {
+ timer = new TimerTask() {
+ public void run() {
+ timedout = true;
+ process.destroy();
+ if (handler != null)
+ handler.interrupt();
+ }
+ };
+ Command.timer.schedule(timer, timeout);
+ }
+
+ InputStream out = process.getInputStream();
+ try {
+ InputStream err = process.getErrorStream();
+ try {
+ new Collector(out, stdout).start();
+ new Collector(err, stdout).start();
+ if (handler != null)
+ handler.start();
+
+ result = process.waitFor();
+ } finally {
+ err.close();
+ }
+ } finally {
+ out.close();
+ if (timer != null)
+ timer.cancel();
+ Runtime.getRuntime().removeShutdownHook(hook);
+ if (handler != null)
+ handler.interrupt();
+ }
+ if (reporter != null)
+ reporter.trace("cmd %s executed with result=%d, result: %s/%s", arguments, result,
+ stdout, stderr);
+
+ if( timedout )
+ return Integer.MIN_VALUE;
+ byte exitValue = (byte) process.exitValue();
+ return exitValue;
+ }
+
+ public void add(String... args) {
+ for (String arg : args)
+ arguments.add(arg);
+ }
+
+ public void addAll(Collection<String> args) {
+ arguments.addAll(args);
+ }
+
+ public void setTimeout(long duration, TimeUnit unit) {
+ timeout = unit.toMillis(duration);
+ }
+
+ public void setTrace() {
+ this.trace = true;
+ }
+
+ public void setReporter(Reporter reporter) {
+ this.reporter = reporter;
+ }
+
+ public void setCwd(File dir) {
+ if (!dir.isDirectory())
+ throw new IllegalArgumentException("Working directory must be a directory: " + dir);
+
+ this.cwd = dir;
+ }
+
+ public void cancel() {
+ process.destroy();
+ }
+
+ class Collector extends Thread {
+ final InputStream in;
+ final Appendable sb;
+
+ public Collector(InputStream inputStream, Appendable sb) {
+ this.in = inputStream;
+ this.sb = sb;
+ }
+
+ public void run() {
+ try {
+ int c = in.read();
+ while (c >= 0) {
+ if (trace)
+ System.out.print((char) c);
+ sb.append((char) c);
+ c = in.read();
+ }
+ } catch (Exception e) {
+ try {
+ sb.append("\n**************************************\n");
+ sb.append(e.toString());
+ sb.append("\n**************************************\n");
+ } catch (IOException e1) {
+ }
+ if (reporter != null) {
+ reporter.trace("cmd exec: %s", e);
+ }
+ }
+ }
+ }
+
+ class InputStreamHandler extends Thread {
+ final InputStream in;
+ final OutputStream stdin;
+
+ public InputStreamHandler(InputStream in, OutputStream stdin) {
+ this.stdin = stdin;
+ this.in = in;
+ }
+
+ public void run() {
+ try {
+ int c = in.read();
+ while (c >= 0) {
+ stdin.write(c);
+ stdin.flush();
+ c = in.read();
+ }
+ } catch (InterruptedIOException e) {
+ // Ignore here
+ } catch (Exception e) {
+ // Who cares?
+ }
+ }
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ String del = "";
+
+ for (String argument : arguments) {
+ sb.append(del);
+ sb.append(argument);
+ del = " ";
+ }
+ return sb.toString();
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/command/packageinfo b/bundleplugin/src/main/java/aQute/libg/command/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/command/packageinfo
@@ -0,0 +1 @@
+version 1.0