diff options
Diffstat (limited to 'plugin/icedteanp/java/sun/applet/PluginAppletViewer.java')
-rw-r--r-- | plugin/icedteanp/java/sun/applet/PluginAppletViewer.java | 3622 |
1 files changed, 1799 insertions, 1823 deletions
diff --git a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java index 29a3103..ca90b70 100644 --- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java +++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java @@ -60,9 +60,9 @@ exception statement from your version. */ * have any questions. */ - package sun.applet; +package sun.applet; - import java.applet.Applet; +import java.applet.Applet; import java.applet.AppletContext; import java.applet.AudioClip; import java.awt.Dimension; @@ -115,368 +115,362 @@ import sun.misc.Ref; import com.sun.jndi.toolkit.url.UrlUtil; - /** - * Lets us construct one using unix-style one shot behaviors - */ +/** + * Lets us construct one using unix-style one shot behaviors + */ - class PluginAppletPanelFactory - { +class PluginAppletPanelFactory { - public AppletPanel createPanel(PluginStreamHandler streamhandler, + public AppletPanel createPanel(PluginStreamHandler streamhandler, int identifier, long handle, int x, int y, final URL doc, - final Hashtable<String,String> atts) { - AppletViewerPanel panel = AccessController.doPrivileged(new PrivilegedAction<AppletViewerPanel>() { - public AppletViewerPanel run() { - try { - AppletViewerPanel panel = new NetxPanel(doc, atts, false); - AppletViewerPanel.debug("Using NetX panel"); - PluginDebug.debug(atts.toString()); - return panel; - } catch (Exception ex) { - AppletViewerPanel.debug("Unable to start NetX applet - defaulting to Sun applet", ex); - return new AppletViewerPanel(doc, atts); - } - } - }); + final Hashtable<String, String> atts) { + AppletViewerPanel panel = AccessController.doPrivileged(new PrivilegedAction<AppletViewerPanel>() { + public AppletViewerPanel run() { + try { + AppletViewerPanel panel = new NetxPanel(doc, atts, false); + AppletViewerPanel.debug("Using NetX panel"); + PluginDebug.debug(atts.toString()); + return panel; + } catch (Exception ex) { + AppletViewerPanel.debug("Unable to start NetX applet - defaulting to Sun applet", ex); + return new AppletViewerPanel(doc, atts); + } + } + }); - // create the frame. - PluginAppletViewer.framePanel(identifier, System.out, handle, panel); + // create the frame. + PluginAppletViewer.framePanel(identifier, System.out, handle, panel); - panel.init(); + panel.init(); - // Start the applet - initEventQueue(panel); + // Start the applet + initEventQueue(panel); - // Applet initialized. Find out it's classloader and add it to the list - String portComponent = doc.getPort() != -1 ? ":" + doc.getPort() : ""; - String codeBase = doc.getProtocol() + "://" + doc.getHost() + portComponent; + // Applet initialized. Find out it's classloader and add it to the list + String portComponent = doc.getPort() != -1 ? ":" + doc.getPort() : ""; + String codeBase = doc.getProtocol() + "://" + doc.getHost() + portComponent; - if (atts.get("codebase") != null) { - try { - URL appletSrcURL = new URL(codeBase + atts.get("codebase")); - codeBase = appletSrcURL.getProtocol() + "://" + appletSrcURL.getHost(); - } catch (MalformedURLException mfue) { - // do nothing - } - } - - - // Wait for the panel to initialize - // (happens in a separate thread) - Applet a; - - // Wait for panel to come alive - int maxWait = PluginAppletViewer.APPLET_TIMEOUT; // wait for panel to come alive - int wait = 0; - while ((panel == null) || (!((NetxPanel) panel).isAlive() && wait < maxWait)) { - try { - Thread.sleep(50); - wait += 50; - } catch (InterruptedException ie) { - // just wait - } - } - - // Wait for the panel to initialize - // (happens in a separate thread) - PluginAppletViewer.waitForAppletInit((NetxPanel) panel); - - a = panel.getApplet(); - - // Still null? - if (panel.getApplet() == null) { - streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError " + "Initialization failed"); - return null; - } - - PluginDebug.debug("Applet " + a.getClass() + " initialized"); - streamhandler.write("instance " + identifier + " reference 0 initialized"); - - AppletSecurityContextManager.getSecurityContext(0).associateSrc(((NetxPanel) panel).getAppletClassLoader(), doc); - AppletSecurityContextManager.getSecurityContext(0).associateInstance(identifier, ((NetxPanel) panel).getAppletClassLoader()); - - return panel; - } - - public boolean isStandalone() - { - return false; - } - - /** - * 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(AppletPanel panel) { - // appletviewer.send.event is an undocumented and unsupported system - // property which is used exclusively for testing purposes. - PrivilegedAction<String> pa = new PrivilegedAction<String>() { - public String run() { - return System.getProperty("appletviewer.send.event"); - } - }; - String eventList = AccessController.doPrivileged(pa); - - 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++) { - PluginDebug.debug("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 - PluginDebug.debug("Unrecognized event name: " + events[i]); - } + if (atts.get("codebase") != null) { + try { + URL appletSrcURL = new URL(codeBase + atts.get("codebase")); + codeBase = appletSrcURL.getProtocol() + "://" + appletSrcURL.getHost(); + } catch (MalformedURLException mfue) { + // do nothing + } + } - while (!panel.emptyEventQueue()) ; - } - } - - - /** - * 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) { - List<String> l = new ArrayList<String>(); - int tokenStart = 0; - int tokenEnd = 0; - - while ((tokenEnd = s.indexOf(sep, tokenStart)) != -1) { - l.add(s.substring(tokenStart, tokenEnd)); - tokenStart = tokenEnd+1; - } - // Add the final element. - l.add(s.substring(tokenStart)); - - return l.toArray(new String[l.size()]); - } - } - - class PluginParseRequest - { - long handle; - String tag; - String documentbase; - } - - /* - */ - // FIXME: declare JSProxy implementation - public class PluginAppletViewer extends XEmbeddedFrame - implements AppletContext, Printable { - /** - * Some constants... - */ - private static String defaultSaveFile = "Applet.ser"; + // Wait for the panel to initialize + // (happens in a separate thread) + Applet a; + + // Wait for panel to come alive + int maxWait = PluginAppletViewer.APPLET_TIMEOUT; // wait for panel to come alive + int wait = 0; + while ((panel == null) || (!((NetxPanel) panel).isAlive() && wait < maxWait)) { + try { + Thread.sleep(50); + wait += 50; + } catch (InterruptedException ie) { + // just wait + } + } + + // Wait for the panel to initialize + // (happens in a separate thread) + PluginAppletViewer.waitForAppletInit((NetxPanel) panel); + + a = panel.getApplet(); + + // Still null? + if (panel.getApplet() == null) { + streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError " + "Initialization failed"); + return null; + } + + PluginDebug.debug("Applet " + a.getClass() + " initialized"); + streamhandler.write("instance " + identifier + " reference 0 initialized"); + + AppletSecurityContextManager.getSecurityContext(0).associateSrc(((NetxPanel) panel).getAppletClassLoader(), doc); + AppletSecurityContextManager.getSecurityContext(0).associateInstance(identifier, ((NetxPanel) panel).getAppletClassLoader()); + + return panel; + } + + public boolean isStandalone() { + return false; + } + + /** + * 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(AppletPanel panel) { + // appletviewer.send.event is an undocumented and unsupported system + // property which is used exclusively for testing purposes. + PrivilegedAction<String> pa = new PrivilegedAction<String>() { + public String run() { + return System.getProperty("appletviewer.send.event"); + } + }; + String eventList = AccessController.doPrivileged(pa); + + 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++) { + PluginDebug.debug("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 + PluginDebug.debug("Unrecognized event name: " + events[i]); + } + + while (!panel.emptyEventQueue()) + ; + } + } + /** + * 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) { + List<String> l = new ArrayList<String>(); + int tokenStart = 0; + int tokenEnd = 0; + + while ((tokenEnd = s.indexOf(sep, tokenStart)) != -1) { + l.add(s.substring(tokenStart, tokenEnd)); + tokenStart = tokenEnd + 1; + } + // Add the final element. + l.add(s.substring(tokenStart)); + + return l.toArray(new String[l.size()]); + } +} + +class PluginParseRequest { + long handle; + String tag; + String documentbase; +} + +/* + */ +// FIXME: declare JSProxy implementation +public class PluginAppletViewer extends XEmbeddedFrame + implements AppletContext, Printable { + /** + * Some constants... + */ + private static String defaultSaveFile = "Applet.ser"; - /** - * Enumerates the current status of an applet - * - * PRE_INIT -> Parsing and initialization phase - * INIT_COMPLETE -> Initialization complete, reframe pending - * REFRAME_COMPLETE -> Reframe complete, applet is initialized and usable by the user - * INACTIVE -> Browser has directed that the applet be destroyed (this state is non-overridable except by DESTROYED) - * DESTROYED -> Applet has been destroyed - */ - private static enum PAV_INIT_STATUS {PRE_INIT, INIT_COMPLETE, REFRAME_COMPLETE, INACTIVE, DESTROYED}; + /** + * Enumerates the current status of an applet + * + * PRE_INIT -> Parsing and initialization phase + * INIT_COMPLETE -> Initialization complete, reframe pending + * REFRAME_COMPLETE -> Reframe complete, applet is initialized and usable by the user + * INACTIVE -> Browser has directed that the applet be destroyed (this state is non-overridable except by DESTROYED) + * DESTROYED -> Applet has been destroyed + */ + private static enum PAV_INIT_STATUS { + PRE_INIT, INIT_COMPLETE, REFRAME_COMPLETE, INACTIVE, DESTROYED + }; - /** - * The panel in which the applet is being displayed. - */ - AppletViewerPanel panel; + /** + * The panel in which the applet is being displayed. + */ + AppletViewerPanel panel; - /** - * The status line. - */ - Label label; + /** + * The status line. + */ + Label label; - /** - * output status messages to this stream - */ + /** + * output status messages to this stream + */ - PrintStream statusMsgStream; + PrintStream statusMsgStream; - int identifier; + int identifier; - private static HashMap<Integer, PluginParseRequest> requests = - new HashMap<Integer,PluginParseRequest>(); + private static HashMap<Integer, PluginParseRequest> requests = + new HashMap<Integer, PluginParseRequest>(); - // Instance identifier -> PluginAppletViewer object. - private static HashMap<Integer, PluginAppletViewer> applets = - new HashMap<Integer,PluginAppletViewer>(); + // Instance identifier -> PluginAppletViewer object. + private static HashMap<Integer, PluginAppletViewer> applets = + new HashMap<Integer, PluginAppletViewer>(); - private static PluginStreamHandler streamhandler; + private static PluginStreamHandler streamhandler; - private static PluginCallRequestFactory requestFactory; + private static PluginCallRequestFactory requestFactory; - private static HashMap<Integer, PAV_INIT_STATUS> status = - new HashMap<Integer,PAV_INIT_STATUS>(); + private static HashMap<Integer, PAV_INIT_STATUS> status = + new HashMap<Integer, PAV_INIT_STATUS>(); - private long handle = 0; - private WindowListener windowEventListener = null; - private AppletEventListener appletEventListener = null; + private long handle = 0; + private WindowListener windowEventListener = null; + private AppletEventListener appletEventListener = null; - public static final int APPLET_TIMEOUT = 180000; + public static final int APPLET_TIMEOUT = 180000; - private static Long requestIdentityCounter = 0L; + private static Long requestIdentityCounter = 0L; - private Image bufFrameImg; - private Graphics bufFrameImgGraphics; + private Image bufFrameImg; + private Graphics bufFrameImgGraphics; - /** - * Null constructor to allow instantiation via newInstance() - */ - public PluginAppletViewer() { - } + /** + * Null constructor to allow instantiation via newInstance() + */ + public PluginAppletViewer() { + } - public static void framePanel(int identifier, PrintStream statusMsgStream, + public static void framePanel(int identifier, PrintStream statusMsgStream, long handle, AppletViewerPanel panel) { - PluginDebug.debug("Framing " + panel); + PluginDebug.debug("Framing " + panel); - // SecurityManager MUST be set, and only privileged code may call reFrame() - System.getSecurityManager().checkPermission(new AllPermission()); + // SecurityManager MUST be set, and only privileged code may call reFrame() + System.getSecurityManager().checkPermission(new AllPermission()); - PluginAppletViewer appletFrame = new PluginAppletViewer(handle, identifier, statusMsgStream, panel); + PluginAppletViewer appletFrame = new PluginAppletViewer(handle, identifier, statusMsgStream, panel); - appletFrame.add("Center", panel); - appletFrame.pack(); + appletFrame.add("Center", panel); + appletFrame.pack(); - appletFrame.appletEventListener = new AppletEventListener(appletFrame, appletFrame); - panel.addAppletListener(appletFrame.appletEventListener); + appletFrame.appletEventListener = new AppletEventListener(appletFrame, appletFrame); + panel.addAppletListener(appletFrame.appletEventListener); - applets.put(identifier, appletFrame); + applets.put(identifier, appletFrame); - PluginDebug.debug(panel + " framed"); - } + PluginDebug.debug(panel + " framed"); + } - /** - * Create new plugin appletviewer frame - */ - private PluginAppletViewer(long handle, final int identifier, + /** + * Create new plugin appletviewer frame + */ + private PluginAppletViewer(long handle, final int identifier, PrintStream statusMsgStream, AppletViewerPanel appletPanel) { - super(handle, true); - this.statusMsgStream = statusMsgStream; - this.identifier = identifier; - this.panel = appletPanel; + super(handle, true); + this.statusMsgStream = statusMsgStream; + this.identifier = identifier; + this.panel = appletPanel; - if (!appletPanels.contains(panel)) - appletPanels.addElement(panel); + if (!appletPanels.contains(panel)) + appletPanels.addElement(panel); - windowEventListener = new WindowAdapter() { + windowEventListener = new WindowAdapter() { - public void windowClosing(WindowEvent evt) { - appletClose(); - } + public void windowClosing(WindowEvent evt) { + appletClose(); + } - public void windowIconified(WindowEvent evt) { - appletStop(); - } + public void windowIconified(WindowEvent evt) { + appletStop(); + } - public void windowDeiconified(WindowEvent evt) { - appletStart(); - } - }; + public void windowDeiconified(WindowEvent evt) { + appletStart(); + } + }; - addWindowListener(windowEventListener); + addWindowListener(windowEventListener); - } + } - private static class AppletEventListener implements AppletListener - { - final Frame frame; - final PluginAppletViewer appletViewer; + private static class AppletEventListener implements AppletListener { + final Frame frame; + final PluginAppletViewer appletViewer; - public AppletEventListener(Frame frame, PluginAppletViewer appletViewer) - { - this.frame = frame; - this.appletViewer = appletViewer; - } + public AppletEventListener(Frame frame, PluginAppletViewer appletViewer) { + this.frame = frame; + this.appletViewer = appletViewer; + } - public void appletStateChanged(AppletEvent evt) - { - AppletPanel src = (AppletPanel)evt.getSource(); + public void appletStateChanged(AppletEvent evt) { + AppletPanel src = (AppletPanel) evt.getSource(); - switch (evt.getID()) { - case AppletPanel.APPLET_RESIZE: { - if(src != null) { - appletViewer.setSize(appletViewer.getPreferredSize()); - appletViewer.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()); - - updateStatus(appletViewer.identifier, PAV_INIT_STATUS.INIT_COMPLETE); - - break; - } - } - } - } + switch (evt.getID()) { + case AppletPanel.APPLET_RESIZE: { + if (src != null) { + appletViewer.setSize(appletViewer.getPreferredSize()); + appletViewer.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()); + + updateStatus(appletViewer.identifier, PAV_INIT_STATUS.INIT_COMPLETE); + + break; + } + } + } + } public static void setStreamhandler(PluginStreamHandler sh) { streamhandler = sh; @@ -486,288 +480,286 @@ import com.sun.jndi.toolkit.url.UrlUtil; requestFactory = rf; } - /** - * Handle an incoming message from the plugin. - */ - public static void handleMessage(int identifier, int reference, String message) - { - - PluginDebug.debug("PAV handling: " + message); - - try { - if (message.startsWith("handle")) { - - // If there is a key for this status, it means it - // was either initialized before, or destroy has been - // processed. Stop moving further. - if (updateStatus(identifier, PAV_INIT_STATUS.PRE_INIT) != null) - return; - - // Extract the information from the message - String[] msgParts = new String[4]; - for (int i=0; i < 3; i++) { - int spaceLocation = message.indexOf(' '); - int nextSpaceLocation = message.indexOf(' ', spaceLocation+1); - msgParts[i] = message.substring(spaceLocation + 1, nextSpaceLocation); - message = message.substring(nextSpaceLocation + 1); - } - - long handle = Long.parseLong(msgParts[0]); - String width = msgParts[1]; - String height = msgParts[2]; - - int spaceLocation = message.indexOf(' ', "tag".length()+1); - String documentBase = - UrlUtil.decode(message.substring("tag".length() + 1, spaceLocation)); - String tag = message.substring(spaceLocation+1); + /** + * Handle an incoming message from the plugin. + */ + public static void handleMessage(int identifier, int reference, String message) { - // Decode the tag - tag = tag.replace(">", ">"); - tag = tag.replace("<", "<"); - tag = tag.replace("&", "&"); - tag = tag.replace(" ", "\n"); - tag = tag.replace(" ", "\r"); - tag = tag.replace(""", "\""); + PluginDebug.debug("PAV handling: " + message); - PluginDebug.debug ("Handle = " + handle + "\n" + + try { + if (message.startsWith("handle")) { + + // If there is a key for this status, it means it + // was either initialized before, or destroy has been + // processed. Stop moving further. + if (updateStatus(identifier, PAV_INIT_STATUS.PRE_INIT) != null) + return; + + // Extract the information from the message + String[] msgParts = new String[4]; + for (int i = 0; i < 3; i++) { + int spaceLocation = message.indexOf(' '); + int nextSpaceLocation = message.indexOf(' ', spaceLocation + 1); + msgParts[i] = message.substring(spaceLocation + 1, nextSpaceLocation); + message = message.substring(nextSpaceLocation + 1); + } + + long handle = Long.parseLong(msgParts[0]); + String width = msgParts[1]; + String height = msgParts[2]; + + int spaceLocation = message.indexOf(' ', "tag".length() + 1); + String documentBase = + UrlUtil.decode(message.substring("tag".length() + 1, spaceLocation)); + String tag = message.substring(spaceLocation + 1); + + // Decode the tag + tag = tag.replace(">", ">"); + tag = tag.replace("<", "<"); + tag = tag.replace("&", "&"); + tag = tag.replace(" ", "\n"); + tag = tag.replace(" ", "\r"); + tag = tag.replace(""", "\""); + + PluginDebug.debug("Handle = " + handle + "\n" + "Width = " + width + "\n" + "Height = " + height + "\n" + "DocumentBase = " + documentBase + "\n" + "Tag = " + tag); - PluginAppletViewer.parse + PluginAppletViewer.parse (identifier, handle, width, height, new StringReader(tag), new URL(documentBase)); - int maxWait = APPLET_TIMEOUT; // wait for applet to fully load - int wait = 0; - while ( !applets.containsKey(identifier) && // Map is populated only by reFrame - (wait < maxWait)) { - - try { - Thread.sleep(50); - wait += 50; - } catch (InterruptedException ie) { - // just wait - } - } + int maxWait = APPLET_TIMEOUT; // wait for applet to fully load + int wait = 0; + while (!applets.containsKey(identifier) && // Map is populated only by reFrame + (wait < maxWait)) { - // If wait exceeded maxWait, we timed out. Throw an exception - if (wait >= maxWait) - throw new Exception("Applet initialization timeout"); + try { + Thread.sleep(50); + wait += 50; + } catch (InterruptedException ie) { + // just wait + } + } - PluginAppletViewer oldFrame = applets.get(identifier); + // If wait exceeded maxWait, we timed out. Throw an exception + if (wait >= maxWait) + throw new Exception("Applet initialization timeout"); - // We should not try to destroy an applet during - // initialization. It may cause an inconsistent state, - // which would bad if it's a trusted applet that - // read/writes to files - waitForAppletInit((NetxPanel) applets.get(identifier).panel); + PluginAppletViewer oldFrame = applets.get(identifier); - // Should we proceed with reframing? - if (updateStatus(identifier, PAV_INIT_STATUS.REFRAME_COMPLETE).equals(PAV_INIT_STATUS.INACTIVE)) { - destroyApplet(identifier); - return; - } + // We should not try to destroy an applet during + // initialization. It may cause an inconsistent state, + // which would bad if it's a trusted applet that + // read/writes to files + waitForAppletInit((NetxPanel) applets.get(identifier).panel); + + // Should we proceed with reframing? + if (updateStatus(identifier, PAV_INIT_STATUS.REFRAME_COMPLETE).equals(PAV_INIT_STATUS.INACTIVE)) { + destroyApplet(identifier); + return; + } - } else if (message.startsWith("destroy")) { + } else if (message.startsWith("destroy")) { - // Set it inactive, and try to do cleanup is applicable - PAV_INIT_STATUS previousStatus = updateStatus(identifier, PAV_INIT_STATUS.INACTIVE); - PluginDebug.debug("Destroy status set for " + identifier); + // Set it inactive, and try to do cleanup is applicable + PAV_INIT_STATUS previousStatus = updateStatus(identifier, PAV_INIT_STATUS.INACTIVE); + PluginDebug.debug("Destroy status set for " + identifier); - if (previousStatus != null && + if (previousStatus != null && previousStatus.equals(PAV_INIT_STATUS.REFRAME_COMPLETE)) { - destroyApplet(identifier); - } + destroyApplet(identifier); + } - } else { - PluginDebug.debug ("Handling message: " + message + " instance " + identifier + " " + Thread.currentThread()); + } else { + PluginDebug.debug("Handling message: " + message + " instance " + identifier + " " + Thread.currentThread()); - // Wait till initialization finishes - while (!applets.containsKey(identifier) && + // Wait till initialization finishes + while (!applets.containsKey(identifier) && ( !status.containsKey(identifier) || status.get(identifier).equals(PAV_INIT_STATUS.PRE_INIT) - ) - ); + )) + ; - // don't bother processing further for inactive applets - if (status.get(identifier).equals(PAV_INIT_STATUS.INACTIVE)) - return; + // don't bother processing further for inactive applets + if (status.get(identifier).equals(PAV_INIT_STATUS.INACTIVE)) + return; - applets.get(identifier).handleMessage(reference, message); - } - } catch (Exception e) { + applets.get(identifier).handleMessage(reference, message); + } + } catch (Exception e) { - e.printStackTrace(); + e.printStackTrace(); - // If an exception happened during pre-init, we need to update status - updateStatus(identifier, PAV_INIT_STATUS.INACTIVE); + // If an exception happened during pre-init, we need to update status + updateStatus(identifier, PAV_INIT_STATUS.INACTIVE); - throw new RuntimeException("Failed to handle message: " + + throw new RuntimeException("Failed to handle message: " + message + " for instance " + identifier, e); - } - } - - /** - * Sets the status unless an overriding status is set (e.g. if - * status is DESTROYED, it may not be overridden). - * - * @param identifier The identifier for which the status is to be set - * @param status The status to switch to - * @return The previous status - */ - private static synchronized PAV_INIT_STATUS updateStatus(int identifier, PAV_INIT_STATUS newStatus) { - - PAV_INIT_STATUS prev = status.get(identifier); - - // If the status is set - if (status.containsKey(identifier)) { - - // Nothing may override destroyed status - if (status.get(identifier).equals(PAV_INIT_STATUS.DESTROYED)) { - return prev; - } + } + } - // If status is inactive, only DESTROYED may override it - if (status.get(identifier).equals(PAV_INIT_STATUS.INACTIVE)) { - if (!newStatus.equals(PAV_INIT_STATUS.DESTROYED)) { - return prev; - } - } - } + /** + * Sets the status unless an overriding status is set (e.g. if + * status is DESTROYED, it may not be overridden). + * + * @param identifier The identifier for which the status is to be set + * @param status The status to switch to + * @return The previous status + */ + private static synchronized PAV_INIT_STATUS updateStatus(int identifier, PAV_INIT_STATUS newStatus) { + + PAV_INIT_STATUS prev = status.get(identifier); + + // If the status is set + if (status.containsKey(identifier)) { + + // Nothing may override destroyed status + if (status.get(identifier).equals(PAV_INIT_STATUS.DESTROYED)) { + return prev; + } + + // If status is inactive, only DESTROYED may override it + if (status.get(identifier).equals(PAV_INIT_STATUS.INACTIVE)) { + if (!newStatus.equals(PAV_INIT_STATUS.DESTROYED)) { + return prev; + } + } + } // Else set to given status status.put(identifier, newStatus); return prev; - } + } - /** - * Destroys the given applet instance. - * - * This function may be called multiple times without problems. - * It does a synchronized check on the status and will only - * attempt to destroy the applet if not previously destroyed. - * - * @param identifier The instance which is to be destroyed - */ + /** + * Destroys the given applet instance. + * + * This function may be called multiple times without problems. + * It does a synchronized check on the status and will only + * attempt to destroy the applet if not previously destroyed. + * + * @param identifier The instance which is to be destroyed + */ - private static synchronized void destroyApplet(int identifier) { + private static synchronized void destroyApplet(int identifier) { - PluginDebug.debug("DestroyApplet called for " + identifier); + PluginDebug.debug("DestroyApplet called for " + identifier); - PAV_INIT_STATUS prev = updateStatus(identifier, PAV_INIT_STATUS.DESTROYED); + PAV_INIT_STATUS prev = updateStatus(identifier, PAV_INIT_STATUS.DESTROYED); - // If already destroyed, return - if (prev.equals(PAV_INIT_STATUS.DESTROYED)) { - PluginDebug.debug(identifier + " already destroyed. Returning."); - return; - } + // If already destroyed, return + if (prev.equals(PAV_INIT_STATUS.DESTROYED)) { + PluginDebug.debug(identifier + " already destroyed. Returning."); + return; + } - PluginDebug.debug("Attempting to destroy frame " + identifier); + PluginDebug.debug("Attempting to destroy frame " + identifier); - // Try to dispose the panel right away - if (applets.containsKey(identifier)) - applets.get(identifier).dispose(); + // Try to dispose the panel right away + if (applets.containsKey(identifier)) + applets.get(identifier).dispose(); - // If panel is already disposed, return - if (applets.get(identifier).panel.applet == null) { - PluginDebug.debug(identifier + " panel inactive. Returning."); - return; - } + // If panel is already disposed, return + if (applets.get(identifier).panel.applet == null) { + PluginDebug.debug(identifier + " panel inactive. Returning."); + return; + } - PluginDebug.debug("Attempting to destroy panel " + identifier); + PluginDebug.debug("Attempting to destroy panel " + identifier); - final int fIdentifier = identifier; - SwingUtilities.invokeLater(new Runnable() { - public void run() { - applets.get(fIdentifier).appletClose(); - } - }); + final int fIdentifier = identifier; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + applets.get(fIdentifier).appletClose(); + } + }); - PluginDebug.debug(identifier + " destroyed"); - } + PluginDebug.debug(identifier + " destroyed"); + } - /** - * Function to block until applet initialization is complete - * - * @param identifier The instance to wait for - */ - public static void waitForAppletInit(NetxPanel panel) { + /** + * Function to block until applet initialization is complete + * + * @param identifier The instance to wait for + */ + public static void waitForAppletInit(NetxPanel panel) { - int waitTime = 0; + int waitTime = 0; - // Wait till initialization finishes - while (panel.getApplet() == null && + // Wait till initialization finishes + while (panel.getApplet() == null && panel.isAlive() && waitTime < APPLET_TIMEOUT) { - try { - if (waitTime%500 == 0) - PluginDebug.debug("Waiting for applet panel " + panel + " to initialize..."); + try { + if (waitTime % 500 == 0) + PluginDebug.debug("Waiting for applet panel " + panel + " to initialize..."); - Thread.sleep(waitTime += 50); - } catch (InterruptedException ie) { - // just wait - } - } - - PluginDebug.debug("Applet panel " + panel + " initialized"); - } - - public void handleMessage(int reference, String message) - { - if (message.startsWith("width")) { - - // Wait for panel to come alive - int maxWait = APPLET_TIMEOUT; // wait for panel to come alive - int wait = 0; - while (!status.get(identifier).equals(PAV_INIT_STATUS.INIT_COMPLETE) && wait < maxWait) { - try { - Thread.sleep(50); - wait += 50; - } catch (InterruptedException ie) { - // just wait - } - } + Thread.sleep(waitTime += 50); + } catch (InterruptedException ie) { + // just wait + } + } - // 0 => width, 1=> width_value, 2 => height, 3=> height_value - String[] dimMsg = message.split(" "); + PluginDebug.debug("Applet panel " + panel + " initialized"); + } - final int height = Integer.parseInt(dimMsg[3]); - final int width = Integer.parseInt(dimMsg[1]); + public void handleMessage(int reference, String message) { + if (message.startsWith("width")) { + + // Wait for panel to come alive + int maxWait = APPLET_TIMEOUT; // wait for panel to come alive + int wait = 0; + while (!status.get(identifier).equals(PAV_INIT_STATUS.INIT_COMPLETE) && wait < maxWait) { + try { + Thread.sleep(50); + wait += 50; + } catch (InterruptedException ie) { + // just wait + } + } + + // 0 => width, 1=> width_value, 2 => height, 3=> height_value + String[] dimMsg = message.split(" "); - if (panel instanceof NetxPanel) - ((NetxPanel) panel).updateSizeInAtts(height, width); + final int height = Integer.parseInt(dimMsg[3]); + final int width = Integer.parseInt(dimMsg[1]); - try { + if (panel instanceof NetxPanel) + ((NetxPanel) panel).updateSizeInAtts(height, width); + + try { SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - - setSize(width, height); - - // There is a rather odd drawing bug whereby resizing - // the panel makes no difference on initial call - // because the panel thinks that it is already the - // right size. Validation has no effect there either. - // So we work around by setting size to 1, validating, - // and then setting to the right size and validating - // again. This is not very efficient, and there is - // probably a better way -- but resizing happens - // quite infrequently, so for now this is how we do it - - panel.setSize(1,1); - panel.validate(); - - panel.setSize(width, height); - panel.validate(); - - panel.applet.resize(width, height); - panel.applet.validate(); - } - }); + public void run() { + + setSize(width, height); + + // There is a rather odd drawing bug whereby resizing + // the panel makes no difference on initial call + // because the panel thinks that it is already the + // right size. Validation has no effect there either. + // So we work around by setting size to 1, validating, + // and then setting to the right size and validating + // again. This is not very efficient, and there is + // probably a better way -- but resizing happens + // quite infrequently, so for now this is how we do it + + panel.setSize(1, 1); + panel.validate(); + + panel.setSize(width, height); + panel.validate(); + + panel.applet.resize(width, height); + panel.applet.validate(); + } + }); } catch (InterruptedException e) { // do nothing e.printStackTrace(); @@ -776,780 +768,771 @@ import com.sun.jndi.toolkit.url.UrlUtil; e.printStackTrace(); } - } else if (message.startsWith("GetJavaObject")) { - - // FIXME: how do we determine what security context this - // object should belong to? - Object o; - - // Wait for panel to come alive - int maxWait = APPLET_TIMEOUT; // wait for panel to come alive - int wait = 0; - while ((panel == null) || (!((NetxPanel) panel).isAlive() && wait < maxWait)) { - try { - Thread.sleep(50); - wait += 50; - } catch (InterruptedException ie) { - // just wait - } - } + } else if (message.startsWith("GetJavaObject")) { + + // FIXME: how do we determine what security context this + // object should belong to? + Object o; + + // Wait for panel to come alive + int maxWait = APPLET_TIMEOUT; // wait for panel to come alive + int wait = 0; + while ((panel == null) || (!((NetxPanel) panel).isAlive() && wait < maxWait)) { + try { + Thread.sleep(50); + wait += 50; + } catch (InterruptedException ie) { + // just wait + } + } - // Wait for the panel to initialize - // (happens in a separate thread) - waitForAppletInit((NetxPanel) panel); + // Wait for the panel to initialize + // (happens in a separate thread) + waitForAppletInit((NetxPanel) panel); - PluginDebug.debug(panel + " -- " + panel.getApplet() + " -- " + ((NetxPanel) panel).isAlive()); + PluginDebug.debug(panel + " -- " + panel.getApplet() + " -- " + ((NetxPanel) panel).isAlive()); - // Still null? - if (panel.getApplet() == null) { - this.streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError " + "Initialization failed"); - return; - } + // Still null? + if (panel.getApplet() == null) { + this.streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError " + "Initialization failed"); + return; + } - o = panel.getApplet(); - PluginDebug.debug ("Looking for object " + o + " panel is " + panel); - AppletSecurityContextManager.getSecurityContext(0).store(o); - PluginDebug.debug ("WRITING 1: " + "context 0 reference " + reference + " GetJavaObject " + o = panel.getApplet(); + PluginDebug.debug("Looking for object " + o + " panel is " + panel); + AppletSecurityContextManager.getSecurityContext(0).store(o); + PluginDebug.debug("WRITING 1: " + "context 0 reference " + reference + " GetJavaObject " + AppletSecurityContextManager.getSecurityContext(0).getIdentifier(o)); - streamhandler.write("context 0 reference " + reference + " GetJavaObject " + streamhandler.write("context 0 reference " + reference + " GetJavaObject " + AppletSecurityContextManager.getSecurityContext(0).getIdentifier(o)); - PluginDebug.debug ("WRITING 1 DONE"); - } - } - - // FIXME: Kind of hackish way to ensure synchronized re-drawing - private synchronized void forceredraw() { - doLayout(); - } - - /* - * Methods for java.applet.AppletContext - */ - - private static Map<URL,AudioClip> audioClips = new HashMap<URL,AudioClip>(); - - /** - * Get an audio clip. - */ - public AudioClip getAudioClip(URL url) { - checkConnect(url); - synchronized (audioClips) { - AudioClip clip = audioClips.get(url); - if (clip == null) { - audioClips.put(url, clip = new AppletAudioClip(url)); - } - return clip; - } - } + PluginDebug.debug("WRITING 1 DONE"); + } + } + + // FIXME: Kind of hackish way to ensure synchronized re-drawing + private synchronized void forceredraw() { + doLayout(); + } + + /* + * Methods for java.applet.AppletContext + */ + + private static Map<URL, AudioClip> audioClips = new HashMap<URL, AudioClip>(); + + /** + * Get an audio clip. + */ + public AudioClip getAudioClip(URL url) { + checkConnect(url); + synchronized (audioClips) { + AudioClip clip = audioClips.get(url); + if (clip == null) { + audioClips.put(url, clip = new AppletAudioClip(url)); + } + return clip; + } + } - private static Map<URL,AppletImageRef> imageRefs = new HashMap<URL,AppletImageRef>(); + private static Map<URL, AppletImageRef> imageRefs = new HashMap<URL, AppletImageRef>(); - /** - * Get an image. - */ - public Image getImage(URL url) { - return getCachedImage(url); - } + /** + * Get an image. + */ + public Image getImage(URL url) { + return getCachedImage(url); + } - private Image getCachedImage(URL url) { - // System.getSecurityManager().checkConnection(url.getHost(), url.getPort()); - return (Image)getCachedImageRef(url).get(); - } + private Image getCachedImage(URL url) { + // System.getSecurityManager().checkConnection(url.getHost(), url.getPort()); + return (Image) getCachedImageRef(url).get(); + } - /** - * Get an image ref. - */ - private synchronized Ref getCachedImageRef(URL url) { - PluginDebug.debug("getCachedImageRef() searching for " + url); + /** + * Get an image ref. + */ + private synchronized Ref getCachedImageRef(URL url) { + PluginDebug.debug("getCachedImageRef() searching for " + url); - try { + try { - String originalURL = url.toString(); - String codeBase = panel.getCodeBase().toString(); + String originalURL = url.toString(); + String codeBase = panel.getCodeBase().toString(); - if (originalURL.startsWith(codeBase)) { + if (originalURL.startsWith(codeBase)) { - PluginDebug.debug("getCachedImageRef() got URL = " + url); - PluginDebug.debug("getCachedImageRef() plugin codebase = " + codeBase); + PluginDebug.debug("getCachedImageRef() got URL = " + url); + PluginDebug.debug("getCachedImageRef() plugin codebase = " + codeBase); - // try to fetch it locally - if (panel instanceof NetxPanel) { + // try to fetch it locally + if (panel instanceof NetxPanel) { - URL localURL = null; + URL localURL = null; - String resourceName = originalURL.substring(codeBase.length()); - JNLPClassLoader loader = (JNLPClassLoader) ((NetxPanel) panel).getAppletClassLoader(); + String resourceName = originalURL.substring(codeBase.length()); + JNLPClassLoader loader = (JNLPClassLoader) ((NetxPanel) panel).getAppletClassLoader(); - if (loader.resourceAvailableLocally(resourceName)) - localURL = loader.getResource(resourceName); + if (loader.resourceAvailableLocally(resourceName)) + localURL = loader.getResource(resourceName); - url = localURL != null ? localURL : url; - } - } + url = localURL != null ? localURL : url; + } + } - PluginDebug.debug("getCachedImageRef() getting img from URL = " + url); + PluginDebug.debug("getCachedImageRef() getting img from URL = " + url); - synchronized (imageRefs) { - AppletImageRef ref = imageRefs.get(url); - if (ref == null) { - ref = new AppletImageRef(url); - imageRefs.put(url, ref); - } - return ref; - } - } catch (Exception e) { - System.err.println("Error occurred when trying to fetch image:"); - e.printStackTrace(); - return null; - } - } - - /** - * Flush the image cache. - */ - static void flushImageCache() { + synchronized (imageRefs) { + AppletImageRef ref = imageRefs.get(url); + if (ref == null) { + ref = new AppletImageRef(url); + imageRefs.put(url, ref); + } + return ref; + } + } catch (Exception e) { + System.err.println("Error occurred when trying to fetch image:"); + e.printStackTrace(); + return null; + } + } + + /** + * Flush the image cache. + */ + static void flushImageCache() { imageRefs.clear(); - } - - static Vector<AppletPanel> appletPanels = new Vector<AppletPanel>(); - - /** - * Get an applet by name. - */ - public Applet getApplet(String name) { - 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(); + } + + static Vector<AppletPanel> appletPanels = new Vector<AppletPanel>(); + + /** + * Get an applet by name. + */ + public Applet getApplet(String name) { + 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. + */ + public Enumeration<Applet> getApplets() { + Vector<Applet> v = new Vector<Applet>(); + SocketPermission panelSp = + new SocketPermission(panel.getCodeBase().getHost(), "connect"); + + for (Enumeration<AppletPanel> e = appletPanels.elements(); e.hasMoreElements();) { + AppletPanel p = e.nextElement(); + if (p.getDocumentBase().equals(panel.getDocumentBase())) { + + SocketPermission sp = + new SocketPermission(p.getCodeBase().getHost(), "connect"); + if (panelSp.implies(sp)) { + v.addElement(p.applet); + } + } } - if (name.equals(param) && - p.getDocumentBase().equals(panel.getDocumentBase())) { + return v.elements(); + } - SocketPermission sp = - new SocketPermission(p.getCodeBase().getHost(), "connect"); + /** + * Ignore. + */ + public void showDocument(URL url) { + PluginDebug.debug("Showing document..."); + showDocument(url, "_self"); + } - if (panelSp.implies(sp)) { - return p.applet; + /** + * Ignore. + */ + public void showDocument(URL url, String target) { + try { + // FIXME: change to postCallRequest + write("url " + UrlUtil.encode(url.toString(), "UTF-8") + " " + target); + } catch (IOException exception) { + // Deliberately ignore IOException. showDocument may be + // called from threads other than the main thread after + // streamhandler.pluginOutputStream has been closed. } + } + + /** + * Show status. + */ + public void showStatus(String status) { + try { + // FIXME: change to postCallRequest + // For statuses, we cannot have a newline + status = status.replace("\n", " "); + write("status " + status); + } catch (IOException exception) { + // Deliberately ignore IOException. showStatus may be + // called from threads other than the main thread after + // streamhandler.pluginOutputStream has been closed. } } - return null; - } - - /** - * Return an enumeration of all the accessible - * applets on this page. - */ - public Enumeration<Applet> getApplets() { - Vector<Applet> v = new Vector<Applet>(); - SocketPermission panelSp = - new SocketPermission(panel.getCodeBase().getHost(), "connect"); - - for (Enumeration<AppletPanel> e = appletPanels.elements() ; e.hasMoreElements() ;) { - AppletPanel p = 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. - */ - public void showDocument(URL url) { - PluginDebug.debug("Showing document..."); - showDocument(url, "_self"); - } - - /** - * Ignore. - */ - public void showDocument(URL url, String target) { - try { - // FIXME: change to postCallRequest - write("url " + UrlUtil.encode(url.toString(), "UTF-8") + " " + target); - } catch (IOException exception) { - // Deliberately ignore IOException. showDocument may be - // called from threads other than the main thread after - // streamhandler.pluginOutputStream has been closed. - } - } - - /** - * Show status. - */ - public void showStatus(String status) { - try { - // FIXME: change to postCallRequest - // For statuses, we cannot have a newline - status = status.replace("\n", " "); - write("status " + status); - } catch (IOException exception) { - // Deliberately ignore IOException. showStatus may be - // called from threads other than the main thread after - // streamhandler.pluginOutputStream has been closed. - } - } - - /** - * Returns an incremental number (unique identifier) for a message. - * If identifier hits Long.MAX_VALUE it loops back starting at 0. - * - * @return A unique Long identifier for the request - */ - private static Long getRequestIdentifier() { - synchronized (requestIdentityCounter) { - - if (requestIdentityCounter == Long.MAX_VALUE) - requestIdentityCounter = 0L; - - return requestIdentityCounter++; + + /** + * Returns an incremental number (unique identifier) for a message. + * If identifier hits Long.MAX_VALUE it loops back starting at 0. + * + * @return A unique Long identifier for the request + */ + private static Long getRequestIdentifier() { + synchronized (requestIdentityCounter) { + + if (requestIdentityCounter == Long.MAX_VALUE) + requestIdentityCounter = 0L; + + return requestIdentityCounter++; } - } - - public long getWindow() { - PluginDebug.debug ("STARTING getWindow"); - Long reference = getRequestIdentifier(); - - PluginCallRequest request = requestFactory.getPluginCallRequest("window", - "instance " + identifier + " reference " + - + reference + " " + "GetWindow", reference); - - PluginDebug.debug ("STARTING postCallRequest"); - streamhandler.postCallRequest(request); - PluginDebug.debug ("STARTING postCallRequest done"); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait request 1"); - synchronized(request) { - PluginDebug.debug ("wait request 2"); - while ((Long) request.getObject() == 0) - request.wait(); - PluginDebug.debug ("wait request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", + } + + public long getWindow() { + PluginDebug.debug("STARTING getWindow"); + Long reference = getRequestIdentifier(); + + PluginCallRequest request = requestFactory.getPluginCallRequest("window", + "instance " + identifier + " reference " + + +reference + " " + "GetWindow", reference); + + PluginDebug.debug("STARTING postCallRequest"); + streamhandler.postCallRequest(request); + PluginDebug.debug("STARTING postCallRequest done"); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait request 1"); + synchronized (request) { + PluginDebug.debug("wait request 2"); + while ((Long) request.getObject() == 0) + request.wait(); + PluginDebug.debug("wait request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", e); - } - - PluginDebug.debug ("STARTING getWindow DONE"); - return (Long) request.getObject(); - } - - // FIXME: make private, access via reflection. - public static Object getMember(long internal, String name) - { - AppletSecurityContextManager.getSecurityContext(0).store(name); - int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); - Long reference = getRequestIdentifier(); - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("member", - "instance " + 0 + " reference " + reference + " GetMember " + - internal + " " + nameID, reference); - - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait getMEM request 1"); - synchronized(request) { - PluginDebug.debug ("wait getMEM request 2"); - while (request.isDone() == false) - request.wait(); - PluginDebug.debug ("wait getMEM request 3 GOT: " + request.getObject().getClass()); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", + } + + PluginDebug.debug("STARTING getWindow DONE"); + return (Long) request.getObject(); + } + + // FIXME: make private, access via reflection. + public static Object getMember(long internal, String name) { + AppletSecurityContextManager.getSecurityContext(0).store(name); + int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); + Long reference = getRequestIdentifier(); + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("member", + "instance " + 0 + " reference " + reference + " GetMember " + + internal + " " + nameID, reference); + + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait getMEM request 1"); + synchronized (request) { + PluginDebug.debug("wait getMEM request 2"); + while (request.isDone() == false) + request.wait(); + PluginDebug.debug("wait getMEM request 3 GOT: " + request.getObject().getClass()); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", e); - } - PluginDebug.debug (" getMember DONE"); - return request.getObject(); - } - - public static void setMember(long internal, String name, Object value) { - System.err.println("Setting to class " + value.getClass() + ":" + value.getClass().isPrimitive()); - AppletSecurityContextManager.getSecurityContext(0).store(name); - int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); - Long reference = getRequestIdentifier(); - - // work on a copy of value, as we don't want to be manipulating - // complex objects - String valueToSetTo; - if (value instanceof java.lang.Byte || - value instanceof java.lang.Character || - value instanceof java.lang.Short || - value instanceof java.lang.Integer || - value instanceof java.lang.Long || - value instanceof java.lang.Float || - value instanceof java.lang.Double || - value instanceof java.lang.Boolean) { - - valueToSetTo = "literalreturn " + value.toString(); - - // Character -> Str results in str value.. we need int value as - // per specs. - if (value instanceof java.lang.Character) { - valueToSetTo = "literalreturn " + (int) ((java.lang.Character) value).charValue(); - } else if (value instanceof Float || + } + PluginDebug.debug(" getMember DONE"); + return request.getObject(); + } + + public static void setMember(long internal, String name, Object value) { + System.err.println("Setting to class " + value.getClass() + ":" + value.getClass().isPrimitive()); + AppletSecurityContextManager.getSecurityContext(0).store(name); + int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); + Long reference = getRequestIdentifier(); + + // work on a copy of value, as we don't want to be manipulating + // complex objects + String valueToSetTo; + if (value instanceof java.lang.Byte || + value instanceof java.lang.Character || + value instanceof java.lang.Short || + value instanceof java.lang.Integer || + value instanceof java.lang.Long || + value instanceof java.lang.Float || + value instanceof java.lang.Double || + value instanceof java.lang.Boolean) { + + valueToSetTo = "literalreturn " + value.toString(); + + // Character -> Str results in str value.. we need int value as + // per specs. + if (value instanceof java.lang.Character) { + valueToSetTo = "literalreturn " + (int) ((java.lang.Character) value).charValue(); + } else if (value instanceof Float || value instanceof Double) { - valueToSetTo = "literalreturn " + String.format("%308.308e", value); - } + valueToSetTo = "literalreturn " + String.format("%308.308e", value); + } - } else { - AppletSecurityContextManager.getSecurityContext(0).store(value); - valueToSetTo = Integer.toString(AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value)); - } - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("void", - "instance " + 0 + " reference " + reference + " SetMember " + - internal + " " + nameID + " " + valueToSetTo, reference); - - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait setMem request: " + request.getMessage()); - PluginDebug.debug ("wait setMem request 1"); - synchronized(request) { - PluginDebug.debug ("wait setMem request 2"); - while (request.isDone() == false) - request.wait(); - PluginDebug.debug ("wait setMem request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", + } else { + AppletSecurityContextManager.getSecurityContext(0).store(value); + valueToSetTo = Integer.toString(AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value)); + } + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("void", + "instance " + 0 + " reference " + reference + " SetMember " + + internal + " " + nameID + " " + valueToSetTo, reference); + + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait setMem request: " + request.getMessage()); + PluginDebug.debug("wait setMem request 1"); + synchronized (request) { + PluginDebug.debug("wait setMem request 2"); + while (request.isDone() == false) + request.wait(); + PluginDebug.debug("wait setMem request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", e); - } - PluginDebug.debug (" setMember DONE"); - } - - // FIXME: handle long index as well. - public static void setSlot(long internal, int index, Object value) { - AppletSecurityContextManager.getSecurityContext(0).store(value); - Long reference = getRequestIdentifier(); - - // work on a copy of value, as we don't want to be manipulating - // complex objects - String valueToSetTo; - if (value instanceof java.lang.Byte || - value instanceof java.lang.Character || - value instanceof java.lang.Short || - value instanceof java.lang.Integer || - value instanceof java.lang.Long || - value instanceof java.lang.Float || - value instanceof java.lang.Double || - value instanceof java.lang.Boolean) { - - valueToSetTo = "literalreturn " + value.toString(); - - // Character -> Str results in str value.. we need int value as - // per specs. - if (value instanceof java.lang.Character) { - valueToSetTo = "literalreturn " + (int) ((java.lang.Character) value).charValue(); - } else if (value instanceof Float || + } + PluginDebug.debug(" setMember DONE"); + } + + // FIXME: handle long index as well. + public static void setSlot(long internal, int index, Object value) { + AppletSecurityContextManager.getSecurityContext(0).store(value); + Long reference = getRequestIdentifier(); + + // work on a copy of value, as we don't want to be manipulating + // complex objects + String valueToSetTo; + if (value instanceof java.lang.Byte || + value instanceof java.lang.Character || + value instanceof java.lang.Short || + value instanceof java.lang.Integer || + value instanceof java.lang.Long || + value instanceof java.lang.Float || + value instanceof java.lang.Double || + value instanceof java.lang.Boolean) { + + valueToSetTo = "literalreturn " + value.toString(); + + // Character -> Str results in str value.. we need int value as + // per specs. + if (value instanceof java.lang.Character) { + valueToSetTo = "literalreturn " + (int) ((java.lang.Character) value).charValue(); + } else if (value instanceof Float || value instanceof Double) { - valueToSetTo = "literalreturn " + String.format("%308.308e", value); - } + valueToSetTo = "literalreturn " + String.format("%308.308e", value); + } - } else { - AppletSecurityContextManager.getSecurityContext(0).store(value); - valueToSetTo = Integer.toString(AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value)); - } - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("void", - "instance " + 0 + " reference " + reference + " SetSlot " + - internal + " " + index + " " + valueToSetTo, reference); - - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait setSlot request 1"); - synchronized(request) { - PluginDebug.debug ("wait setSlot request 2"); - while (request.isDone() == false) - request.wait(); - PluginDebug.debug ("wait setSlot request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", + } else { + AppletSecurityContextManager.getSecurityContext(0).store(value); + valueToSetTo = Integer.toString(AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value)); + } + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("void", + "instance " + 0 + " reference " + reference + " SetSlot " + + internal + " " + index + " " + valueToSetTo, reference); + + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait setSlot request 1"); + synchronized (request) { + PluginDebug.debug("wait setSlot request 2"); + while (request.isDone() == false) + request.wait(); + PluginDebug.debug("wait setSlot request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", e); - } - PluginDebug.debug (" setSlot DONE"); - } - - public static Object getSlot(long internal, int index) - { - Long reference = getRequestIdentifier(); - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("member", - "instance " + 0 + " reference " + reference + " GetSlot " + - internal + " " + index, reference); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait getSlot request 1"); - synchronized(request) { - PluginDebug.debug ("wait getSlot request 2"); - while (request.isDone() == false) - request.wait(); - PluginDebug.debug ("wait getSlot request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", + } + PluginDebug.debug(" setSlot DONE"); + } + + public static Object getSlot(long internal, int index) { + Long reference = getRequestIdentifier(); + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("member", + "instance " + 0 + " reference " + reference + " GetSlot " + + internal + " " + index, reference); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait getSlot request 1"); + synchronized (request) { + PluginDebug.debug("wait getSlot request 2"); + while (request.isDone() == false) + request.wait(); + PluginDebug.debug("wait getSlot request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", e); - } - PluginDebug.debug (" getSlot DONE"); - return request.getObject(); - } - - public static Object eval(long internal, String s) - { - AppletSecurityContextManager.getSecurityContext(0).store(s); - int stringID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(s); - Long reference = getRequestIdentifier(); - - // Prefix with dummy instance for convenience. - // FIXME: rename GetMemberPluginCallRequest ObjectPluginCallRequest. - PluginCallRequest request = requestFactory.getPluginCallRequest("member", - "instance " + 0 + " reference " + reference + " Eval " + - internal + " " + stringID, reference); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait eval request 1"); - synchronized(request) { - PluginDebug.debug ("wait eval request 2"); - while (request.isDone() == false) - request.wait(); - PluginDebug.debug ("wait eval request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", + } + PluginDebug.debug(" getSlot DONE"); + return request.getObject(); + } + + public static Object eval(long internal, String s) { + AppletSecurityContextManager.getSecurityContext(0).store(s); + int stringID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(s); + Long reference = getRequestIdentifier(); + + // Prefix with dummy instance for convenience. + // FIXME: rename GetMemberPluginCallRequest ObjectPluginCallRequest. + PluginCallRequest request = requestFactory.getPluginCallRequest("member", + "instance " + 0 + " reference " + reference + " Eval " + + internal + " " + stringID, reference); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait eval request 1"); + synchronized (request) { + PluginDebug.debug("wait eval request 2"); + while (request.isDone() == false) + request.wait(); + PluginDebug.debug("wait eval request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", e); - } - PluginDebug.debug (" getSlot DONE"); - return request.getObject(); - } - - public static void removeMember (long internal, String name) { - AppletSecurityContextManager.getSecurityContext(0).store(name); - int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); - Long reference = getRequestIdentifier(); - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("void", - "instance " + 0 + " reference " + reference + " RemoveMember " + - internal + " " + nameID, reference); - - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait removeMember request 1"); - synchronized(request) { - PluginDebug.debug ("wait removeMember request 2"); - while (request.isDone() == false) - request.wait(); - PluginDebug.debug ("wait removeMember request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", + } + PluginDebug.debug(" getSlot DONE"); + return request.getObject(); + } + + public static void removeMember(long internal, String name) { + AppletSecurityContextManager.getSecurityContext(0).store(name); + int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); + Long reference = getRequestIdentifier(); + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("void", + "instance " + 0 + " reference " + reference + " RemoveMember " + + internal + " " + nameID, reference); + + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait removeMember request 1"); + synchronized (request) { + PluginDebug.debug("wait removeMember request 2"); + while (request.isDone() == false) + request.wait(); + PluginDebug.debug("wait removeMember request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", e); - } - PluginDebug.debug (" RemoveMember DONE"); - } - - public static Object call(long internal, String name, Object args[]) - { - // FIXME: when is this removed from the object store? - // FIXME: reference should return the ID. - // FIXME: convenience method for this long line. - AppletSecurityContextManager.getSecurityContext(0).store(name); - int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); - Long reference = getRequestIdentifier(); - - String argIDs = ""; - for (Object arg : args) - { - AppletSecurityContextManager.getSecurityContext(0).store(arg); - argIDs += AppletSecurityContextManager.getSecurityContext(0).getIdentifier(arg) + " "; - } - argIDs = argIDs.trim(); - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("member", - "instance " + 0 + " reference " + reference + " Call " + - internal + " " + nameID + " " + argIDs, reference); - - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait call request 1"); - synchronized(request) { - PluginDebug.debug ("wait call request 2"); - while (request.isDone() == false) - request.wait(); - PluginDebug.debug ("wait call request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", + } + PluginDebug.debug(" RemoveMember DONE"); + } + + public static Object call(long internal, String name, Object args[]) { + // FIXME: when is this removed from the object store? + // FIXME: reference should return the ID. + // FIXME: convenience method for this long line. + AppletSecurityContextManager.getSecurityContext(0).store(name); + int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); + Long reference = getRequestIdentifier(); + + String argIDs = ""; + for (Object arg : args) { + AppletSecurityContextManager.getSecurityContext(0).store(arg); + argIDs += AppletSecurityContextManager.getSecurityContext(0).getIdentifier(arg) + " "; + } + argIDs = argIDs.trim(); + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("member", + "instance " + 0 + " reference " + reference + " Call " + + internal + " " + nameID + " " + argIDs, reference); + + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait call request 1"); + synchronized (request) { + PluginDebug.debug("wait call request 2"); + while (request.isDone() == false) + request.wait(); + PluginDebug.debug("wait call request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", e); - } - PluginDebug.debug (" Call DONE"); - return request.getObject(); - } + } + PluginDebug.debug(" Call DONE"); + return request.getObject(); + } - public static Object requestPluginCookieInfo(URI uri) { + public static Object requestPluginCookieInfo(URI uri) { - PluginCallRequest request; - Long reference = getRequestIdentifier(); + PluginCallRequest request; + Long reference = getRequestIdentifier(); - try - { - String encodedURI = UrlUtil.encode(uri.toString(), "UTF-8"); - request = requestFactory.getPluginCallRequest("cookieinfo", - "plugin PluginCookieInfo " + "reference " + reference + - " " + encodedURI, reference); + try { + String encodedURI = UrlUtil.encode(uri.toString(), "UTF-8"); + request = requestFactory.getPluginCallRequest("cookieinfo", + "plugin PluginCookieInfo " + "reference " + reference + + " " + encodedURI, reference); + + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return null; + } - } catch (UnsupportedEncodingException e) - { - e.printStackTrace(); - return null; - } - - PluginMessageConsumer.registerPriorityWait(reference); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait cookieinfo request 1"); - synchronized(request) { - PluginDebug.debug ("wait cookieinfo request 2"); - while (request.isDone() == false) - request.wait(); - PluginDebug.debug ("wait cookieinfo request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for cookieinfo request.", - e); - } - PluginDebug.debug (" Cookieinfo DONE"); - return request.getObject(); - } - - public static Object requestPluginProxyInfo(URI uri) { - - String requestURI = null; - Long reference = getRequestIdentifier(); - - try { - - // there is no easy way to get SOCKS proxy info. So, we tell mozilla that we want proxy for - // an HTTP uri in case of non http/ftp protocols. If we get back a SOCKS proxy, we can - // use that, if we get back an http proxy, we fallback to DIRECT connect - - String scheme = uri.getScheme(); - String port = uri.getPort() != -1 ? ":" + uri.getPort() : ""; - if (!uri.getScheme().startsWith("http") && !uri.getScheme().equals("ftp")) - scheme = "http"; - - requestURI = UrlUtil.encode(scheme + "://" + uri.getHost() + port + "/" + uri.getPath(), "UTF-8"); - } catch (Exception e) { - PluginDebug.debug("Cannot construct URL from " + uri.toString() + " ... falling back to DIRECT proxy"); - e.printStackTrace(); - return null; - } - - PluginCallRequest request = requestFactory.getPluginCallRequest("proxyinfo", - "plugin PluginProxyInfo reference " + reference + " " + - requestURI, reference); - - PluginMessageConsumer.registerPriorityWait(reference); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait call request 1"); - synchronized(request) { - PluginDebug.debug ("wait call request 2"); - while (request.isDone() == false) - request.wait(); - PluginDebug.debug ("wait call request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", + PluginMessageConsumer.registerPriorityWait(reference); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait cookieinfo request 1"); + synchronized (request) { + PluginDebug.debug("wait cookieinfo request 2"); + while (request.isDone() == false) + request.wait(); + PluginDebug.debug("wait cookieinfo request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for cookieinfo request.", e); - } - PluginDebug.debug (" Call DONE"); - return request.getObject(); - } - - public static void JavaScriptFinalize(long internal) - { - Long reference = getRequestIdentifier(); - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("void", - "instance " + 0 + " reference " + reference + " Finalize " + - internal, reference); - - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait finalize request 1"); - synchronized(request) { - PluginDebug.debug ("wait finalize request 2"); - while (request.isDone() == false) - request.wait(); - PluginDebug.debug ("wait finalize request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", + } + PluginDebug.debug(" Cookieinfo DONE"); + return request.getObject(); + } + + public static Object requestPluginProxyInfo(URI uri) { + + String requestURI = null; + Long reference = getRequestIdentifier(); + + try { + + // there is no easy way to get SOCKS proxy info. So, we tell mozilla that we want proxy for + // an HTTP uri in case of non http/ftp protocols. If we get back a SOCKS proxy, we can + // use that, if we get back an http proxy, we fallback to DIRECT connect + + String scheme = uri.getScheme(); + String port = uri.getPort() != -1 ? ":" + uri.getPort() : ""; + if (!uri.getScheme().startsWith("http") && !uri.getScheme().equals("ftp")) + scheme = "http"; + + requestURI = UrlUtil.encode(scheme + "://" + uri.getHost() + port + "/" + uri.getPath(), "UTF-8"); + } catch (Exception e) { + PluginDebug.debug("Cannot construct URL from " + uri.toString() + " ... falling back to DIRECT proxy"); + e.printStackTrace(); + return null; + } + + PluginCallRequest request = requestFactory.getPluginCallRequest("proxyinfo", + "plugin PluginProxyInfo reference " + reference + " " + + requestURI, reference); + + PluginMessageConsumer.registerPriorityWait(reference); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait call request 1"); + synchronized (request) { + PluginDebug.debug("wait call request 2"); + while (request.isDone() == false) + request.wait(); + PluginDebug.debug("wait call request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", e); - } - PluginDebug.debug (" finalize DONE"); - } - - public static String javascriptToString(long internal) - { - Long reference = getRequestIdentifier(); - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("member", - "instance " + 0 + " reference " + reference + " ToString " + - internal, reference); - - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - PluginDebug.debug ("wait ToString request 1"); - synchronized(request) { - PluginDebug.debug ("wait ToString request 2"); - while (request.isDone() == false) - request.wait(); - PluginDebug.debug ("wait ToString request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", + } + PluginDebug.debug(" Call DONE"); + return request.getObject(); + } + + public static void JavaScriptFinalize(long internal) { + Long reference = getRequestIdentifier(); + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("void", + "instance " + 0 + " reference " + reference + " Finalize " + + internal, reference); + + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait finalize request 1"); + synchronized (request) { + PluginDebug.debug("wait finalize request 2"); + while (request.isDone() == false) + request.wait(); + PluginDebug.debug("wait finalize request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", e); - } - PluginDebug.debug (" ToString DONE"); - return (String) request.getObject(); - } - - // FIXME: make this private and access it from JSObject using - // reflection. - private void write(String message) throws IOException { - PluginDebug.debug ("WRITING 2: " + "instance " + identifier + " " + message); - streamhandler.write("instance " + identifier + " " + message); - PluginDebug.debug ("WRITING 2 DONE"); - } - - public void setStream(String key, InputStream stream)throws IOException{ - // We do nothing. - } - - @Override - public InputStream getStream(String key){ - // We do nothing. - return null; - } - - @Override - public Iterator<String> getStreamKeys(){ - // We do nothing. - return null; - } - - /** - * System parameters. - */ - static Hashtable<String,String> systemParam = new Hashtable<String,String>(); - - 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. - */ - public static void printTag(PrintStream out, Hashtable<String,String> atts) { - out.print("<applet"); - - String v = atts.get("codebase"); - if (v != null) { - out.print(" codebase=\"" + v + "\""); - } - - v = atts.get("code"); - if (v == null) { - v = "applet.class"; - } - out.print(" code=\"" + v + "\""); - v = atts.get("width"); - if (v == null) { - v = "150"; - } - out.print(" width=" + v); - - v = atts.get("height"); - if (v == null) { - v = "100"; - } - out.print(" height=" + v); - - v = 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<String> e = atts.keys() ; e.hasMoreElements() ;) { - String param = e.nextElement(); - int i = 0; - for (; i < len ; i++) { - if (params[i].compareTo(param) >= 0) { - break; + } + PluginDebug.debug(" finalize DONE"); + } + + public static String javascriptToString(long internal) { + Long reference = getRequestIdentifier(); + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("member", + "instance " + 0 + " reference " + reference + " ToString " + + internal, reference); + + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + PluginDebug.debug("wait ToString request 1"); + synchronized (request) { + PluginDebug.debug("wait ToString request 2"); + while (request.isDone() == false) + request.wait(); + PluginDebug.debug("wait ToString request 3"); } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", + e); } - System.arraycopy(params, i, params, i + 1, len - i); - params[i] = param; - len++; + PluginDebug.debug(" ToString DONE"); + return (String) request.getObject(); + } + + // FIXME: make this private and access it from JSObject using + // reflection. + private void write(String message) throws IOException { + PluginDebug.debug("WRITING 2: " + "instance " + identifier + " " + message); + streamhandler.write("instance " + identifier + " " + message); + PluginDebug.debug("WRITING 2 DONE"); + } + + public void setStream(String key, InputStream stream) throws IOException { + // We do nothing. + } + + @Override + public InputStream getStream(String key) { + // We do nothing. + return null; + } + + @Override + public Iterator<String> getStreamKeys() { + // We do nothing. + return null; } - 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) + "\">"); + /** + * System parameters. + */ + static Hashtable<String, String> systemParam = new Hashtable<String, String>(); + + 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. + */ + public static void printTag(PrintStream out, Hashtable<String, String> atts) { + out.print("<applet"); + + String v = atts.get("codebase"); + if (v != null) { + out.print(" codebase=\"" + v + "\""); + } + + v = atts.get("code"); + if (v == null) { + v = "applet.class"; + } + out.print(" code=\"" + v + "\""); + v = atts.get("width"); + if (v == null) { + v = "150"; + } + out.print(" width=" + v); + + v = atts.get("height"); + if (v == null) { + v = "100"; + } + out.print(" height=" + v); + + v = 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<String> e = atts.keys(); e.hasMoreElements();) { + String param = 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>"); } - out.println("</applet>"); - } - /** - * Make sure the atrributes are uptodate. - */ + /** + * Make sure the atrributes are uptodate. + */ public void updateAtts() { Dimension d = panel.getSize(); Insets in = panel.getInsets(); @@ -1557,100 +1540,100 @@ import com.sun.jndi.toolkit.url.UrlUtil; Integer.valueOf(d.width - (in.left + in.right)).toString()); panel.atts.put("height", Integer.valueOf(d.height - (in.top + in.bottom)).toString()); - } - - /** - * 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. - */ - 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] + * Restart the applet. */ - 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 - } - - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - panel.createAppletThread(); - return null; - } - }); - - panel.sendEvent(AppletPanel.APPLET_LOAD); - panel.sendEvent(AppletPanel.APPLET_INIT); - panel.sendEvent(AppletPanel.APPLET_START); - } - - public int print(Graphics graphics, PageFormat pf, int pageIndex) { - return Printable.NO_SUCH_PAGE; - } - - /** - * Start the applet. - */ - void appletStart() { - panel.sendEvent(AppletPanel.APPLET_START); - } - - /** - * Stop the applet. - */ - void appletStop() { - panel.sendEvent(AppletPanel.APPLET_STOP); - } - - /** - * 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. - */ - 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() + 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. + */ + 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 + } + + AccessController.doPrivileged(new PrivilegedAction<Void>() { + public Void run() { + panel.createAppletThread(); + return null; + } + }); + + panel.sendEvent(AppletPanel.APPLET_LOAD); + panel.sendEvent(AppletPanel.APPLET_INIT); + panel.sendEvent(AppletPanel.APPLET_START); + } + + public int print(Graphics graphics, PageFormat pf, int pageIndex) { + return Printable.NO_SUCH_PAGE; + } + + /** + * Start the applet. + */ + void appletStart() { + panel.sendEvent(AppletPanel.APPLET_START); + } + + /** + * Stop the applet. + */ + void appletStop() { + panel.sendEvent(AppletPanel.APPLET_STOP); + } + + /** + * 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. + */ + 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() { @@ -1661,7 +1644,7 @@ import com.sun.jndi.toolkit.url.UrlUtil; dispose(); if (tg.activeCount() > 0) - tg.stop(); + tg.stop(); if (countApplets() == 0) { appletSystemExit(); @@ -1671,497 +1654,490 @@ import com.sun.jndi.toolkit.url.UrlUtil; } }).start(); - } - - /** - * Exit the program. - * Exit from the program (if not stand alone) - do no clean-up - */ - private void appletSystemExit() { - // Do nothing. Exit is handled by another - // block of code, called when _all_ applets are gone - } - - /** - * How many applets are running? - */ - - public static int countApplets() { - return appletPanels.size(); - } - - - /** - * Scan spaces. - */ - public static void skipSpace(int[] c, Reader in) throws IOException { - while ((c[0] >= 0) && - ((c[0] == ' ') || (c[0] == '\t') || (c[0] == '\n') || (c[0] == '\r'))) { - c[0] = in.read(); - } - } - - /** - * Scan identifier - */ - public static String scanIdentifier(int[] c, Reader in) throws IOException { - StringBuilder buf = new StringBuilder(); - - if (c[0] == '!') { - // Technically, we should be scanning for '!--' but we are reading - // from a stream, and there is no way to peek ahead. That said, - // a ! at this point can only mean comment here afaik, so we - // should be okay - skipComment(c, in); - return ""; - } - - while (true) { - if (((c[0] >= 'a') && (c[0] <= 'z')) || - ((c[0] >= 'A') && (c[0] <= 'Z')) || - ((c[0] >= '0') && (c[0] <= '9')) || (c[0] == '_')) { - buf.append((char)c[0]); - c[0] = in.read(); - } else { - return buf.toString(); - } - } - } - - public static void skipComment(int[] c, Reader in) throws IOException { - StringBuilder buf = new StringBuilder(); - boolean commentHeaderPassed = false; - c[0] = in.read(); - buf.append((char)c[0]); - - while (true) { - if (c[0] == '-' && (c[0] = in.read()) == '-') { - buf.append((char)c[0]); - if (commentHeaderPassed) { - // -- encountered ... is > next? - if ((c[0] = in.read()) == '>') { - buf.append((char)c[0]); - - PluginDebug.debug("Comment skipped: " + buf.toString()); - - // comment skipped. - return; - } - } else { - // first -- is part of <!-- ... , just mark that we have passed it - commentHeaderPassed = true; - } + } - } else if (commentHeaderPassed == false) { - buf.append((char)c[0]); - PluginDebug.debug("Warning: Attempted to skip comment, but this tag does not appear to be a comment: " + buf.toString()); - return; - } + /** + * Exit the program. + * Exit from the program (if not stand alone) - do no clean-up + */ + private void appletSystemExit() { + // Do nothing. Exit is handled by another + // block of code, called when _all_ applets are gone + } - c[0] = in.read(); - buf.append((char)c[0]); - } - } - - /** - * Scan tag - */ - public static Hashtable<String,String> scanTag(int[] c, Reader in) throws IOException { - Hashtable<String,String> atts = new Hashtable<String,String>(); - skipSpace(c, in); - while (c[0] >= 0 && c[0] != '>') { - String att = scanIdentifier(c, in); - String val = ""; - skipSpace(c, in); - if (c[0] == '=') { - int quote = -1; - c[0] = in.read(); - skipSpace(c, in); - if ((c[0] == '\'') || (c[0] == '\"')) { - quote = c[0]; - c[0] = in.read(); - } - StringBuilder buf = new StringBuilder(); - while ((c[0] > 0) && + /** + * How many applets are running? + */ + + public static int countApplets() { + return appletPanels.size(); + } + + /** + * Scan spaces. + */ + public static void skipSpace(int[] c, Reader in) throws IOException { + while ((c[0] >= 0) && + ((c[0] == ' ') || (c[0] == '\t') || (c[0] == '\n') || (c[0] == '\r'))) { + c[0] = in.read(); + } + } + + /** + * Scan identifier + */ + public static String scanIdentifier(int[] c, Reader in) throws IOException { + StringBuilder buf = new StringBuilder(); + + if (c[0] == '!') { + // Technically, we should be scanning for '!--' but we are reading + // from a stream, and there is no way to peek ahead. That said, + // a ! at this point can only mean comment here afaik, so we + // should be okay + skipComment(c, in); + return ""; + } + + while (true) { + if (((c[0] >= 'a') && (c[0] <= 'z')) || + ((c[0] >= 'A') && (c[0] <= 'Z')) || + ((c[0] >= '0') && (c[0] <= '9')) || (c[0] == '_')) { + buf.append((char) c[0]); + c[0] = in.read(); + } else { + return buf.toString(); + } + } + } + + public static void skipComment(int[] c, Reader in) throws IOException { + StringBuilder buf = new StringBuilder(); + boolean commentHeaderPassed = false; + c[0] = in.read(); + buf.append((char) c[0]); + + while (true) { + if (c[0] == '-' && (c[0] = in.read()) == '-') { + buf.append((char) c[0]); + if (commentHeaderPassed) { + // -- encountered ... is > next? + if ((c[0] = in.read()) == '>') { + buf.append((char) c[0]); + + PluginDebug.debug("Comment skipped: " + buf.toString()); + + // comment skipped. + return; + } + } else { + // first -- is part of <!-- ... , just mark that we have passed it + commentHeaderPassed = true; + } + + } else if (commentHeaderPassed == false) { + buf.append((char) c[0]); + PluginDebug.debug("Warning: Attempted to skip comment, but this tag does not appear to be a comment: " + buf.toString()); + return; + } + + c[0] = in.read(); + buf.append((char) c[0]); + } + } + + /** + * Scan tag + */ + public static Hashtable<String, String> scanTag(int[] c, Reader in) throws IOException { + Hashtable<String, String> atts = new Hashtable<String, String>(); + skipSpace(c, in); + while (c[0] >= 0 && c[0] != '>') { + String att = scanIdentifier(c, in); + String val = ""; + skipSpace(c, in); + if (c[0] == '=') { + int quote = -1; + c[0] = in.read(); + skipSpace(c, in); + if ((c[0] == '\'') || (c[0] == '\"')) { + quote = c[0]; + c[0] = in.read(); + } + StringBuilder buf = new StringBuilder(); + while ((c[0] > 0) && (((quote < 0) && (c[0] != ' ') && (c[0] != '\t') && - (c[0] != '\n') && (c[0] != '\r') && (c[0] != '>')) + (c[0] != '\n') && (c[0] != '\r') && (c[0] != '>')) || ((quote >= 0) && (c[0] != quote)))) { - buf.append((char)c[0]); - c[0] = in.read(); - } - if (c[0] == quote) { - c[0] = in.read(); - } - skipSpace(c, in); - val = buf.toString(); - } + buf.append((char) c[0]); + c[0] = in.read(); + } + if (c[0] == quote) { + c[0] = in.read(); + } + skipSpace(c, in); + val = buf.toString(); + } - PluginDebug.debug("PUT " + att + " = '" + val + "'"); - atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val); + PluginDebug.debug("PUT " + att + " = '" + val + "'"); + atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val); - while (true) { - if ((c[0] == '>') || (c[0] < 0) || - ((c[0] >= 'a') && (c[0] <= 'z')) || - ((c[0] >= 'A') && (c[0] <= 'Z')) || - ((c[0] >= '0') && (c[0] <= '9')) || (c[0] == '_')) - break; - c[0] = in.read(); - } - //skipSpace(in); - } - return atts; - } - - // private static final == inline - private static final boolean isInt(Object o) { - boolean isInt = false; - try { - Integer.parseInt((String) o); - isInt = true; - } catch (Exception e) { - // don't care - } - - return isInt; - } - - /* 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) { + while (true) { + if ((c[0] == '>') || (c[0] < 0) || + ((c[0] >= 'a') && (c[0] <= 'z')) || + ((c[0] >= 'A') && (c[0] <= 'Z')) || + ((c[0] >= '0') && (c[0] <= '9')) || (c[0] == '_')) + break; + c[0] = in.read(); + } + //skipSpace(in); + } + return atts; + } + + // private static final == inline + private static final boolean isInt(Object o) { + boolean isInt = false; 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 <applet> tags - */ - public static void parse(int identifier, long handle, String width, String height, Reader in, URL url, String enc) - throws IOException { - encoding = enc; - parse(identifier, handle, width, height, in, url, System.out, new PluginAppletPanelFactory()); - } - - public static void parse(int identifier, long handle, String width, String height, Reader in, URL url) - throws PrivilegedActionException { - - final int fIdentifier = identifier; - final long fHandle = handle; - final String fWidth = width; - final String fHeight = height; - final Reader fIn = in; - final URL fUrl = url; - AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { - public Void run() throws IOException { - parse(fIdentifier, fHandle, fWidth, fHeight, fIn, fUrl, - System.out, new PluginAppletPanelFactory()); - return null; - } - }); - } + Integer.parseInt((String) o); + isInt = true; + } catch (Exception e) { + // don't care + } + + return isInt; + } + + /* 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; - public static void parse(int identifier, long handle, String width, + 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 <applet> tags + */ + public static void parse(int identifier, long handle, String width, String height, Reader in, URL url, String enc) + throws IOException { + encoding = enc; + parse(identifier, handle, width, height, in, url, System.out, new PluginAppletPanelFactory()); + } + + public static void parse(int identifier, long handle, String width, String height, Reader in, URL url) + throws PrivilegedActionException { + + final int fIdentifier = identifier; + final long fHandle = handle; + final String fWidth = width; + final String fHeight = height; + final Reader fIn = in; + final URL fUrl = url; + AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { + public Void run() throws IOException { + parse(fIdentifier, fHandle, fWidth, fHeight, fIn, fUrl, + System.out, new PluginAppletPanelFactory()); + return null; + } + }); + } + + public static void parse(int identifier, long handle, String width, String height, Reader in, URL url, PrintStream statusMsgStream, PluginAppletPanelFactory factory) - throws IOException - { - // <OBJECT> <EMBED> tag flags - boolean isAppletTag = false; - boolean isObjectTag = false; - boolean isEmbedTag = false; - boolean objectTagAlreadyParsed = false; - - // The current character - // FIXME: This is an evil hack to force pass-by-reference.. the - // parsing code needs to be rewritten from scratch to prevent such - //a need - int[] c = new int[1]; - - // 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(); - /* 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<String,String> atts = null; - - while(true) { - c[0] = in.read(); - if (c[0] == -1) - break; - - if (c[0] == '<') { - c[0] = in.read(); - if (c[0] == '/') { - c[0] = in.read(); - String nm = scanIdentifier(c, in); - if (nm.equalsIgnoreCase("applet") || + throws IOException { + // <OBJECT> <EMBED> tag flags + boolean isAppletTag = false; + boolean isObjectTag = false; + boolean isEmbedTag = false; + boolean objectTagAlreadyParsed = false; + + // The current character + // FIXME: This is an evil hack to force pass-by-reference.. the + // parsing code needs to be rewritten from scratch to prevent such + //a need + int[] c = new int[1]; + + // 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(); + /* 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<String, String> atts = null; + + while (true) { + c[0] = in.read(); + if (c[0] == -1) + break; + + if (c[0] == '<') { + c[0] = in.read(); + if (c[0] == '/') { + c[0] = in.read(); + String nm = scanIdentifier(c, 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. - - // Let user know we are starting up - streamhandler.write("instance " + identifier + " status " + amh.getMessage("status.start")); - factory.createPanel(streamhandler, identifier, handle, 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(c, in); - if (nm.equalsIgnoreCase("param")) { - Hashtable<String,String> t = scanTag(c, in); - String att = t.get("name"); - - if (atts.containsKey(att)) - continue; - - if (att == null) { - statusMsgStream.println(requiresNameWarning); - } else { - String val = t.get("value"); - if (val == null) { - statusMsgStream.println(requiresNameWarning); - } else if (atts != null) { - PluginDebug.debug("PUT " + att + " = " + val); - atts.put(att.toLowerCase(), val); - } else { - statusMsgStream.println(paramOutsideWarning); - } - } - } - else if (nm.equalsIgnoreCase("applet")) { - isAppletTag = true; - atts = scanTag(c, in); - - // If there is a classid and no code tag present, transform it to code tag - if (atts.get("code") == null && atts.get("classid") != null - && !(atts.get("classid")).startsWith("clsid:")) { - atts.put("code", atts.get("classid")); - } - - // remove java: from code tag - if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) { - atts.put("code", (atts.get("code")).substring(5)); - } - - if (atts.get("code") == null && atts.get("object") == null) { - statusMsgStream.println(appletRequiresCodeWarning); - atts = null; - } - - if (atts.get("width") == null || !isInt(atts.get("width"))) { - atts.put("width", width); - } - - if (atts.get("height") == null || !isInt(atts.get("height"))) { - atts.put("height", height); - } - } - else if (nm.equalsIgnoreCase("object")) { - isObjectTag = true; - - // Once code is set, additional nested objects are ignored - if (!objectTagAlreadyParsed) { - objectTagAlreadyParsed = true; - atts = scanTag(c, in); - } - - // If there is a classid and no code tag present, transform it to code tag - if (atts.get("code") == null && atts.get("classid") != null - && !(atts.get("classid")).startsWith("clsid:")) { - atts.put("code", atts.get("classid")); - } - - // remove java: from code tag - if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) { - atts.put("code", (atts.get("code")).substring(5)); - } - - // java_* aliases override older names: - // http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/using_tags.html#in-ie - if (atts.get("java_code") != null) { - atts.put("code", (atts.get("java_code"))); - } - - if (atts.containsKey("code")) { - objectTagAlreadyParsed = true; - } - - if (atts.get("java_codebase") != null) { - atts.put("codebase", (atts.get("java_codebase"))); - } - - if (atts.get("java_archive") != null) { - atts.put("archive", (atts.get("java_archive"))); - } - - if (atts.get("java_object") != null) { - atts.put("object", (atts.get("java_object"))); - } - - if (atts.get("java_type") != null) { - atts.put("type", (atts.get("java_type"))); - } - - if (atts.get("width") == null || !isInt(atts.get("width"))) { - atts.put("width", width); - } - - if (atts.get("height") == null || !isInt(atts.get("height"))) { - atts.put("height", height); - } - } - else if (nm.equalsIgnoreCase("embed")) { - isEmbedTag = true; - atts = scanTag(c, in); - - // If there is a classid and no code tag present, transform it to code tag - if (atts.get("code") == null && atts.get("classid") != null - && !(atts.get("classid")).startsWith("clsid:")) { - atts.put("code", atts.get("classid")); - } - - // remove java: from code tag - if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) { - atts.put("code", (atts.get("code")).substring(5)); - } - - // java_* aliases override older names: - // http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/using_tags.html#in-nav - if (atts.get("java_code") != null) { - atts.put("code", (atts.get("java_code"))); - } - - if (atts.get("java_codebase") != null) { - atts.put("codebase", (atts.get("java_codebase"))); - } - - if (atts.get("java_archive") != null) { - atts.put("archive", (atts.get("java_archive"))); - } - - if (atts.get("java_object") != null) { - atts.put("object", (atts.get("java_object"))); - } - - if (atts.get("java_type") != null) { - atts.put("type", (atts.get("java_type"))); - } - - if (atts.get("code") == null && atts.get("object") == null) { - statusMsgStream.println(embedRequiresCodeWarning); - atts = null; - } - - if (atts.get("width") == null || !isInt(atts.get("width"))) { - atts.put("width", width); - } - - if (atts.get("height") == null || !isInt(atts.get("height"))) { - atts.put("height", height); - } - - } - } - } - } - in.close(); - } - + // 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; + } + } - private static AppletMessageHandler amh = new AppletMessageHandler("appletviewer"); + 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. + + // Let user know we are starting up + streamhandler.write("instance " + identifier + " status " + amh.getMessage("status.start")); + factory.createPanel(streamhandler, identifier, handle, 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(c, in); + if (nm.equalsIgnoreCase("param")) { + Hashtable<String, String> t = scanTag(c, in); + String att = t.get("name"); + + if (atts.containsKey(att)) + continue; + + if (att == null) { + statusMsgStream.println(requiresNameWarning); + } else { + String val = t.get("value"); + if (val == null) { + statusMsgStream.println(requiresNameWarning); + } else if (atts != null) { + PluginDebug.debug("PUT " + att + " = " + val); + atts.put(att.toLowerCase(), val); + } else { + statusMsgStream.println(paramOutsideWarning); + } + } + } else if (nm.equalsIgnoreCase("applet")) { + isAppletTag = true; + atts = scanTag(c, in); + + // If there is a classid and no code tag present, transform it to code tag + if (atts.get("code") == null && atts.get("classid") != null + && !(atts.get("classid")).startsWith("clsid:")) { + atts.put("code", atts.get("classid")); + } - 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()); + // remove java: from code tag + if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) { + atts.put("code", (atts.get("code")).substring(5)); + } + + if (atts.get("code") == null && atts.get("object") == null) { + statusMsgStream.println(appletRequiresCodeWarning); + atts = null; + } + + if (atts.get("width") == null || !isInt(atts.get("width"))) { + atts.put("width", width); + } + + if (atts.get("height") == null || !isInt(atts.get("height"))) { + atts.put("height", height); + } + } else if (nm.equalsIgnoreCase("object")) { + isObjectTag = true; + + // Once code is set, additional nested objects are ignored + if (!objectTagAlreadyParsed) { + objectTagAlreadyParsed = true; + atts = scanTag(c, in); + } + + // If there is a classid and no code tag present, transform it to code tag + if (atts.get("code") == null && atts.get("classid") != null + && !(atts.get("classid")).startsWith("clsid:")) { + atts.put("code", atts.get("classid")); + } + + // remove java: from code tag + if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) { + atts.put("code", (atts.get("code")).substring(5)); + } + + // java_* aliases override older names: + // http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/using_tags.html#in-ie + if (atts.get("java_code") != null) { + atts.put("code", (atts.get("java_code"))); + } + + if (atts.containsKey("code")) { + objectTagAlreadyParsed = true; + } + + if (atts.get("java_codebase") != null) { + atts.put("codebase", (atts.get("java_codebase"))); + } + + if (atts.get("java_archive") != null) { + atts.put("archive", (atts.get("java_archive"))); + } + + if (atts.get("java_object") != null) { + atts.put("object", (atts.get("java_object"))); + } + + if (atts.get("java_type") != null) { + atts.put("type", (atts.get("java_type"))); + } + + if (atts.get("width") == null || !isInt(atts.get("width"))) { + atts.put("width", width); + } + + if (atts.get("height") == null || !isInt(atts.get("height"))) { + atts.put("height", height); + } + } else if (nm.equalsIgnoreCase("embed")) { + isEmbedTag = true; + atts = scanTag(c, in); + + // If there is a classid and no code tag present, transform it to code tag + if (atts.get("code") == null && atts.get("classid") != null + && !(atts.get("classid")).startsWith("clsid:")) { + atts.put("code", atts.get("classid")); + } + + // remove java: from code tag + if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) { + atts.put("code", (atts.get("code")).substring(5)); + } + + // java_* aliases override older names: + // http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/using_tags.html#in-nav + if (atts.get("java_code") != null) { + atts.put("code", (atts.get("java_code"))); + } + + if (atts.get("java_codebase") != null) { + atts.put("codebase", (atts.get("java_codebase"))); + } + + if (atts.get("java_archive") != null) { + atts.put("archive", (atts.get("java_archive"))); + } + + if (atts.get("java_object") != null) { + atts.put("object", (atts.get("java_object"))); + } + + if (atts.get("java_type") != null) { + atts.put("type", (atts.get("java_type"))); + } + + if (atts.get("code") == null && atts.get("object") == null) { + statusMsgStream.println(embedRequiresCodeWarning); + atts = null; + } + + if (atts.get("width") == null || !isInt(atts.get("width"))) { + atts.put("width", width); + } + + if (atts.get("height") == null || !isInt(atts.get("height"))) { + atts.put("height", height); + } + + } + } + } + } + in.close(); + } + + 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()); + } } } - } - - /** - * {@inheritDoc} - * - * This method calls paint directly, rather than via super.update() since - * the parent class's update() just does a couple of checks (both of - * which are accounted for) and then calls paint anyway. - */ - public void update(Graphics g) { - - // If the image or the graphics don't exist, create new ones - if (bufFrameImg == null || bufFrameImgGraphics == null) { - bufFrameImg = createImage(getWidth(), getHeight()); - bufFrameImgGraphics = bufFrameImg.getGraphics (); - } - - // Paint off-screen - paint(bufFrameImgGraphics); - - // Draw the painted image - g.drawImage(bufFrameImg, 0, 0, this); - } - } + + /** + * {@inheritDoc} + * + * This method calls paint directly, rather than via super.update() since + * the parent class's update() just does a couple of checks (both of + * which are accounted for) and then calls paint anyway. + */ + public void update(Graphics g) { + + // If the image or the graphics don't exist, create new ones + if (bufFrameImg == null || bufFrameImgGraphics == null) { + bufFrameImg = createImage(getWidth(), getHeight()); + bufFrameImgGraphics = bufFrameImg.getGraphics(); + } + + // Paint off-screen + paint(bufFrameImgGraphics); + + // Draw the painted image + g.drawImage(bufFrameImg, 0, 0, this); + } +} |