/*
 * Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.applet;

import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.print.*;
import javax.print.attribute.*;
import java.applet.*;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.SocketPermission;
import sun.misc.Ref;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import sun.awt.SunToolkit;
import sun.awt.AppContext;
import java.lang.ref.WeakReference;

A frame to show the applet tag in.
/** * A frame to show the applet tag in. */
class TextFrame extends Frame {
Create the tag frame.
/** * Create the tag frame. */
TextFrame(int x, int y, String title, String text) { setTitle(title); TextArea txt = new TextArea(20, 60); txt.setText(text); txt.setEditable(false); add("Center", txt); Panel p = new Panel(); add("South", p); Button b = new Button(amh.getMessage("button.dismiss", "Dismiss")); p.add(b); class ActionEventListener implements ActionListener { public void actionPerformed(ActionEvent evt) { dispose(); } } b.addActionListener(new ActionEventListener()); pack(); move(x, y); setVisible(true); WindowListener windowEventListener = new WindowAdapter() { public void windowClosing(WindowEvent evt) { dispose(); } }; addWindowListener(windowEventListener); } private static AppletMessageHandler amh = new AppletMessageHandler("textframe"); }
Lets us construct one using unix-style one shot behaviors
/** * Lets us construct one using unix-style one shot behaviors */
class StdAppletViewerFactory implements AppletViewerFactory { public AppletViewer createAppletViewer(int x, int y, URL doc, Hashtable atts) { return new AppletViewer(x, y, doc, atts, System.out, this); } public MenuBar getBaseMenuBar() { return new MenuBar(); } public boolean isStandalone() { return true; } }
The applet viewer makes it possible to run a Java applet without using a browser. For details on the syntax that appletviewer supports, see AppletViewer Tags. (The document named appletviewertags.html in the JDK's docs/tooldocs directory, once the JDK docs have been installed.)
/** * The applet viewer makes it possible to run a Java applet without using a browser. * For details on the syntax that <B>appletviewer</B> supports, see * <a href="../../../docs/tooldocs/appletviewertags.html">AppletViewer Tags</a>. * (The document named appletviewertags.html in the JDK's docs/tooldocs directory, * once the JDK docs have been installed.) */
public class AppletViewer extends Frame implements AppletContext, Printable {
Some constants...
/** * Some constants... */
private static String defaultSaveFile = "Applet.ser";
The panel in which the applet is being displayed.
/** * The panel in which the applet is being displayed. */
AppletViewerPanel panel;
The status line.
/** * The status line. */
Label label;
output status messages to this stream
/** * output status messages to this stream */
PrintStream statusMsgStream;
For cloning
/** * For cloning */
AppletViewerFactory factory; private final class UserActionListener implements ActionListener { public void actionPerformed(ActionEvent evt) { processUserAction(evt); } }
Create the applet viewer
/** * Create the applet viewer */
public AppletViewer(int x, int y, URL doc, Hashtable atts, PrintStream statusMsgStream, AppletViewerFactory factory) { this.factory = factory; this.statusMsgStream = statusMsgStream; setTitle(amh.getMessage("tool.title", atts.get("code"))); MenuBar mb = factory.getBaseMenuBar(); Menu m = new Menu(amh.getMessage("menu.applet")); addMenuItem(m, "menuitem.restart"); addMenuItem(m, "menuitem.reload"); addMenuItem(m, "menuitem.stop"); addMenuItem(m, "menuitem.save"); addMenuItem(m, "menuitem.start"); addMenuItem(m, "menuitem.clone"); m.add(new MenuItem("-")); addMenuItem(m, "menuitem.tag"); addMenuItem(m, "menuitem.info"); addMenuItem(m, "menuitem.edit").disable(); addMenuItem(m, "menuitem.encoding"); m.add(new MenuItem("-")); addMenuItem(m, "menuitem.print"); m.add(new MenuItem("-")); addMenuItem(m, "menuitem.props"); m.add(new MenuItem("-")); addMenuItem(m, "menuitem.close"); if (factory.isStandalone()) { addMenuItem(m, "menuitem.quit"); } mb.add(m); setMenuBar(mb); add("Center", panel = new AppletViewerPanel(doc, atts)); add("South", label = new Label(amh.getMessage("label.hello"))); panel.init(); appletPanels.addElement(panel); pack(); move(x, y); setVisible(true); WindowListener windowEventListener = new WindowAdapter() { public void windowClosing(WindowEvent evt) { appletClose(); } public void windowIconified(WindowEvent evt) { appletStop(); } public void windowDeiconified(WindowEvent evt) { appletStart(); } }; class AppletEventListener implements AppletListener { final Frame frame; public AppletEventListener(Frame frame) { this.frame = frame; } public void appletStateChanged(AppletEvent evt) { AppletPanel src = (AppletPanel)evt.getSource(); switch (evt.getID()) { case AppletPanel.APPLET_RESIZE: { if(src != null) { resize(preferredSize()); validate(); } break; } case AppletPanel.APPLET_LOADING_COMPLETED: { Applet a = src.getApplet(); // sun.applet.AppletPanel // Fixed #4754451: Applet can have methods running on main // thread event queue. // // The cause of this bug is that the frame of the applet // is created in main thread group. Thus, when certain // AWT/Swing events are generated, the events will be // dispatched through the wrong event dispatch thread. // // To fix this, we rearrange the AppContext with the frame, // so the proper event queue will be looked up. // // Swing also maintains a Frame list for the AppContext, // so we will have to rearrange it as well. // if (a != null) AppletPanel.changeFrameAppContext(frame, SunToolkit.targetToAppContext(a)); else AppletPanel.changeFrameAppContext(frame, AppContext.getAppContext()); break; } } } }; addWindowListener(windowEventListener); panel.addAppletListener(new AppletEventListener(this)); // Start the applet showStatus(amh.getMessage("status.start")); initEventQueue(); } // XXX 99/9/10 probably should be "private" public MenuItem addMenuItem(Menu m, String s) { MenuItem mItem = new MenuItem(amh.getMessage(s)); mItem.addActionListener(new UserActionListener()); return m.add(mItem); }
Send the initial set of events to the appletviewer event queue. On start-up the current behaviour is to load the applet and call Applet.init() and Applet.start().
/** * Send the initial set of events to the appletviewer event queue. * On start-up the current behaviour is to load the applet and call * Applet.init() and Applet.start(). */
private void initEventQueue() { // appletviewer.send.event is an undocumented and unsupported system // property which is used exclusively for testing purposes. String eventList = System.getProperty("appletviewer.send.event"); if (eventList == null) { // Add the standard events onto the event queue. panel.sendEvent(AppletPanel.APPLET_LOAD); panel.sendEvent(AppletPanel.APPLET_INIT); panel.sendEvent(AppletPanel.APPLET_START); } else { // We're testing AppletViewer. Force the specified set of events // onto the event queue, wait for the events to be processed, and // exit. // The list of events that will be executed is provided as a // ","-separated list. No error-checking will be done on the list. String [] events = splitSeparator(",", eventList); for (int i = 0; i < events.length; i++) { System.out.println("Adding event to queue: " + events[i]); if (events[i].equals("dispose")) panel.sendEvent(AppletPanel.APPLET_DISPOSE); else if (events[i].equals("load")) panel.sendEvent(AppletPanel.APPLET_LOAD); else if (events[i].equals("init")) panel.sendEvent(AppletPanel.APPLET_INIT); else if (events[i].equals("start")) panel.sendEvent(AppletPanel.APPLET_START); else if (events[i].equals("stop")) panel.sendEvent(AppletPanel.APPLET_STOP); else if (events[i].equals("destroy")) panel.sendEvent(AppletPanel.APPLET_DESTROY); else if (events[i].equals("quit")) panel.sendEvent(AppletPanel.APPLET_QUIT); else if (events[i].equals("error")) panel.sendEvent(AppletPanel.APPLET_ERROR); else // non-fatal error if we get an unrecognized event System.out.println("Unrecognized event name: " + events[i]); } while (!panel.emptyEventQueue()) ; appletSystemExit(); } }
Split a string based on the presence of a specified separator. Returns an array of arbitrary length. The end of each element in the array is indicated by the separator of the end of the string. If there is a separator immediately before the end of the string, the final element will be empty. None of the strings will contain the separator. Useful when separating strings such as "foo/bar/bas" using separator "/".
Params:
  • sep – The separator.
  • s – The string to split.
Returns: An array of strings. Each string in the array is determined by the location of the provided sep in the original string, s. Whitespace not stripped.
/** * Split a string based on the presence of a specified separator. Returns * an array of arbitrary length. The end of each element in the array is * indicated by the separator of the end of the string. If there is a * separator immediately before the end of the string, the final element * will be empty. None of the strings will contain the separator. Useful * when separating strings such as "foo/bar/bas" using separator "/". * * @param sep The separator. * @param s The string to split. * @return An array of strings. Each string in the array is determined * by the location of the provided sep in the original string, * s. Whitespace not stripped. */
private String [] splitSeparator(String sep, String s) { Vector v = new Vector(); int tokenStart = 0; int tokenEnd = 0; while ((tokenEnd = s.indexOf(sep, tokenStart)) != -1) { v.addElement(s.substring(tokenStart, tokenEnd)); tokenStart = tokenEnd+1; } // Add the final element. v.addElement(s.substring(tokenStart)); String [] retVal = new String[v.size()]; v.copyInto(retVal); return retVal; } /* * Methods for java.applet.AppletContext */ private static Map audioClips = new HashMap();
Get an audio clip.
/** * Get an audio clip. */
public AudioClip getAudioClip(URL url) { checkConnect(url); synchronized (audioClips) { AudioClip clip = (AudioClip)audioClips.get(url); if (clip == null) { audioClips.put(url, clip = new AppletAudioClip(url)); } return clip; } } private static Map imageRefs = new HashMap();
Get an image.
/** * Get an image. */
public Image getImage(URL url) { return getCachedImage(url); } static Image getCachedImage(URL url) { // System.getSecurityManager().checkConnection(url.getHost(), url.getPort()); return (Image)getCachedImageRef(url).get(); }
Get an image ref.
/** * Get an image ref. */
static Ref getCachedImageRef(URL url) { synchronized (imageRefs) { AppletImageRef ref = (AppletImageRef)imageRefs.get(url); if (ref == null) { ref = new AppletImageRef(url); imageRefs.put(url, ref); } return ref; } }
Flush the image cache.
/** * Flush the image cache. */
static void flushImageCache() { imageRefs.clear(); } static Vector appletPanels = new Vector();
Get an applet by name.
/** * Get an applet by name. */
public Applet getApplet(String name) { AppletSecurity security = (AppletSecurity)System.getSecurityManager(); name = name.toLowerCase(); SocketPermission panelSp = new SocketPermission(panel.getCodeBase().getHost(), "connect"); for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) { AppletPanel p = (AppletPanel)e.nextElement(); String param = p.getParameter("name"); if (param != null) { param = param.toLowerCase(); } if (name.equals(param) && p.getDocumentBase().equals(panel.getDocumentBase())) { SocketPermission sp = new SocketPermission(p.getCodeBase().getHost(), "connect"); if (panelSp.implies(sp)) { return p.applet; } } } return null; }
Return an enumeration of all the accessible applets on this page.
/** * Return an enumeration of all the accessible * applets on this page. */
public Enumeration getApplets() { AppletSecurity security = (AppletSecurity)System.getSecurityManager(); Vector v = new Vector(); SocketPermission panelSp = new SocketPermission(panel.getCodeBase().getHost(), "connect"); for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) { AppletPanel p = (AppletPanel)e.nextElement(); if (p.getDocumentBase().equals(panel.getDocumentBase())) { SocketPermission sp = new SocketPermission(p.getCodeBase().getHost(), "connect"); if (panelSp.implies(sp)) { v.addElement(p.applet); } } } return v.elements(); }
Ignore.
/** * Ignore. */
public void showDocument(URL url) { }
Ignore.
/** * Ignore. */
public void showDocument(URL url, String target) { }
Show status.
/** * Show status. */
public void showStatus(String status) { label.setText(status); } public void setStream(String key, InputStream stream)throws IOException{ // We do nothing. } public InputStream getStream(String key){ // We do nothing. return null; } public Iterator getStreamKeys(){ // We do nothing. return null; }
System parameters.
/** * System parameters. */
static Hashtable systemParam = new Hashtable(); static { systemParam.put("codebase", "codebase"); systemParam.put("code", "code"); systemParam.put("alt", "alt"); systemParam.put("width", "width"); systemParam.put("height", "height"); systemParam.put("align", "align"); systemParam.put("vspace", "vspace"); systemParam.put("hspace", "hspace"); }
Print the HTML tag.
/** * Print the HTML tag. */
public static void printTag(PrintStream out, Hashtable atts) { out.print("<applet"); String v = (String)atts.get("codebase"); if (v != null) { out.print(" codebase=\"" + v + "\""); } v = (String)atts.get("code"); if (v == null) { v = "applet.class"; } out.print(" code=\"" + v + "\""); v = (String)atts.get("width"); if (v == null) { v = "150"; } out.print(" width=" + v); v = (String)atts.get("height"); if (v == null) { v = "100"; } out.print(" height=" + v); v = (String)atts.get("name"); if (v != null) { out.print(" name=\"" + v + "\""); } out.println(">"); // A very slow sorting algorithm int len = atts.size(); String params[] = new String[len]; len = 0; for (Enumeration e = atts.keys() ; e.hasMoreElements() ;) { String param = (String)e.nextElement(); int i = 0; for (; i < len ; i++) { if (params[i].compareTo(param) >= 0) { break; } } System.arraycopy(params, i, params, i + 1, len - i); params[i] = param; len++; } for (int i = 0 ; i < len ; i++) { String param = params[i]; if (systemParam.get(param) == null) { out.println("<param name=" + param + " value=\"" + atts.get(param) + "\">"); } } out.println("</applet>"); }
Make sure the atrributes are uptodate.
/** * Make sure the atrributes are uptodate. */
public void updateAtts() { Dimension d = panel.size(); Insets in = panel.insets(); panel.atts.put("width", new Integer(d.width - (in.left + in.right)).toString()); panel.atts.put("height", new Integer(d.height - (in.top + in.bottom)).toString()); }
Restart the applet.
/** * Restart the applet. */
void appletRestart() { panel.sendEvent(AppletPanel.APPLET_STOP); panel.sendEvent(AppletPanel.APPLET_DESTROY); panel.sendEvent(AppletPanel.APPLET_INIT); panel.sendEvent(AppletPanel.APPLET_START); }
Reload the applet.
/** * Reload the applet. */
void appletReload() { panel.sendEvent(AppletPanel.APPLET_STOP); panel.sendEvent(AppletPanel.APPLET_DESTROY); panel.sendEvent(AppletPanel.APPLET_DISPOSE); /** * Fixed #4501142: Classlaoder sharing policy doesn't * take "archive" into account. This will be overridden * by Java Plug-in. [stanleyh] */ AppletPanel.flushClassLoader(panel.getClassLoaderCacheKey()); /* * Make sure we don't have two threads running through the event queue * at the same time. */ try { panel.joinAppletThread(); panel.release(); } catch (InterruptedException e) { return; // abort the reload } panel.createAppletThread(); panel.sendEvent(AppletPanel.APPLET_LOAD); panel.sendEvent(AppletPanel.APPLET_INIT); panel.sendEvent(AppletPanel.APPLET_START); }
Save the applet to a well known file (for now) as a serialized object
/** * Save the applet to a well known file (for now) as a serialized object */
void appletSave() { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { // XXX: this privileged block should be made smaller // by initializing a private static variable with "user.dir" // Applet needs to be stopped for serialization to succeed. // Since panel.sendEvent only queues the event, there is a // chance that the event will not be processed before // serialization begins. However, by sending the event before // FileDialog is created, enough time is given such that this // situation is unlikely to ever occur. panel.sendEvent(AppletPanel.APPLET_STOP); FileDialog fd = new FileDialog(AppletViewer.this, amh.getMessage("appletsave.filedialogtitle"), FileDialog.SAVE); // needed for a bug under Solaris... fd.setDirectory(System.getProperty("user.dir")); fd.setFile(defaultSaveFile); fd.show(); String fname = fd.getFile(); if (fname == null) { // Restart applet if Save is cancelled. panel.sendEvent(AppletPanel.APPLET_START); return null; // cancelled } String dname = fd.getDirectory(); File file = new File(dname, fname); try { BufferedOutputStream s = new BufferedOutputStream(new FileOutputStream(file)); ObjectOutputStream os = new ObjectOutputStream(s); showStatus(amh.getMessage("appletsave.err1", panel.applet.toString(), file.toString())); os.writeObject(panel.applet); } catch (IOException ex) { System.err.println(amh.getMessage("appletsave.err2", ex)); } finally { panel.sendEvent(AppletPanel.APPLET_START); } return null; } }); }
Clone the viewer and the applet.
/** * Clone the viewer and the applet. */
void appletClone() { Point p = location(); updateAtts(); factory.createAppletViewer(p.x + XDELTA, p.y + YDELTA, panel.documentURL, (Hashtable)panel.atts.clone()); }
Show the applet tag.
/** * Show the applet tag. */
void appletTag() { ByteArrayOutputStream out = new ByteArrayOutputStream(); updateAtts(); printTag(new PrintStream(out), panel.atts); showStatus(amh.getMessage("applettag")); Point p = location(); new TextFrame(p.x + XDELTA, p.y + YDELTA, amh.getMessage("applettag.textframe"), out.toString()); }
Show the applet info.
/** * Show the applet info. */
void appletInfo() { String str = panel.applet.getAppletInfo(); if (str == null) { str = amh.getMessage("appletinfo.applet"); } str += "\n\n"; String atts[][] = panel.applet.getParameterInfo(); if (atts != null) { for (int i = 0 ; i < atts.length ; i++) { str += atts[i][0] + " -- " + atts[i][1] + " -- " + atts[i][2] + "\n"; } } else { str += amh.getMessage("appletinfo.param"); } Point p = location(); new TextFrame(p.x + XDELTA, p.y + YDELTA, amh.getMessage("appletinfo.textframe"), str); }
Show character encoding type
/** * Show character encoding type */
void appletCharacterEncoding() { showStatus(amh.getMessage("appletencoding", encoding)); }
Edit the applet.
/** * Edit the applet. */
void appletEdit() { }
Print the applet.
/** * Print the applet. */
void appletPrint() { PrinterJob pj = PrinterJob.getPrinterJob(); if (pj != null) { PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); if (pj.printDialog(aset)) { pj.setPrintable(this); try { pj.print(aset); statusMsgStream.println(amh.getMessage("appletprint.finish")); } catch (PrinterException e) { statusMsgStream.println(amh.getMessage("appletprint.fail")); } } else { statusMsgStream.println(amh.getMessage("appletprint.cancel")); } } else { statusMsgStream.println(amh.getMessage("appletprint.fail")); } } public int print(Graphics graphics, PageFormat pf, int pageIndex) { if (pageIndex > 0) { return Printable.NO_SUCH_PAGE; } else { Graphics2D g2d = (Graphics2D)graphics; g2d.translate(pf.getImageableX(), pf.getImageableY()); panel.applet.printAll(graphics); return Printable.PAGE_EXISTS; } }
Properties.
/** * Properties. */
static AppletProps props; public static synchronized void networkProperties() { if (props == null) { props = new AppletProps(); } props.addNotify(); props.setVisible(true); }
Start the applet.
/** * Start the applet. */
void appletStart() { panel.sendEvent(AppletPanel.APPLET_START); }
Stop the applet.
/** * Stop the applet. */
void appletStop() { panel.sendEvent(AppletPanel.APPLET_STOP); }
Shutdown a viewer. Stop, Destroy, Dispose and Quit a viewer
/** * Shutdown a viewer. * Stop, Destroy, Dispose and Quit a viewer */
private void appletShutdown(AppletPanel p) { p.sendEvent(AppletPanel.APPLET_STOP); p.sendEvent(AppletPanel.APPLET_DESTROY); p.sendEvent(AppletPanel.APPLET_DISPOSE); p.sendEvent(AppletPanel.APPLET_QUIT); }
Close this viewer. Stop, Destroy, Dispose and Quit an AppletView, then reclaim resources and exit the program if this is the last applet.
/** * Close this viewer. * Stop, Destroy, Dispose and Quit an AppletView, then * reclaim resources and exit the program if this is * the last applet. */
void appletClose() { // The caller thread is event dispatch thread, so // spawn a new thread to avoid blocking the event queue // when calling appletShutdown. // final AppletPanel p = panel; new Thread(new Runnable() { public void run() { appletShutdown(p); appletPanels.removeElement(p); dispose(); if (countApplets() == 0) { appletSystemExit(); } } }).start(); }
Exit the program. Exit from the program (if not stand alone) - do no clean-up
/** * Exit the program. * Exit from the program (if not stand alone) - do no clean-up */
private void appletSystemExit() { if (factory.isStandalone()) System.exit(0); }
Quit all viewers. Shutdown all viewers properly then exit from the program (if not stand alone)
/** * Quit all viewers. * Shutdown all viewers properly then * exit from the program (if not stand alone) */
protected void appletQuit() { // The caller thread is event dispatch thread, so // spawn a new thread to avoid blocking the event queue // when calling appletShutdown. // new Thread(new Runnable() { public void run() { for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) { AppletPanel p = (AppletPanel)e.nextElement(); appletShutdown(p); } appletSystemExit(); } }).start(); }
Handle events.
/** * Handle events. */
public void processUserAction(ActionEvent evt) { String label = ((MenuItem)evt.getSource()).getLabel(); if (amh.getMessage("menuitem.restart").equals(label)) { appletRestart(); return; } if (amh.getMessage("menuitem.reload").equals(label)) { appletReload(); return; } if (amh.getMessage("menuitem.clone").equals(label)) { appletClone(); return; } if (amh.getMessage("menuitem.stop").equals(label)) { appletStop(); return; } if (amh.getMessage("menuitem.save").equals(label)) { appletSave(); return; } if (amh.getMessage("menuitem.start").equals(label)) { appletStart(); return; } if (amh.getMessage("menuitem.tag").equals(label)) { appletTag(); return; } if (amh.getMessage("menuitem.info").equals(label)) { appletInfo(); return; } if (amh.getMessage("menuitem.encoding").equals(label)) { appletCharacterEncoding(); return; } if (amh.getMessage("menuitem.edit").equals(label)) { appletEdit(); return; } if (amh.getMessage("menuitem.print").equals(label)) { appletPrint(); return; } if (amh.getMessage("menuitem.props").equals(label)) { networkProperties(); return; } if (amh.getMessage("menuitem.close").equals(label)) { appletClose(); return; } if (factory.isStandalone() && amh.getMessage("menuitem.quit").equals(label)) { appletQuit(); return; } //statusMsgStream.println("evt = " + evt); }
How many applets are running?
/** * How many applets are running? */
public static int countApplets() { return appletPanels.size(); }
The current character.
/** * The current character. */
static int c;
Scan spaces.
/** * Scan spaces. */
public static void skipSpace(Reader in) throws IOException { while ((c >= 0) && ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'))) { c = in.read(); } }
Scan identifier
/** * Scan identifier */
public static String scanIdentifier(Reader in) throws IOException { StringBuffer buf = new StringBuffer(); while (true) { if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')) || (c == '_')) { buf.append((char)c); c = in.read(); } else { return buf.toString(); } } }
Scan tag
/** * Scan tag */
public static Hashtable scanTag(Reader in) throws IOException { Hashtable atts = new Hashtable(); skipSpace(in); while (c >= 0 && c != '>') { String att = scanIdentifier(in); String val = ""; skipSpace(in); if (c == '=') { int quote = -1; c = in.read(); skipSpace(in); if ((c == '\'') || (c == '\"')) { quote = c; c = in.read(); } StringBuffer buf = new StringBuffer(); while ((c > 0) && (((quote < 0) && (c != ' ') && (c != '\t') && (c != '\n') && (c != '\r') && (c != '>')) || ((quote >= 0) && (c != quote)))) { buf.append((char)c); c = in.read(); } if (c == quote) { c = in.read(); } skipSpace(in); val = buf.toString(); } //statusMsgStream.println("PUT " + att + " = '" + val + "'"); if (! val.equals("")) { atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val); } while (true) { if ((c == '>') || (c < 0) || ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')) || (c == '_')) break; c = in.read(); } //skipSpace(in); } return atts; } /* values used for placement of AppletViewer's frames */ private static int x = 0; private static int y = 0; private static final int XDELTA = 30; private static final int YDELTA = XDELTA; static String encoding = null; static private Reader makeReader(InputStream is) { if (encoding != null) { try { return new BufferedReader(new InputStreamReader(is, encoding)); } catch (IOException x) { } } InputStreamReader r = new InputStreamReader(is); encoding = r.getEncoding(); return new BufferedReader(r); }
Scan an html file for tags
/** * Scan an html file for <applet> tags */
public static void parse(URL url, String enc) throws IOException { encoding = enc; parse(url, System.out, new StdAppletViewerFactory()); } public static void parse(URL url) throws IOException { parse(url, System.out, new StdAppletViewerFactory()); } public static void parse(URL url, PrintStream statusMsgStream, AppletViewerFactory factory) throws IOException { // <OBJECT> <EMBED> tag flags boolean isAppletTag = false; boolean isObjectTag = false; boolean isEmbedTag = false; // warning messages String requiresNameWarning = amh.getMessage("parse.warning.requiresname"); String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside"); String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode"); String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight"); String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth"); String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode"); String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight"); String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth"); String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode"); String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight"); String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth"); String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported"); java.net.URLConnection conn = url.openConnection(); Reader in = makeReader(conn.getInputStream()); /* The original URL may have been redirected - this * sets it to whatever URL/codebase we ended up getting */ url = conn.getURL(); int ydisp = 1; Hashtable atts = null; while(true) { c = in.read(); if (c == -1) break; if (c == '<') { c = in.read(); if (c == '/') { c = in.read(); String nm = scanIdentifier(in); if (nm.equalsIgnoreCase("applet") || nm.equalsIgnoreCase("object") || nm.equalsIgnoreCase("embed")) { // We can't test for a code tag until </OBJECT> // because it is a parameter, not an attribute. if(isObjectTag) { if (atts.get("code") == null && atts.get("object") == null) { statusMsgStream.println(objectRequiresCodeWarning); atts = null; } } if (atts != null) { // XXX 5/18 In general this code just simply // shouldn't be part of parsing. It's presence // causes things to be a little too much of a // hack. factory.createAppletViewer(x, y, url, atts); x += XDELTA; y += YDELTA; // make sure we don't go too far! Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); if ((x > d.width - 300) || (y > d.height - 300)) { x = 0; y = 2 * ydisp * YDELTA; ydisp++; } } atts = null; isAppletTag = false; isObjectTag = false; isEmbedTag = false; } } else { String nm = scanIdentifier(in); if (nm.equalsIgnoreCase("param")) { Hashtable t = scanTag(in); String att = (String)t.get("name"); if (att == null) { statusMsgStream.println(requiresNameWarning); } else { String val = (String)t.get("value"); if (val == null) { statusMsgStream.println(requiresNameWarning); } else if (atts != null) { atts.put(att.toLowerCase(), val); } else { statusMsgStream.println(paramOutsideWarning); } } } else if (nm.equalsIgnoreCase("applet")) { isAppletTag = true; atts = scanTag(in); if (atts.get("code") == null && atts.get("object") == null) { statusMsgStream.println(appletRequiresCodeWarning); atts = null; } else if (atts.get("width") == null) { statusMsgStream.println(appletRequiresWidthWarning); atts = null; } else if (atts.get("height") == null) { statusMsgStream.println(appletRequiresHeightWarning); atts = null; } } else if (nm.equalsIgnoreCase("object")) { isObjectTag = true; atts = scanTag(in); // The <OBJECT> attribute codebase isn't what // we want. If its defined, remove it. if(atts.get("codebase") != null) { atts.remove("codebase"); } if (atts.get("width") == null) { statusMsgStream.println(objectRequiresWidthWarning); atts = null; } else if (atts.get("height") == null) { statusMsgStream.println(objectRequiresHeightWarning); atts = null; } } else if (nm.equalsIgnoreCase("embed")) { isEmbedTag = true; atts = scanTag(in); if (atts.get("code") == null && atts.get("object") == null) { statusMsgStream.println(embedRequiresCodeWarning); atts = null; } else if (atts.get("width") == null) { statusMsgStream.println(embedRequiresWidthWarning); atts = null; } else if (atts.get("height") == null) { statusMsgStream.println(embedRequiresHeightWarning); atts = null; } } else if (nm.equalsIgnoreCase("app")) { statusMsgStream.println(appNotLongerSupportedWarning); Hashtable atts2 = scanTag(in); nm = (String)atts2.get("class"); if (nm != null) { atts2.remove("class"); atts2.put("code", nm + ".class"); } nm = (String)atts2.get("src"); if (nm != null) { atts2.remove("src"); atts2.put("codebase", nm); } if (atts2.get("width") == null) { atts2.put("width", "100"); } if (atts2.get("height") == null) { atts2.put("height", "100"); } printTag(statusMsgStream, atts2); statusMsgStream.println(); } } } } in.close(); }
Old main entry point.
Deprecated:
/** * Old main entry point. * * @deprecated */
@Deprecated public static void main(String argv[]) { // re-route everything to the new main entry point Main.main(argv); } private static AppletMessageHandler amh = new AppletMessageHandler("appletviewer"); private static void checkConnect(URL url) { SecurityManager security = System.getSecurityManager(); if (security != null) { try { java.security.Permission perm = url.openConnection().getPermission(); if (perm != null) security.checkPermission(perm); else security.checkConnect(url.getHost(), url.getPort()); } catch (java.io.IOException ioe) { security.checkConnect(url.getHost(), url.getPort()); } } } }