Statistics
| Revision:

root / import / ext3D / trunk / install-extension3d / IzPack / src / lib / com / izforge / izpack / util / Console.java @ 15280

History | View | Annotate | Download (14.4 KB)

1
/*
2
 *  $Id: Console.java,v 1.1 2006/06/14 07:29:07 cesar Exp $
3
 *  IzPack
4
 *  Copyright (C) 2002 Jan Blok (jblok@profdata.nl - PDM - www.profdata.nl)
5
 *
6
 *  File :               Console.java
7
 *  Description :        a Console.
8
 *  Author's email :     jblok@profdata.nl
9
 *  Author's Website :   http://www.profdata.nl
10
 *
11
 *  This program is free software; you can redistribute it and/or
12
 *  modify it under the terms of the GNU General Public License
13
 *  as published by the Free Software Foundation; either version 2
14
 *  of the License, or any later version.
15
 *
16
 *  This program is distributed in the hope that it will be useful,
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 *  GNU General Public License for more details.
20
 *
21
 *  You should have received a copy of the GNU General Public License
22
 *  along with this program; if not, write to the Free Software
23
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24
 */
25
package com.izforge.izpack.util;
26

    
27
import java.awt.Dimension;
28
import java.awt.Font;
29
import java.awt.Toolkit;
30
import java.awt.event.KeyEvent;
31
import java.awt.event.KeyListener;
32
import java.io.BufferedOutputStream;
33
import java.io.BufferedReader;
34
import java.io.IOException;
35
import java.io.InputStream;
36
import java.io.InputStreamReader;
37
import java.io.OutputStreamWriter;
38
import java.io.PipedInputStream;
39
import java.io.PipedOutputStream;
40
import java.io.PrintStream;
41
import java.io.PrintWriter;
42

    
43
import javax.swing.JFrame;
44
import javax.swing.JScrollPane;
45
import javax.swing.JTextArea;
46
import javax.swing.SwingUtilities;
47
import javax.swing.event.DocumentEvent;
48
import javax.swing.event.DocumentListener;
49
import javax.swing.text.Document;
50
import javax.swing.text.Segment;
51

    
52
public final class Console
53
{
54
        public static final int INITIAL_WIDTH = 800;
55
        public static final int INITIAL_HEIGHT = 600;
56
        
57
        public static void main(String[] args)
58
        {
59
        Runtime rt = Runtime.getRuntime();
60
        Process p = null;
61
        try 
62
        {
63

    
64
          /*
65
            Start a new process in which to execute the
66
            commands in cmd, using the environment in env
67
            and use pwd as the current working directory.
68
           */
69
          p = rt.exec(args);//, env, pwd);
70
                            new Console(p);
71
                System.exit(p.exitValue());
72
        }
73
        catch (IOException e) 
74
        {
75
            /*
76
              Couldn't even get the command to start.  Most likely 
77
              it couldn't be found because of a typo.
78
            */
79
            System.out.println("Error starting: " + args[0]);
80
            System.out.println(e);
81
        }
82
        }
83
        
84
        private StdOut so;
85
        private StdOut se;
86

    
87
        public String getOutputData()        
88
        {
89
                if (so != null)
90
                {
91
                        return so.getData();
92
                }
93
                else
94
                {
95
                        return "";
96
                }
97
        }
98
        public String getErrorData()        
99
        {
100
                if (se != null)
101
                {
102
                        return se.getData();
103
                }
104
                else
105
                {
106
                        return "";
107
                }
108
        }
109
        
110
        public Console(Process p)
111
        {
112
                JFrame frame = new JFrame();
113
                frame.setTitle("Console");
114
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
115
                frame.setLocation(screenSize.width/2 - INITIAL_WIDTH/2,screenSize.height/2 - INITIAL_HEIGHT/2);
116
                ConsoleTextArea cta = new ConsoleTextArea();
117
                JScrollPane scroll = new JScrollPane(cta);
118
                scroll.setPreferredSize(new Dimension(INITIAL_WIDTH,INITIAL_HEIGHT));
119
                frame.getContentPane().add(scroll);
120
                frame.pack();
121

    
122
        // From here down your shell should be pretty much
123
        // as it is written here!
124
        /*
125
          Start up StdOut, StdIn and StdErr threads that write 
126
          the output generated by the process p to the screen, and
127
          feed the keyboard input into p. 
128
        */
129
        so = new StdOut(p,cta);
130
        se = new StdOut(p,cta);
131
        StdIn si = new StdIn(p,cta);
132
        so.start();
133
        se.start();
134
        si.start();
135
        
136
        // Wait for the process p to complete.
137
        try 
138
        {
139
                        frame.setVisible(true);
140
            p.waitFor();
141
        }
142
        catch (InterruptedException e) 
143
        {
144
            /*
145
              Something bad happened while the command was
146
              executing.
147
            */
148
            System.out.println("Error during execution");
149
            System.out.println(e);
150
        }
151
        
152
        /*
153
          Now signal the StdOut, StdErr and StdIn threads that the 
154
          process is done, and wait for them to complete.
155
        */
156
        try 
157
        {
158
            so.done();
159
            se.done();
160
            si.done();
161
            so.join();
162
            se.join();
163
            si.join();
164
        }
165
        catch (InterruptedException e) 
166
        {                
167
            // Something bad happend to one of the Std threads.
168
            System.out.println("Error in StdOut, StdErr or StdIn.");
169
            System.out.println(e);
170
        }
171
                frame.setVisible(false);
172
    }
173
}
174

    
175
class StdIn extends Thread
176
{
177
        private BufferedReader kb;
178
        private boolean processRunning;
179
        private PrintWriter op;
180

    
181
        public StdIn(Process p,ConsoleTextArea cta)
182
        {
183
                setDaemon(true);
184
                InputStreamReader ir = new InputStreamReader(cta.getIn());
185
                kb = new BufferedReader(ir);
186

    
187
                BufferedOutputStream os = new BufferedOutputStream(p.getOutputStream());
188
                op = new PrintWriter((new OutputStreamWriter(os)), true);
189
                processRunning = true;
190
        }
191

    
192
        public void run()
193
        {
194
                try
195
                {
196
                        while (kb.ready() || processRunning)
197
                        {
198
                                if (kb.ready())
199
                                {
200
                                        op.println(kb.readLine());
201
                                }
202
                        }
203
                }
204
                catch (IOException e)
205
                {
206
                        System.err.println("Problem reading standard input.");
207
                        System.err.println(e);
208
                }
209
        }
210

    
211
        public void done()
212
        {
213
                processRunning = false;
214
        }
215
}
216

    
217
class StdOut extends Thread
218
{
219
        private InputStreamReader output;
220
        private boolean processRunning;
221
        private ConsoleTextArea cta;
222
        private StringBuffer data;
223
        
224
        public StdOut(Process p,ConsoleTextArea cta)
225
        {
226
                setDaemon(true);
227
                output = new InputStreamReader(p.getInputStream());
228
                this.cta = cta;
229
                processRunning = true;
230
                data = new StringBuffer();
231
        }
232

    
233
        public void run()
234
        {
235
                try
236
                {
237
                        /*
238
                         Loop as long as there is output from the process
239
                         to be displayed or as long as the process is still
240
                         running even if there is presently no output.
241
                        */
242
                        while (output.ready() || processRunning)
243
                        {
244

    
245
                                // If there is output get it and display it.
246
                                if (output.ready())
247
                                {
248
                                        char[] array = new char[255];
249
                                        int num = output.read(array);
250
                                        if (num != -1)
251
                                        {
252
                                                String s = new String(array,0,num);
253
                                                data.append(s);
254
                                                SwingUtilities.invokeAndWait( new ConsoleWrite(cta, s) );
255
                                        }
256
                                }
257
                        }
258
                }
259
                catch (Exception e)
260
                {
261
                        System.err.println("Problem writing to standard output.");
262
                        System.err.println(e);
263
                }
264
        }
265

    
266
        public void done()
267
        {
268
                processRunning = false;
269
        }
270
        
271
        public String getData()
272
        {
273
                return data.toString();
274
        }
275
}
276

    
277

    
278
class ConsoleWrite implements Runnable {
279
    private ConsoleTextArea textArea;
280
    private String str;
281

    
282
    public ConsoleWrite(ConsoleTextArea textArea, String str) {
283
        this.textArea = textArea;
284
        this.str = str;
285
    }
286

    
287
    public void run() {
288
        textArea.write(str);
289
    }
290
};
291

    
292
class ConsoleWriter extends java.io.OutputStream {
293

    
294
    private ConsoleTextArea textArea;
295
    private StringBuffer buffer;
296

    
297
    public ConsoleWriter(ConsoleTextArea textArea) {
298
        this.textArea = textArea;
299
        buffer = new StringBuffer();
300
    }
301

    
302
    public synchronized void write(int ch) {
303
        buffer.append((char)ch);
304
        if(ch == '\n') {
305
            flushBuffer();
306
        }
307
    }
308

    
309
    public synchronized void write (char[] data, int off, int len) {
310
        for(int i = off; i < len; i++) {
311
            buffer.append(data[i]);
312
            if(data[i] == '\n') {
313
                flushBuffer();
314
            }
315
        }
316
    }
317

    
318
    public synchronized void flush() {
319
        if (buffer.length() > 0) {
320
            flushBuffer();
321
        }
322
    }
323

    
324
    public void close () {
325
        flush();
326
    }
327

    
328
    private void flushBuffer() {
329
        String str = buffer.toString();
330
        buffer.setLength(0);
331
        SwingUtilities.invokeLater(new ConsoleWrite(textArea, str));
332
    }
333
};
334

    
335
class ConsoleTextArea extends JTextArea implements KeyListener,DocumentListener 
336
{
337
    private ConsoleWriter console1;
338
    private ConsoleWriter console2;
339
    private PrintStream out;
340
    private PrintStream err;
341
    private PrintWriter inPipe;
342
    private PipedInputStream in;
343
    private java.util.Vector history;
344
    private int historyIndex = -1;
345
    private int outputMark = 0;
346

    
347
    public void select(int start, int end) {
348
        requestFocus();
349
        super.select(start, end);
350
    }
351

    
352
    public ConsoleTextArea()
353
    {
354
        super();
355
        history = new java.util.Vector();
356
        console1 = new ConsoleWriter(this);
357
        console2 = new ConsoleWriter(this);
358
        out = new PrintStream(console1);
359
        err = new PrintStream(console2);
360
        PipedOutputStream outPipe = new PipedOutputStream();
361
        inPipe = new PrintWriter(outPipe);
362
        in = new PipedInputStream();
363
        try 
364
        {
365
            outPipe.connect(in);
366
        } catch(IOException exc) {
367
            exc.printStackTrace();
368
        }
369
        getDocument().addDocumentListener(this);
370
        addKeyListener(this);
371
        setLineWrap(true);
372
        setFont(new Font("Monospaced", 0, 12));
373
    }
374
    
375
    
376
    void returnPressed() {
377
        Document doc = getDocument();
378
        int len = doc.getLength();
379
        Segment segment = new Segment();
380
        try {
381
          synchronized(doc) {
382
            doc.getText(outputMark, len - outputMark, segment);
383
          }
384
        } catch(javax.swing.text.BadLocationException ignored) {
385
            ignored.printStackTrace();
386
        }
387
        if(segment.count > 0) {
388
            history.addElement(segment.toString());
389
        }
390
        historyIndex = history.size();
391
        inPipe.write(segment.array, segment.offset, segment.count);
392
        append("\n");
393
        synchronized(doc) {
394
          outputMark = doc.getLength();
395
        }
396
        inPipe.write("\n");
397
        inPipe.flush();
398
        console1.flush();
399
    }
400
    
401
    public void eval(String str) {
402
        inPipe.write(str);
403
        inPipe.write("\n");
404
        inPipe.flush();
405
        console1.flush();
406
    }
407
    
408
    public void keyPressed(KeyEvent e) {
409
        int code = e.getKeyCode();
410
        if(code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT) {
411
            if(outputMark == getCaretPosition()) {
412
                e.consume();
413
            }
414
        } else if(code == KeyEvent.VK_HOME) {
415
           int caretPos = getCaretPosition();
416
           if(caretPos == outputMark) {
417
               e.consume();
418
           } else if(caretPos > outputMark) {
419
               if(!e.isControlDown()) {
420
                   if(e.isShiftDown()) {
421
                       moveCaretPosition(outputMark);
422
                   } else {
423
                       setCaretPosition(outputMark);
424
                   }
425
                   e.consume();
426
               }
427
           }
428
        } else if(code == KeyEvent.VK_ENTER) {
429
            returnPressed();
430
            e.consume();
431
        } else if(code == KeyEvent.VK_UP) {
432
            historyIndex--;
433
            if(historyIndex >= 0) {
434
                if(historyIndex >= history.size()) {
435
                    historyIndex = history.size() -1;
436
                }
437
                if(historyIndex >= 0) {
438
                    String str = (String)history.elementAt(historyIndex);
439
                    int len = getDocument().getLength();
440
                    replaceRange(str, outputMark, len);
441
                    int caretPos = outputMark + str.length();
442
                    select(caretPos, caretPos);
443
                } else {
444
                    historyIndex++;
445
                }
446
            } else {
447
                historyIndex++;
448
            }
449
            e.consume();
450
        } else if(code == KeyEvent.VK_DOWN) {
451
            int caretPos = outputMark;
452
            if(history.size() > 0) {
453
                historyIndex++;
454
                if(historyIndex < 0) {historyIndex = 0;}
455
                int len = getDocument().getLength();
456
                if(historyIndex < history.size()) {
457
                    String str = (String)history.elementAt(historyIndex);
458
                    replaceRange(str, outputMark, len);
459
                    caretPos = outputMark + str.length();
460
                } else {
461
                    historyIndex = history.size();
462
                    replaceRange("", outputMark, len);
463
                }
464
            }
465
            select(caretPos, caretPos);
466
            e.consume();
467
        }
468
    }
469
 
470
    public void keyTyped(KeyEvent e) {
471
        int keyChar = e.getKeyChar();
472
        if(keyChar == 0x8 /* KeyEvent.VK_BACK_SPACE */) {
473
            if(outputMark == getCaretPosition()) {
474
                e.consume();
475
            }
476
        } else if(getCaretPosition() < outputMark) {
477
            setCaretPosition(outputMark);
478
        }
479
    }
480
    
481
    public void keyReleased(KeyEvent e) {
482
    }
483

    
484
    public synchronized void write(String str) {
485
        insert(str, outputMark);
486
        int len = str.length();
487
        outputMark += len;
488
        select(outputMark, outputMark);
489
    }
490
    
491
    public synchronized void insertUpdate(DocumentEvent e) {
492
        int len = e.getLength();
493
        int off = e.getOffset();
494
        if(outputMark > off) {
495
            outputMark += len;
496
        }
497
    }
498
    
499
    public synchronized void removeUpdate(DocumentEvent e) {
500
        int len = e.getLength();
501
        int off = e.getOffset();
502
        if(outputMark > off) {
503
            if(outputMark >= off + len) {
504
                outputMark -= len;
505
            } else {
506
                outputMark = off;
507
            }
508
        }
509
    }
510

    
511
    public void postUpdateUI() {
512
        // this attempts to cleanup the damage done by updateComponentTreeUI
513
        requestFocus();
514
        setCaret(getCaret());
515
        synchronized(this) {
516
          select(outputMark, outputMark);
517
        }
518
    }
519
    
520
    public void changedUpdate(DocumentEvent e) {
521
    }
522
    
523
    
524
    public InputStream getIn() {
525
        return in;
526
    }
527
    
528
    public PrintStream getOut() {
529
        return out;
530
    }
531
    
532
    public PrintStream getErr() {
533
        return err;
534
    }
535
    
536
};