Back to index

lightning-sunbird  0.9+nobinonly
MRJConsole.java
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the MRJ Carbon OJI Plugin.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corp.
00018  * Portions created by the Initial Developer are Copyright (C) 2001
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Patrick C. Beard <beard@netscape.com>
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /*
00039        MJRConsole.java
00040        
00041        Simple Java console for MRJ.
00042        
00043        All methods are called asynchronously, using JMExecJNIStaticMethodInContext(). After posting
00044        each call this way, MRJConsole.finish() is called, which waits on MRJConsole.class. Each
00045        public method calls MRJConsole.done(), which notifies. This should probably be changed
00046        to a pure Java approach.
00047        
00048        by Patrick C. Beard.
00049  */
00050 
00051 package netscape.oji;
00052 
00053 import java.io.*;
00054 import java.awt.*;
00055 import java.awt.event.*;
00056 
00057 class ConsoleWindow extends Frame {
00058        TextArea text;
00059 
00060        ConsoleWindow(String title) {
00061               super("Java Console");
00062               
00063               addWindowListener(
00064                      new WindowAdapter() {
00065                             public void windowClosing(WindowEvent e) {
00066                                    hide();
00067                             }
00068                      });
00069               
00070               add(text = new TextArea());
00071               setSize(300, 200);
00072 
00073               ActionListener dumpThreadsListener =
00074                      new ActionListener() {
00075                             public void actionPerformed(ActionEvent e) {
00076                                    dumpThreads();
00077                             }
00078                      };
00079 
00080               // Create a console menu.
00081               MenuBar menuBar = new MenuBar();
00082               Menu consoleMenu = new Menu("Console");
00083               consoleMenu.add(newItem("Dump Threads", dumpThreadsListener));
00084               
00085               menuBar.add(consoleMenu);
00086               setMenuBar(menuBar);
00087        }
00088 
00089        private MenuItem newItem(String title, ActionListener listener) {
00090               MenuItem item = new MenuItem(title);
00091               item.addActionListener(listener);
00092               return item;
00093        }
00094        
00095        public void dumpThreads() {
00096               System.out.println("Dumping threads...");
00097        }
00098 }
00099 
00100 public class MRJConsole {
00101        // Save primordial System streams.
00102        private static InputStream in;
00103        private static PrintStream out;
00104        private static PrintStream err;
00105        private static ConsoleWindow window;
00106 
00107        native static int readLine(byte[] buffer, int offset, int length);
00108        native static void writeLine(byte[] buffer, int offset, int length);
00109 
00110        private static class Input extends InputStream {
00111               byte[] buffer = new byte[1024];
00112               int position = 0;
00113               int count = 0;
00114               
00115               private void fillBuffer() throws EOFException {
00116                      // int length = readLine(buffer, 0, buffer.length);
00117                      int length = 1024;
00118                      if (length == -1)
00119                             throw new EOFException();
00120                      count = length;
00121                      position = 0;
00122               }
00123               
00124            public int read() throws IOException {
00125               synchronized(this) {
00126                      if (position >= count)
00127                             fillBuffer();
00128                      return buffer[position++];
00129               }
00130            }
00131 
00132            public int read(byte[] b, int offset, int length) throws IOException {
00133                      synchronized(this) {
00134                             // only fill the buffer at the outset, always returns at most one line of data.
00135                      if (position >= count)
00136                             fillBuffer();
00137                      int initialOffset = offset;
00138                      while (offset < length && position < count) {
00139                             b[offset++] = buffer[position++];
00140                      }
00141                      return (offset - initialOffset);
00142                   }
00143            }
00144        }
00145        
00146        private static class Output extends OutputStream implements Runnable {
00147               StringBuffer buffer = new StringBuffer();
00148               
00149               public Output() {
00150                      Thread flusher = new Thread(this, getClass().getName() + "-Flusher");
00151                      flusher.setDaemon(true);
00152                      flusher.start();
00153               }
00154        
00155               public synchronized void write(int b) throws IOException {
00156                      this.buffer.append((char)b);
00157                      notify();
00158            }
00159 
00160               public synchronized void write(byte[] buffer, int offset, int count) throws IOException {
00161                      this.buffer.append(new String(buffer, 0, offset, count));
00162                      notify();
00163               }
00164 
00165            public synchronized void flush() throws IOException {
00166               String value = this.buffer.toString();
00167               window.text.append(value);
00168               this.buffer.setLength(0);
00169        }
00170               
00175        public synchronized void run() {
00176                      for (;;) {
00177                             try {
00178                             wait();
00179                             flush();
00180                      } catch (InterruptedException ie) {
00181                      } catch (IOException ioe) {
00182                      }
00183               }
00184        }
00185        }
00186        
00187        private static class Error extends Output {}
00188 
00189        public static void init() {
00190               in = System.in;
00191               out = System.out;
00192               err = System.err;
00193 
00194               window = new ConsoleWindow("Java Console");
00195 
00196               System.setIn(new Input());
00197               System.setOut(new PrintStream(new Output()));
00198               System.setErr(new PrintStream(new Error()));
00199 
00200               done();
00201        }
00202        
00203        public static void dispose() {
00204               System.setIn(in);
00205               System.setOut(out);
00206               System.setErr(err);
00207               window.dispose();
00208               window = null;
00209               done();
00210        }
00211        
00212        public static void show() {
00213               window.show();
00214               done();
00215        }
00216        
00217        public static void hide() {
00218               window.hide();
00219               done();
00220        }
00221        
00222        public static void visible(boolean[] result) {
00223               result[0] = window.isVisible();
00224               done();
00225        }
00226        
00227        public static void print(String text) {
00228               System.out.print(text);
00229               done();
00230        }
00231        
00232        public static synchronized void finish() {
00233               try {
00234                      MRJConsole.class.wait();
00235               } catch (InterruptedException ie) {
00236               }
00237        }
00238        
00239        private static synchronized void done() {
00240               MRJConsole.class.notify();
00241        }
00242 }