4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
7 * Changhyun Lee <changhyun1.lee@samsung.com>
8 * Kangho Kim <kh5325.kim@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
26 package org.tizen.common.console;
28 import java.io.BufferedReader;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.InputStreamReader;
32 import java.util.List;
34 import org.eclipse.swt.SWT;
38 * Bundled state of a launched process including the threads linking the process
39 * in/output to console documents.
41 public class ConsoleProcessClosure {
44 * Thread which continuously reads from a input stream and pushes the read
45 * data to an output stream which is immediately flushed afterwards.
47 protected static class ReaderThread extends Thread {
49 private InputStream fInputStream;
50 private ConsoleManager fConsole;
51 private boolean fFinished = false;
52 private String lineSeparator;
54 * outputStream can be null
56 public ReaderThread(ThreadGroup group, String name, InputStream in, ConsoleManager out) {
61 lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$
68 BufferedReader reader = new BufferedReader(new InputStreamReader(fInputStream));
70 while ((line = reader.readLine()) != null) {
71 List<TextStyle> ts = AnsicodeAdapter.getStringStyles(line);
74 for (int i=0 ; i< ts.size() ; i++) {
75 fConsole.print(ts.get(i).getStripString(),SWT.NORMAL,ts.get(i).getForeground());
78 fConsole.print(line,SWT.NORMAL,AnsicodeAdapter.BLACK);
80 fConsole.print(lineSeparator,SWT.NORMAL,AnsicodeAdapter.BLACK);
82 } catch (IOException x) {
87 } catch (IOException e) {
96 public synchronized boolean finished() {
100 public synchronized void waitFor() {
104 } catch (InterruptedException e) {
109 public synchronized void complete() {
114 public void close() {
117 fOutputStream.close();
118 } catch (IOException e) {
124 protected static int fCounter = 0;
126 protected Process fProcess;
127 protected ConsoleManager fConsole;
129 protected ReaderThread fOutputReader;
130 protected ReaderThread fErrorReader;
133 * Creates a process closure and connects the launched process with a
136 * @param outputStream
137 * prcess stdout is written to this stream. Can be
138 * <code>null</code>, if not interested in reading the output
140 * prcess stderr is written to this stream. Can be
141 * <code>null</code>, if not interested in reading the output
143 public ConsoleProcessClosure(Process process, ConsoleManager console) {
149 * Live links the launched process with the configured in/out streams using
152 public void runNonBlocking() {
153 ThreadGroup group = new ThreadGroup("SRuncher" + fCounter++); //$NON-NLS-1$
155 InputStream stdin = fProcess.getInputStream();
156 InputStream stderr = fProcess.getErrorStream();
158 fOutputReader = new ReaderThread(group, "OutputReader", stdin, fConsole); //$NON-NLS-1$
159 fErrorReader = new ReaderThread(group, "ErrorReader", stderr, fConsole); //$NON-NLS-1$
161 fOutputReader.start();
162 fErrorReader.start();
165 public void runBlocking() {
168 boolean finished = false;
172 } catch (InterruptedException e) {
173 //System.err.println("Closure exception " +e);
176 fProcess.exitValue();
178 } catch (IllegalThreadStateException e) {
179 //System.err.println("Closure exception " +e);
183 // @@@FIXME: Windows 2000 is screwed; double-check using output threads
184 if (!fOutputReader.finished()) {
185 fOutputReader.waitFor();
188 if (!fErrorReader.finished()) {
189 fErrorReader.waitFor();
192 fOutputReader.close();
193 fErrorReader.close();
194 // it seems that thread termination and stream closing is working
198 fOutputReader = null;
202 public boolean isAlive() {
203 if (fProcess != null) {
204 if (fOutputReader.isAlive() || fErrorReader.isAlive()) {
208 fOutputReader.close();
209 fErrorReader.close();
210 fOutputReader = null;
217 * The same functionality as "isAlive()"
218 * but does not affect out streams,
219 * because they can be shared among processes
221 public boolean isRunning() {
222 if (fProcess != null) {
223 if (fOutputReader.isAlive() || fErrorReader.isAlive()) {
231 * Forces the termination the launched process
233 public void terminate() {
234 if (fProcess != null) {
238 if (!fOutputReader.finished()) {
239 fOutputReader.waitFor();
241 if (!fErrorReader.finished()) {
242 fErrorReader.waitFor();
244 fOutputReader.close();
245 fErrorReader.close();
246 fOutputReader = null;