KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > terminalemulator > StreamTerm


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is Terminal Emulator.
16  * The Initial Developer of the Original Software is Sun Microsystems, Inc..
17  * Portions created by Sun Microsystems, Inc. are Copyright (C) 2001-2004.
18  * All Rights Reserved.
19  *
20  * Contributor(s): Ivan Soleimanipour.
21  */

22
23 package org.netbeans.lib.terminalemulator;
24
25 import java.io.*;
26 import java.awt.*;
27 import javax.swing.SwingUtilities JavaDoc;
28
29 public class StreamTerm extends Term {
30
31     static class Fmt {
32     public static String JavaDoc pad(int what, int width) {
33         return pad("" + what, width);
34     }
35     public static String JavaDoc pad(byte what, int width) {
36         return pad("" + (char) what, width);
37     }
38     public static String JavaDoc pad0(String JavaDoc what, int width) {
39         return padwith(what, width, '0');
40     }
41     public static String JavaDoc pad(String JavaDoc what, int width) {
42         return padwith(what, width, ' ');
43     }
44     private static String JavaDoc padwith(String JavaDoc what, int width, char with) {
45         boolean left = false;
46         if (width < 0) {
47         left = true;
48         width = -width;
49         }
50         String JavaDoc sub;
51         if (what.length() > width)
52         sub = what.substring(0, width); // prevent overflow
53
else
54         sub = what;
55         int pad = width - sub.length();
56         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(sub);
57         if (left) {
58         while(pad-- > 0)
59             buf.append(with);
60         } else {
61         while(pad-- > 0)
62             buf.insert(0, with);
63         }
64         return new String JavaDoc(buf);
65     }
66     }
67
68     private OutputStreamWriter writer; // writes to child process
69

70     /*
71      * Return the OutputStreamWriter used for writing to the child.
72      *
73      * This can be used to send characters to the child process explicitly
74      * as if they were typed at the keyboard.
75      */

76     public OutputStreamWriter getOutputStreamWriter() {
77     return writer;
78     }
79
80     public StreamTerm() {
81     super();
82
83     addInputListener(new TermInputListener() {
84         public void sendChars(char c[], int offset, int count) {
85         if (writer == null)
86             return;
87         try {
88             writer.write(c, offset, count);
89             writer.flush();
90         } catch(Exception JavaDoc x) {
91             x.printStackTrace();
92         }
93         }
94
95         public void sendChar(char c) {
96         if (writer == null)
97             return;
98         try {
99             writer.write(c);
100             // writer is buffered, need to use flush!
101
// perhaps SHOULD use an unbuffered writer?
102
// Also fix send_chars()
103
writer.flush();
104         } catch(Exception JavaDoc x) {
105             x.printStackTrace();
106         }
107         }
108     } );
109     }
110
111     /*
112      * Monitor output from process and forward to terminal
113      */

114     private class OutputMonitor extends Thread JavaDoc {
115     private static final int BUFSZ = 1024;
116     private char[] buf = new char[BUFSZ];
117     private Term term;
118     private InputStreamReader reader;
119
120     OutputMonitor(InputStreamReader reader, Term term) {
121         super("StreamTerm.OutputMonitor"); // NOI18N
122
this.reader = reader;
123         this.term = term;
124
125         // Fix for bug 4921071
126
// NetBeans has many request processors running at P1 so
127
// a default priority of this thread will swamp all the RPs
128
// if we have a firehose sub-process.
129
setPriority(1);
130     }
131
132     private void db_echo_receipt(char buf[], int offset, int count) {
133         /*
134          * Debugging function
135          */

136         System.out.println("Received:"); // NOI18N
137
final int width = 20;
138         int cx = 0;
139         while (cx < count) {
140         // print numbers
141
int cx0 = cx;
142         System.out.print(Fmt.pad(cx, 4) + ": "); // NOI18N
143
for (int x = 0; x < width && cx < count; cx++, x++) {
144             String JavaDoc hex = Integer.toHexString(buf[offset+cx]);
145             System.out.print(Fmt.pad0(hex, 2) + " "); // NOI18N
146
}
147         System.out.println();
148
149         // print charcters
150
cx = cx0;
151         System.out.print(" "); // NOI18N
152
for (int x = 0; x < width && cx < count; cx++, x++) {
153             char c = (char) buf[offset+cx];
154             if (Character.isISOControl(c))
155             c = ' ';
156             System.out.print(Fmt.pad((byte)c, 2) + " "); // NOI18N
157
}
158         System.out.println();
159         }
160     }
161
162     final private class Trampoline implements Runnable JavaDoc {
163         public int nread;
164         public void run() {
165         term.putChars(buf, 0, nread);
166         }
167     }
168
169     public void run() {
170         Trampoline tramp = new Trampoline();
171
172         try {
173         while(true) {
174             int nread = reader.read(buf, 0, BUFSZ);
175             if (nread == -1) {
176             // This happens if someone closes the input stream,
177
// say the master end of the pty.
178
/* When we clean up this gets closed so it's not
179                always an error.
180             System.err.println("com.sun.spro.Term.OutputMonitor: " + // NOI18N
181                 "Input stream closed");inp // NOI18N
182             */

183             break;
184             }
185             if (debugInput())
186             db_echo_receipt(buf, 0, nread);
187
188             if (false) {
189             term.putChars(buf, 0, nread);
190             } else {
191             // InvokeAndWait() is surprisingly fast and
192
// eliminates one whole set of MT headaches.
193
tramp.nread = nread;
194             SwingUtilities.invokeAndWait(tramp);
195             }
196         }
197         reader.close();
198         } catch(Exception JavaDoc x) {
199         x.printStackTrace();
200         }
201     }
202     }
203
204     /**
205      * Connect an I/O stream pair or triple to this Term.
206      *
207      * @param pin Input (and paste operations) to the sub-process.
208      * this stream.
209      * @param pout Main output from the sub-process. Stuff received via this
210      * stream will be rendered on the screen.
211      * @param perr Error output from process. May be null if the error stream
212      * is already absorbed into 'pout' as the case might be with
213      * ptys.
214      */

215     public void connect(OutputStream pin, InputStream pout, InputStream perr) {
216
217     // Now that we have a stream force resize notifications to be sent out.
218
updateTtySize();
219
220     if (pin != null)
221         writer = new OutputStreamWriter(pin);
222
223     InputStreamReader out_reader = new InputStreamReader(pout);
224     OutputMonitor out_monitor = new OutputMonitor(out_reader, this);
225     out_monitor.start();
226
227     if (perr != null) {
228         InputStreamReader err_reader = new InputStreamReader(perr);
229         OutputMonitor err_monitor = new OutputMonitor(err_reader, this);
230         err_monitor.start();
231     }
232     }
233
234 }
235
Popular Tags