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