/* * Copyright (c) 1996-1999 Bill Venners. All Rights Reserved. * * This Java source file is part of the Interactive Illustrations Web * Site, which is delivered in the applets directory of the CD-ROM * that accompanies the book "Inside the Java 2 Virtual Machine" by Bill * Venners, published by McGraw-Hill, 1999, ISBN: 0-07-135093-4. This * source file is provided for evaluation purposes only, but you can * redistribute it under certain conditions, described in the full * copyright notice below. * * Full Copyright Notice: * * All the web pages and Java applets delivered in the applets * directory of the CD-ROM, consisting of ".html," ".gif," ".class," * and ".java" files, are copyrighted (c) 1996-1999 by Bill * Venners, and all rights are reserved. This material may be copied * and placed on any commercial or non-commercial web server on any * network (including the internet) provided that the following * guidelines are followed: * * a. All the web pages and Java Applets (".html," ".gif," ".class," * and ".java" files), including the source code, that are delivered * in the applets directory of the CD-ROM that * accompanies the book must be published together on the same web * site. * * b. All the web pages and Java Applets (".html," ".gif," ".class," * and ".java" files) must be published "as is" and may not be altered * in any way. * * c. All use and access to this web site must be free, and no fees * can be charged to view these materials, unless express written * permission is obtained from Bill Venners. * * d. The web pages and Java Applets may not be distributed on any * media, other than a web server on a network, and may not accompany * any book or publication. * * BILL VENNERS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR PARTICULAR PURPOSE, OR NON-INFRINGEMENT. BILL VENNERS * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY A LICENSEE AS A * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. */ import java.awt.*; import java.applet.*; import java.io.InputStream; import java.io.DataInputStream; import java.io.BufferedInputStream; import java.io.IOException; import java.io.EOFException; import java.net.URL; import java.net.URLConnection; import java.net.MalformedURLException; /** * This applet describes the contents of a particular a Java class * file as it is loaded, one chunk of bytes at a time, by the JVM. * * @author Bill Venners */ public class GettingLoaded extends Applet implements Runnable { private URL theClassFileURL; private URL theActTextURL; private Thread runner; private TextArea ta = new TextArea(); private StepNode firstNode; private StepNode lastNode; private StepNode currentNode; private boolean ready = false; private boolean jvmFinishedGobbling = false; private int currentGobblePosition = 0; private JVMPacman jvmPacman; private String titleString = "Getting Loaded\n\n"; private boolean urlExceptionWasThrown = false; private String cantGoFurtherString = "Unfortunately this means the applet cannot go any further.\n"; private String ioErrorMsg = "An IO Error occured while trying to read a file from the server.\n"; private String securityErrorMsg = "An security exception occured while trying to read a file from the server.\n"; private String urlErrorMsg = "This HTML file contains a malformed URL of a file required by this applet.\n"; public void init() { super.init(); ta.setEditable(false); setBackground(Color.blue); String url = getParameter("classURL"); try { this.theClassFileURL = new URL(getDocumentBase(), url); } catch (MalformedURLException e) { urlExceptionWasThrown = true; URL docBase = getDocumentBase(); ta.setText(titleString + "Bad URL: " + docBase.toString() + url + "\n\n" + urlErrorMsg + cantGoFurtherString); } url = getParameter("textURL"); try { this.theActTextURL = new URL(getDocumentBase(), url); } catch (MalformedURLException e) { urlExceptionWasThrown = true; URL docBase = getDocumentBase(); ta.setText(titleString + "Bad URL: " + docBase.toString() + url + "\n\n" + urlErrorMsg + cantGoFurtherString); } ControlPanel controlPanel = new ControlPanel(); jvmPacman = controlPanel.getJVMPacman(); setLayout(new BorderLayout(5, 5)); ta.setBackground(Color.white); add("North", new ColoredLabel("GETTING LOADED", Label.CENTER, Color.cyan)); add("South", controlPanel); add("Center", ta); } public boolean handleEvent(Event event) { return super.handleEvent(event); } public boolean action(Event evt, Object arg) { if (evt.target instanceof Button) { String bname = (String) arg; if (bname.equals("Reset")) { if (ready) { if (!currentNode.first()) { currentNode = firstNode; currentGobblePosition = 0; jvmPacman.setGobblePosition(0, currentNode.getByteCount()); ta.setText(currentNode.getString()); } } } else if (bname.equals("Step")) { if (ready) { if (!currentNode.last()) { currentGobblePosition += currentNode.getByteCount(); currentNode = currentNode.getNext(); jvmPacman.gobbleToPosition(currentGobblePosition, currentNode.getByteCount()); ta.setText(currentNode.getString()); } else { if (!jvmFinishedGobbling) { currentGobblePosition += currentNode.getByteCount(); jvmPacman.gobbleToPosition(currentGobblePosition, 0); jvmFinishedGobbling = true; ta.setText("(The End)"); } } } } else if (bname.equals("Back")) { if (ready) { if (!currentNode.first()) { if (jvmFinishedGobbling) { jvmFinishedGobbling = false; currentGobblePosition -= currentNode.getByteCount(); } else { currentNode = currentNode.getPrev(); currentGobblePosition -= currentNode.getByteCount(); } jvmPacman.setGobblePosition(currentGobblePosition, currentNode.getByteCount()); ta.setText(currentNode.getString()); } } } } return true; } public Insets insets() { return new Insets(5, 5, 5, 5); } public void start() { if (runner == null && !ready && !urlExceptionWasThrown) { runner = new Thread (this); runner.start(); } } public void stop() { if (runner != null) { runner.stop(); runner = null; } } public void run() { InputStream conn = null; DataInputStream data = null; String line; StringBuffer buf = new StringBuffer(); ta.setText(titleString + "Loading First Of Two Files...\n"); try { conn = this.theClassFileURL.openStream(); data = new DataInputStream(new BufferedInputStream(conn)); try { while (true) { int unsignedByte = data.readUnsignedByte(); HexString hexStr = new HexString(unsignedByte, 2); buf.append(hexStr.getString()); } } catch (EOFException e) { jvmPacman.setText(buf.toString()); } try { ta.setText(titleString + "Loading Second Of Two Files...\n"); conn = this.theActTextURL.openStream(); data = new DataInputStream(new BufferedInputStream(conn)); buf.setLength(0); while ((line = data.readLine()) != null) { if (line.length() > 0 && line.charAt(0) == '*') { int starCount = line.length(); StepNode nextNode = new StepNode(buf.toString(), starCount); if (firstNode == null) { firstNode = nextNode; lastNode = nextNode; } else { lastNode.setNext(nextNode); nextNode.setPrev(lastNode); lastNode = nextNode; } buf.setLength(0); } else { buf.append(line + "\n"); } } ready = true; currentNode = firstNode; jvmPacman.setGobblePosition(0, firstNode.getByteCount()); ta.setText(currentNode.getString()); } catch (IOException e) { ta.setText(titleString + "IO Error: " + e.getMessage() + "\n\n" + ioErrorMsg + cantGoFurtherString); } catch (SecurityException e) { ta.setText(titleString + "Security Exception: " + e.getMessage() + "\n\n" + securityErrorMsg + cantGoFurtherString); } } catch (IOException e) { ta.setText(titleString + "IO Error: " + e.getMessage() + "\n\n" + ioErrorMsg + cantGoFurtherString); } catch (SecurityException e) { ta.setText(titleString + "Security Exception: " + e.getMessage() + "\n\n" + securityErrorMsg + cantGoFurtherString); } finally { runner = null; } } }