KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > AsynchronousShellCommand


1 /*
2  * AsynchronousShellCommand.java
3  *
4  * Copyright (C) 2000-2002 Peter Graves
5  * $Id: AsynchronousShellCommand.java,v 1.4 2003/04/04 14:03:04 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.util.List JavaDoc;
27 import javax.swing.SwingUtilities JavaDoc;
28
29 public final class AsynchronousShellCommand implements Constants, Runnable JavaDoc
30 {
31     private final String JavaDoc command;
32     private final File directory;
33     private final String JavaDoc cmdline;
34     private final ShellCommandOutputBuffer outputBuffer;
35     private final Position posEndOfBuffer;
36
37     private Process JavaDoc process;
38     private Thread JavaDoc thread;
39     private ProcessTable processTable;
40
41     public AsynchronousShellCommand(String JavaDoc command, File directory,
42         ShellCommandOutputBuffer buf)
43     {
44         this.command = command;
45         this.directory = directory;
46         cmdline = "(\\cd " + directory.canonicalPath() + " && " + command + ")";
47         this.outputBuffer = buf;
48         this.posEndOfBuffer = new Position(buf.getFirstLine(), 0);
49         buf.setShellCommand(this);
50     }
51
52     private void start()
53     {
54         thread = new Thread JavaDoc(this);
55         thread.start();
56     }
57
58     public void run()
59     {
60         if (!Platform.isPlatformUnix()) {
61             Debug.bug();
62             return;
63         }
64         try {
65             if (cmdline != null) {
66                 String JavaDoc[] cmdarray = {"/bin/sh", "-c", cmdline};
67                 process = Runtime.getRuntime().exec(cmdarray);
68             }
69         }
70         catch (IOException JavaDoc e) {
71             Log.error(e);
72         }
73         if (process != null) {
74             ShellCommandReaderThread stdoutThread =
75                 new ShellCommandReaderThread(process.getInputStream());
76             stdoutThread.start();
77             ShellCommandReaderThread stderrThread =
78                 new ShellCommandReaderThread(process.getErrorStream());
79             stderrThread.start();
80             processTable = ProcessTable.getProcessTable();
81             try {
82                 process.waitFor();
83             }
84             catch (InterruptedException JavaDoc e) {
85                 // User has closed the output buffer.
86
killProcess();
87             }
88         }
89     }
90
91     private void interrupt()
92     {
93         if (thread != null)
94             thread.interrupt();
95     }
96
97     private void killProcess()
98     {
99         if (processTable != null) {
100             List JavaDoc entries = processTable.findMatchingEntries(cmdline);
101             if (entries != null && entries.size() > 0) {
102                 // We want the last matching entry.
103
ProcessTableEntry parent =
104                     (ProcessTableEntry) entries.get(entries.size()-1);
105                 if (parent != null) {
106                     List JavaDoc children = processTable.findChildren(parent.pid);
107                     if (children != null) {
108                         for (int i = 0; i < children.size(); i++) {
109                             ProcessTableEntry entry =
110                                 (ProcessTableEntry) children.get(i);
111                             Utilities.kill(entry.pid);
112                         }
113                     }
114                 }
115             }
116             try {
117                 process.waitFor();
118             }
119             catch (InterruptedException JavaDoc e) {
120                 Log.debug(e);
121             }
122         }
123     }
124
125     private void appendLater(final String JavaDoc s)
126     {
127         Runnable JavaDoc runnable = new Runnable JavaDoc() {
128             public void run()
129             {
130                 outputBuffer.insertString(posEndOfBuffer, s);
131                 if (outputBuffer.needsRenumbering())
132                     outputBuffer.renumber();
133                 outputBuffer.enforceOutputLimit(Property.SHELL_OUTPUT_LIMIT);
134                 for (EditorIterator it = new EditorIterator(); it.hasNext();) {
135                     Editor ed = it.nextEditor();
136                     if (ed.getBuffer() == outputBuffer) {
137                         ed.eob();
138                         ed.getDisplay().setReframe(-2);
139                         ed.setUpdateFlag(REPAINT);
140                         ed.updateDisplay();
141                     }
142                 }
143             }
144         };
145         SwingUtilities.invokeLater(runnable);
146     }
147
148     private class ShellCommandReaderThread extends ReaderThread
149     {
150         public ShellCommandReaderThread(InputStream JavaDoc inputStream)
151         {
152             super(inputStream);
153         }
154
155         public void update(final String JavaDoc s)
156         {
157             appendLater(s);
158         }
159     }
160
161     private static class ShellCommandOutputBuffer extends Buffer
162     {
163         private AsynchronousShellCommand shellCommand;
164
165         public ShellCommandOutputBuffer()
166         {
167             supportsUndo = false;
168             type = TYPE_OUTPUT;
169             mode = PlainTextMode.getMode();
170             formatter = new PlainTextFormatter(this);
171             lineSeparator = System.getProperty("line.separator");
172             readOnly = true;
173             setTransient(true);
174             setProperty(Property.VERTICAL_RULE, 0);
175             setProperty(Property.SHOW_CHANGE_MARKS, false);
176             setProperty(Property.SHOW_LINE_NUMBERS, false);
177             setProperty(Property.HIGHLIGHT_MATCHING_BRACKET, false);
178             setProperty(Property.HIGHLIGHT_BRACKETS, false);
179             try {
180                 lockWrite();
181             }
182             catch (InterruptedException JavaDoc e) {
183                 Log.debug(e);
184                 return;
185             }
186             try {
187                 appendLine("");
188                 renumber();
189             }
190             finally {
191                 unlockWrite();
192             }
193             setInitialized(true);
194         }
195
196         public void setShellCommand(AsynchronousShellCommand shellCommand)
197         {
198             this.shellCommand = shellCommand;
199         }
200
201         public int load()
202         {
203             return LOAD_COMPLETED;
204         }
205
206         public String JavaDoc getFileNameForDisplay()
207         {
208             return title != null ? title : "";
209         }
210
211         public boolean isModified()
212         {
213             return false;
214         }
215
216         public void dispose()
217         {
218             if (shellCommand != null)
219                 shellCommand.interrupt();
220         }
221     }
222
223     public static void startShellCommand(Editor editor, String JavaDoc command)
224     {
225         final File dir = editor.getCurrentDirectory();
226         if (dir == null || !dir.isDirectory())
227             return;
228         ShellCommandOutputBuffer buf = new ShellCommandOutputBuffer();
229         buf.setTitle(command);
230         editor.makeNext(buf);
231         editor.activateInOtherWindow(buf);
232         AsynchronousShellCommand shellCommand =
233             new AsynchronousShellCommand(command, dir, buf);
234         shellCommand.start();
235     }
236 }
237
Popular Tags