/******************************************************************************* * Copyright (c) 2008 xored software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * xored software, Inc. - initial API and Implementation (Alex Panchenko) *******************************************************************************/ package org.eclipse.dltk.tcl.internal.core.packages; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.dltk.core.DLTKCore; import org.eclipse.dltk.tcl.core.TclPackagesManager; public class ProcessOutputCollector { private static final int TIMEOUT = 50000; private static class ErrorStreamReaderThread extends Thread { final InputStream stream; /** * @param stream */ public ErrorStreamReaderThread(InputStream stream) { this.stream = stream; } /* * @see java.lang.Thread#run() */ public void run() { byte[] buffer = new byte[256]; try { while (stream.read(buffer) != -1) { // ignore } } catch (IOException e) { // ignore } } } private static class OutputReaderThread extends Thread { final InputStream stream; final String endOfStreamMarker; final List<String> output = new ArrayList<String>(); private IProgressMonitor monitor; private Process process; /** * @param process * @param stream * @param monitor */ public OutputReaderThread(Process process, InputStream stream, String endOfStreamMarker, IProgressMonitor monitor) { this.process = process; this.stream = stream; this.endOfStreamMarker = endOfStreamMarker; this.monitor = monitor; } /* * @see java.lang.Thread#run() */ public void run() { final BufferedReader input = new BufferedReader( new InputStreamReader(stream)); try { while (true) { final String line = input.readLine(); if (line == null) { break; } if (line.indexOf(endOfStreamMarker) >= 0) { output.add(line); break; } output.add(line); monitor.worked(1); } } catch (IOException e) { // ignore } // Wait for termination of process try { process.waitFor(); } catch (InterruptedException e) { DLTKCore.error(e); } } } public static List<String> execute(Process process) { return execute(process, new NullProgressMonitor()); } /** * @since 2.0 */ public static List<String> execute(Process process, IProgressMonitor monitor) { try { process.getOutputStream().close(); } catch (Exception e) { e.printStackTrace(); } final InputStream errorStream = process.getErrorStream(); new ErrorStreamReaderThread(errorStream).start(); final InputStream inputStream = process.getInputStream(); final OutputReaderThread output = new OutputReaderThread(process, inputStream, TclPackagesManager.END_OF_STREAM, monitor); output.start(); // TODO also we should check if process is terminated try { output.join(TIMEOUT); } catch (InterruptedException e) { // } try { errorStream.close(); } catch (IOException e) { // } try { inputStream.close(); } catch (IOException e) { // } process.destroy(); return output.output; } }