Mercurial > hg > release > icedtea6-1.3
changeset 1049:abdb5c94757d
More refactoring. Moved classes to a shorter path, removed classes provided by
the JDK tarball (they were there by mistake).
author | Deepak Bhole <dbhole@redhat.com> |
---|---|
date | Tue, 23 Sep 2008 16:52:24 -0400 |
parents | 5cf4df1bc010 |
children | 30567fe7d579 |
files | ChangeLog Makefile.am patches/icedtea-plugin.patch plugin/gcj/java/src/main/sun/applet/PluginAppletViewer.java plugin/gcj/java/src/main/sun/applet/PluginMain.java plugin/icedtea/java/src/main/netscape/javascript/JSException.java plugin/icedtea/java/src/main/netscape/javascript/JSObject.java plugin/icedtea/java/src/main/netscape/javascript/JSProxy.java plugin/icedtea/java/src/main/netscape/javascript/JSRunnable.java plugin/icedtea/java/src/main/netscape/javascript/JSUtil.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMain.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMessageConsumer.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginObjectStore.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/RequestQueue.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/TestEnv.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/VoidPluginCallRequest.java plugin/icedtea/java/src/main/sun/applet/AppletAudioClip.java plugin/icedtea/java/src/main/sun/applet/AppletClassLoader.java plugin/icedtea/java/src/main/sun/applet/AppletEvent.java plugin/icedtea/java/src/main/sun/applet/AppletEventMulticaster.java plugin/icedtea/java/src/main/sun/applet/AppletIOException.java plugin/icedtea/java/src/main/sun/applet/AppletIllegalArgumentException.java plugin/icedtea/java/src/main/sun/applet/AppletImageRef.java plugin/icedtea/java/src/main/sun/applet/AppletListener.java plugin/icedtea/java/src/main/sun/applet/AppletMessageHandler.java plugin/icedtea/java/src/main/sun/applet/AppletObjectInputStream.java plugin/icedtea/java/src/main/sun/applet/AppletPanel.java plugin/icedtea/java/src/main/sun/applet/AppletProps.java plugin/icedtea/java/src/main/sun/applet/AppletResourceLoader.java plugin/icedtea/java/src/main/sun/applet/AppletSecurity.java plugin/icedtea/java/src/main/sun/applet/AppletSecurityContext.java plugin/icedtea/java/src/main/sun/applet/AppletSecurityContextManager.java plugin/icedtea/java/src/main/sun/applet/AppletSecurityException.java plugin/icedtea/java/src/main/sun/applet/AppletThreadGroup.java plugin/icedtea/java/src/main/sun/applet/AppletViewerFactory.java plugin/icedtea/java/src/main/sun/applet/AppletViewerPanel.java plugin/icedtea/java/src/main/sun/applet/Main.java plugin/icedtea/java/src/main/sun/applet/PluginAppletViewer.java plugin/icedtea/java/src/main/sun/applet/PluginCallRequest.java plugin/icedtea/java/src/main/sun/applet/PluginCallRequestFactory.java plugin/icedtea/java/src/main/sun/applet/PluginClassLoader.java plugin/icedtea/java/src/main/sun/applet/PluginDebug.java plugin/icedtea/java/src/main/sun/applet/PluginException.java plugin/icedtea/java/src/main/sun/applet/PluginStreamHandler.java plugin/icedtea/netscape/javascript/JSException.java plugin/icedtea/netscape/javascript/JSObject.java plugin/icedtea/netscape/javascript/JSProxy.java plugin/icedtea/netscape/javascript/JSRunnable.java plugin/icedtea/netscape/javascript/JSUtil.java plugin/icedtea/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java plugin/icedtea/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java plugin/icedtea/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java plugin/icedtea/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java plugin/icedtea/org/classpath/icedtea/plugin/PluginMain.java plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageConsumer.java plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java plugin/icedtea/org/classpath/icedtea/plugin/PluginObjectStore.java plugin/icedtea/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java plugin/icedtea/org/classpath/icedtea/plugin/RequestQueue.java plugin/icedtea/org/classpath/icedtea/plugin/TestEnv.java plugin/icedtea/org/classpath/icedtea/plugin/VoidPluginCallRequest.java plugin/icedtea/sun/applet/AppletSecurityContext.java plugin/icedtea/sun/applet/AppletSecurityContextManager.java plugin/icedtea/sun/applet/PluginAppletViewer.java plugin/icedtea/sun/applet/PluginCallRequest.java plugin/icedtea/sun/applet/PluginCallRequestFactory.java plugin/icedtea/sun/applet/PluginClassLoader.java plugin/icedtea/sun/applet/PluginDebug.java plugin/icedtea/sun/applet/PluginException.java plugin/icedtea/sun/applet/PluginStreamHandler.java |
diffstat | 76 files changed, 5756 insertions(+), 10252 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Sep 23 16:33:17 2008 -0400 +++ b/ChangeLog Tue Sep 23 16:52:24 2008 -0400 @@ -1,3 +1,53 @@ +2008-09-23 Deepak Bhole <dbhole@redhat.com> + * Makefile.am: Update to create new IcedTeaPlugin.jar + * patches/icedtea-liveconnect.patch: Update patch and remove all new .java + files + * plugin/icedtea/java/src/main/netscape/javascript/JSException.java: Moved + out of rt/ overlay. + * plugin/icedtea/java/src/main/netscape/javascript/JSObject.java: Same. + * plugin/icedtea/java/src/main/netscape/javascript/JSProxy.java: Same. + * plugin/icedtea/java/src/main/netscape/javascript/JSRunnable.java: Same. + * plugin/icedtea/java/src/main/netscape/javascript/JSUtil.java: Same. + * plugin/icedtea/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java: + Moved out of icedtea-liveconnect.patch and refactored. + * plugin/icedtea/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java: + Same. + * plugin/icedtea/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java: + Same. + * plugin/icedtea/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java: + Same. + * plugin/icedtea/org/classpath/icedtea/plugin/PluginMain.java: Same. + * plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageConsumer.java: + Same. + * plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java: + Same. + * plugin/icedtea/org/classpath/icedtea/plugin/PluginObjectStore.java: + Same. + * plugin/icedtea/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java: + Same. + * plugin/icedtea/org/classpath/icedtea/plugin/RequestQueue.java: Same. + * plugin/icedtea/org/classpath/icedtea/plugin/TestEnv.java: Same. + * plugin/icedtea/org/classpath/icedtea/plugin/VoidPluginCallRequest.java: + Same. + * plugin/icedtea/sun/applet/AppletSecurityContext.java: Same. + * plugin/icedtea/sun/applet/AppletSecurityContextManager.java: Same. + * plugin/icedtea/sun/applet/PluginAppletViewer.java: Same. + * plugin/icedtea/sun/applet/PluginCallRequest.java: Same. + * plugin/icedtea/sun/applet/PluginCallRequestFactory.java: Same. + * plugin/icedtea/sun/applet/PluginClassLoader.java: Same. + * plugin/icedtea/sun/applet/PluginDebug.java: Same. + * plugin/icedtea/sun/applet/PluginException.java: Same. + * plugin/icedtea/sun/applet/PluginStreamHandler.java: Same. + * rt/net/sourceforge/jnlp/Launcher.java: Print exception trace if launch + fails. + * rt/net/sourceforge/jnlp/runtime/JNLPRuntime.java: Set ServiceManagerStub + before SecurityManager is set. + * rt/netscape/javascript/JSException.java: Move to plugin/icedtea dir. + * rt/netscape/javascript/JSObject.java: Same. + * rt/netscape/javascript/JSProxy.java: Same. + * rt/netscape/javascript/JSRunnable.java: Same. + * rt/netscape/javascript/JSUtil.java: Same. + 2008-09-18 Lillian Angel <langel@redhat.com> * AUTHORS: Added Marc Schoenefeld.
--- a/Makefile.am Tue Sep 23 16:33:17 2008 -0400 +++ b/Makefile.am Tue Sep 23 16:52:24 2008 -0400 @@ -16,7 +16,7 @@ ICEDTEAPLUGIN_TARGET = IcedTeaPlugin.so ICEDTEAPLUGIN_JAR = IcedTeaPlugin.jar PLUGIN_PATCH = patches/icedtea-liveconnect.patch -LIVECONNECT = $(abs_top_srcdir)/plugin/icedtea/java/src/main +LIVECONNECT = $(abs_top_srcdir)/plugin/icedtea/ else ICEDTEAPLUGIN_CLEAN = ICEDTEAPLUGIN_TARGET = @@ -1323,7 +1323,7 @@ # icedtea plugin jar for java-side classes IcedTeaPlugin.jar: mkdir -p $(BUILD_OUTPUT_DIR)/plugin/icedtea/classes - (cd plugin/icedtea/java/src/main/; \ + (cd plugin/icedtea/; \ $(ICEDTEA_BOOT_DIR)/bin/javac -g \ -d ../../../../../$(BUILD_OUTPUT_DIR)/plugin/icedtea/classes \ -bootclasspath $(ICEDTEA_BOOT_DIR)/jre/lib/rt.jar \
--- a/patches/icedtea-plugin.patch Tue Sep 23 16:33:17 2008 -0400 +++ b/patches/icedtea-plugin.patch Tue Sep 23 16:52:24 2008 -0400 @@ -1,6 +1,6 @@ diff -urN openjdk.orig/jdk/make/launchers/Makefile openjdk/jdk/make/launchers/Makefile ---- openjdk.orig/jdk/make/launchers/Makefile 2008-07-10 15:54:41.000000000 -0400 -+++ openjdk/jdk/make/launchers/Makefile 2008-09-18 14:21:46.000000000 -0400 +--- openjdk.orig/jdk/make/launchers/Makefile 2008-06-29 09:40:07.000000000 -0400 ++++ openjdk/jdk/make/launchers/Makefile 2008-06-29 09:40:16.000000000 -0400 @@ -92,6 +92,7 @@ -J-Dcom.sun.CORBA.activation.Port=1049 \ -J-Dcom.sun.CORBA.POA.ORBServerId=1, ) @@ -9,3 +9,1293 @@ $(call make-launcher, policytool, sun.security.tools.PolicyTool, , ) $(call make-launcher, rmic, sun.rmi.rmic.Main, , ) $(call make-launcher, rmid, sun.rmi.server.Activation, , ) +diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/PluginMain.java openjdk/jdk/src/share/classes/sun/applet/PluginMain.java +--- openjdk.orig/jdk/src/share/classes/sun/applet/PluginMain.java 1969-12-31 19:00:00.000000000 -0500 ++++ openjdk/jdk/src/share/classes/sun/applet/PluginMain.java 2008-01-14 14:18:53.000000000 -0500 +@@ -0,0 +1,274 @@ ++/* ++ * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Sun designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Sun in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, ++ * CA 95054 USA or visit www.sun.com if you need additional information or ++ * have any questions. ++ */ ++ ++package sun.applet; ++ ++import java.io.*; ++import java.lang.reflect.Method; ++import java.lang.reflect.InvocationTargetException; ++import java.net.*; ++import java.nio.charset.Charset; ++import java.util.*; ++import sun.net.www.ParseUtil; ++ ++class PluginParseRequest ++{ ++ long handle; ++ String tag; ++ String documentbase; ++ boolean alreadySent; ++} ++ ++/** ++ * The main entry point into PluginAppletViewer. ++ */ ++public class PluginMain ++{ ++ // A mapping of instance IDs to PluginAppletViewers. ++ private static HashMap appletWindows = new HashMap(); ++ private static HashMap parseRequests = new HashMap(); ++ private static String currentKey; ++ private static PluginAppletViewer currentWindow; ++ private static PluginParseRequest currentRequest; ++ private static BufferedReader pluginInputStream; ++ private static BufferedWriter pluginOutputStream; ++ // This is used in init(). Getting rid of this is desirable but depends ++ // on whether the property that uses it is necessary/standard. ++ public static final String theVersion = System.getProperty("java.version"); ++ ++ /** ++ * The main entry point into AppletViewer. ++ */ ++ public static void main(String args[]) ++ throws IOException ++ { ++ if(args.length != 2) { ++ // Indicate to plugin that appletviewer is installed correctly. ++ System.exit(0); ++ } ++ // INSTALL THE SECURITY MANAGER ++ init(); ++ start(new FileInputStream(args[0]), new FileOutputStream(args[1])); ++ System.exit(0); ++ } ++ ++ private static void init() { ++ Properties avProps = new Properties(); ++ ++ // ADD OTHER RANDOM PROPERTIES ++ // XXX 5/18 need to revisit why these are here, is there some ++ // standard for what is available? ++ ++ // Standard browser properties ++ avProps.put("browser", "sun.applet.AppletViewer"); ++ avProps.put("browser.version", "1.06"); ++ avProps.put("browser.vendor", "Sun Microsystems Inc."); ++ avProps.put("http.agent", "Java(tm) 2 SDK, Standard Edition v" + theVersion); ++ ++ // Define which packages can be extended by applets ++ // XXX 5/19 probably not needed, not checked in AppletSecurity ++ avProps.put("package.restrict.definition.java", "true"); ++ avProps.put("package.restrict.definition.sun", "true"); ++ ++ // Define which properties can be read by applets. ++ // A property named by "key" can be read only when its twin ++ // property "key.applet" is true. The following ten properties ++ // are open by default. Any other property can be explicitly ++ // opened up by the browser user by calling appletviewer with ++ // -J-Dkey.applet=true ++ avProps.put("java.version.applet", "true"); ++ avProps.put("java.vendor.applet", "true"); ++ avProps.put("java.vendor.url.applet", "true"); ++ avProps.put("java.class.version.applet", "true"); ++ avProps.put("os.name.applet", "true"); ++ avProps.put("os.version.applet", "true"); ++ avProps.put("os.arch.applet", "true"); ++ avProps.put("file.separator.applet", "true"); ++ avProps.put("path.separator.applet", "true"); ++ avProps.put("line.separator.applet", "true"); ++ ++ // Read in the System properties. If something is going to be ++ // over-written, warn about it. ++ Properties sysProps = System.getProperties(); ++ for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements(); ) { ++ String key = (String) e.nextElement(); ++ String val = (String) sysProps.getProperty(key); ++ avProps.setProperty(key, val); ++ } ++ ++ // INSTALL THE PROPERTY LIST ++ System.setProperties(avProps); ++ ++ // Create and install the security manager ++ System.setSecurityManager(new AppletSecurity()); ++ ++ // REMIND: Create and install a socket factory! ++ } ++ ++ static void registerWindow(PluginAppletViewer pluginappletviewer) ++ { ++ appletWindows.put(currentKey, pluginappletviewer); ++ currentWindow = (PluginAppletViewer)appletWindows.get(currentKey); ++ } ++ ++ private static void deregisterWindow(PluginAppletViewer pluginappletviewer) ++ { ++ appletWindows.remove(currentWindow); ++ currentWindow.dispose(); ++ currentWindow = null; ++ } ++ ++ static void start(InputStream inputstream, OutputStream outputstream) ++ throws MalformedURLException, IOException ++ { ++ // Set up input and output pipes. Use UTF-8 encoding. ++ pluginInputStream = ++ new BufferedReader(new InputStreamReader(inputstream, ++ Charset.forName("UTF-8"))); ++ pluginOutputStream = ++ new BufferedWriter(new OutputStreamWriter ++ (outputstream, Charset.forName("UTF-8"))); ++ ++ write("running"); ++ ++ // Read first message. ++ String message = read(); ++ ++ while(true) { ++ if (message.startsWith("instance")) { ++ // Read applet instance identifier. ++ currentKey = message.substring("instance".length() + 1); ++ currentWindow = ++ (PluginAppletViewer)appletWindows.get(currentKey); ++ currentRequest = null; ++ if (currentWindow == null) { ++ if (!parseRequests.containsKey(currentKey)) ++ parseRequests.put(currentKey, new PluginParseRequest()); ++ currentRequest = ++ (PluginParseRequest)parseRequests.get(currentKey); ++ } ++ } else if (message.startsWith("tag")) { ++ if (currentRequest != null) { ++ int index = message.indexOf(' ', "tag".length() + 1); ++ currentRequest.documentbase = ++ message.substring("tag".length() + 1, index); ++ currentRequest.tag = message.substring(index + 1); ++ if (currentRequest.handle != 0 ++ && !currentRequest.alreadySent) { ++ PluginAppletViewer.parse ++ (currentRequest.handle, 1, 1, ++ new StringReader(currentRequest.tag), ++ new URL(currentRequest.documentbase)); ++ parseRequests.remove(currentKey); ++ } ++ } ++ } else if (message.startsWith("handle")) { ++ if (currentRequest != null) { ++ currentRequest.handle = Long.parseLong ++ (message.substring("handle".length() + 1, ++ message.indexOf("width") - 1)); ++ int width = Integer.parseInt(message.substring ++ (message.indexOf("width") + ++ "width".length() + 1, ++ message.indexOf("height") - 1)); ++ int height = Integer.parseInt(message.substring( ++ message.indexOf("height") + ++ "height".length() + 1)); ++ if (currentRequest.tag != null ++ && !currentRequest.alreadySent) { ++ PluginAppletViewer.parse ++ (currentRequest.handle, width, height, ++ new StringReader(currentRequest.tag), ++ new URL(currentRequest.documentbase)); ++ parseRequests.remove(currentKey); ++ } ++ } ++ } else if (message.startsWith("width")) { ++ int width = ++ Integer.parseInt(message.substring("width".length() + 1)); ++ int height = currentWindow.getHeight(); ++ currentWindow.updateAtts(width, height); ++ currentWindow.setSize(width, height); ++ } else if (message.startsWith("height")) { ++ int height = ++ Integer.parseInt(message.substring("height".length() + 1)); ++ int width = currentWindow.getWidth(); ++ currentWindow.updateAtts(width, height); ++ currentWindow.setSize(width, height); ++ } else if (message.startsWith("destroy") ++ && currentWindow != null) { ++ deregisterWindow(currentWindow); ++ } ++ ++ // Read next message. ++ message = read(); ++ } ++ } ++ ++ /** ++ * Write string to plugin. ++ * ++ * @param message the message to write ++ * ++ * @exception IOException if an error occurs ++ */ ++ static void write(String message) ++ throws IOException ++ { ++ pluginOutputStream.write(message, 0, message.length()); ++ pluginOutputStream.newLine(); ++ pluginOutputStream.flush(); ++ ++ System.err.println(" PIPE: appletviewer wrote: " + message); ++ } ++ ++ /** ++ * Read string from plugin. ++ * ++ * @return the read string ++ * ++ * @exception IOException if an error occurs ++ */ ++ static String read() ++ throws IOException ++ { ++ String message = pluginInputStream.readLine(); ++ System.err.println(" PIPE: appletviewer read: " + message); ++ if (message == null || message.equals("shutdown")) { ++ try { ++ // Close input/output channels to plugin. ++ pluginInputStream.close(); ++ pluginOutputStream.close(); ++ } catch (IOException exception) { ++ // Deliberately ignore IOException caused by broken ++ // pipe since plugin may have already detached. ++ } ++ ++ System.err.println("APPLETVIEWER: exiting appletviewer"); ++ System.exit(0); ++ } ++ return message; ++ } ++} +diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/PluginAppletViewer.java openjdk/jdk/src/share/classes/sun/applet/PluginAppletViewer.java +--- openjdk.orig/jdk/src/share/classes/sun/applet/PluginAppletViewer.java 2008-06-24 22:55:57.286013713 -0400 ++++ openjdk/jdk/src/share/classes/sun/applet/PluginAppletViewer.java 2008-06-29 10:34:07.000000000 -0400 +@@ -0,0 +1,1008 @@ ++/* ++ * Copyright 1995-2004 Sun Microsystems, Inc. All Rights Reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Sun designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Sun in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, ++ * CA 95054 USA or visit www.sun.com if you need additional information or ++ * have any questions. ++ */ ++ ++package sun.applet; ++ ++import java.util.*; ++import java.io.*; ++import java.awt.*; ++import java.awt.event.*; ++import java.awt.print.*; ++import javax.print.attribute.*; ++import java.applet.*; ++import java.net.URL; ++import java.net.MalformedURLException; ++import java.net.SocketPermission; ++import sun.misc.Ref; ++import java.security.AccessController; ++import java.security.PrivilegedAction; ++import java.lang.reflect.InvocationTargetException; ++import java.lang.reflect.Method; ++import sun.awt.SunToolkit; ++import sun.awt.AppContext; ++import sun.awt.X11.*; ++import java.lang.ref.WeakReference; ++import net.sourceforge.jnlp.NetxPanel; ++ ++/** ++ * Lets us construct one using unix-style one shot behaviors ++ */ ++ ++class PluginAppletViewerFactory ++{ ++ public PluginAppletViewer createAppletViewer(long handle, int x, int y, ++ URL doc, Hashtable atts) { ++ PluginAppletViewer pluginappletviewer = new PluginAppletViewer(handle, x, y, doc, atts, System.out, this); ++ PluginMain.registerWindow(pluginappletviewer); ++ return pluginappletviewer; ++ } ++ ++ public boolean isStandalone() ++ { ++ return false; ++ } ++} ++ ++/* ++ */ ++public class PluginAppletViewer extends XEmbeddedFrame ++ implements AppletContext, Printable { ++ /** ++ * Some constants... ++ */ ++ private static String defaultSaveFile = "Applet.ser"; ++ ++ /** ++ * The panel in which the applet is being displayed. ++ */ ++ AppletViewerPanel panel; ++ ++ /** ++ * The status line. ++ */ ++ Label label; ++ ++ /** ++ * output status messages to this stream ++ */ ++ ++ PrintStream statusMsgStream; ++ ++ /** ++ * For cloning ++ */ ++ PluginAppletViewerFactory factory; ++ ++ /** ++ * Create the applet viewer ++ */ ++ public PluginAppletViewer(long handle, int x, int y, final URL doc, ++ final Hashtable atts, PrintStream statusMsgStream, ++ PluginAppletViewerFactory factory) { ++ super(handle, true); ++ this.factory = factory; ++ this.statusMsgStream = statusMsgStream; ++ ++ try { ++ panel = new NetxPanel(doc, atts); ++ AppletViewerPanel.debug("Using NetX panel"); ++ } catch (Exception ex) { ++ AppletViewerPanel.debug("Unable to start NetX applet - defaulting to Sun applet", ex); ++ panel = new AppletViewerPanel(doc, atts); ++ } ++ add("Center", panel); ++ panel.init(); ++ appletPanels.addElement(panel); ++ ++ pack(); ++ setVisible(true); ++ ++ WindowListener windowEventListener = new WindowAdapter() { ++ ++ public void windowClosing(WindowEvent evt) { ++ appletClose(); ++ } ++ ++ public void windowIconified(WindowEvent evt) { ++ appletStop(); ++ } ++ ++ public void windowDeiconified(WindowEvent evt) { ++ appletStart(); ++ } ++ }; ++ ++ class AppletEventListener implements AppletListener ++ { ++ final Frame frame; ++ ++ public AppletEventListener(Frame frame) ++ { ++ this.frame = frame; ++ } ++ ++ public void appletStateChanged(AppletEvent evt) ++ { ++ AppletPanel src = (AppletPanel)evt.getSource(); ++ ++ switch (evt.getID()) { ++ case AppletPanel.APPLET_RESIZE: { ++ if(src != null) { ++ resize(preferredSize()); ++ validate(); ++ } ++ break; ++ } ++ case AppletPanel.APPLET_LOADING_COMPLETED: { ++ Applet a = src.getApplet(); // sun.applet.AppletPanel ++ ++ // Fixed #4754451: Applet can have methods running on main ++ // thread event queue. ++ // ++ // The cause of this bug is that the frame of the applet ++ // is created in main thread group. Thus, when certain ++ // AWT/Swing events are generated, the events will be ++ // dispatched through the wrong event dispatch thread. ++ // ++ // To fix this, we rearrange the AppContext with the frame, ++ // so the proper event queue will be looked up. ++ // ++ // Swing also maintains a Frame list for the AppContext, ++ // so we will have to rearrange it as well. ++ // ++ if (a != null) ++ AppletPanel.changeFrameAppContext(frame, SunToolkit.targetToAppContext(a)); ++ else ++ AppletPanel.changeFrameAppContext(frame, AppContext.getAppContext()); ++ ++ break; ++ } ++ } ++ } ++ }; ++ ++ ComponentListener componentListener = new ComponentAdapter() { ++ public void componentResized(ComponentEvent event) ++ { ++ if (panel != null) ++ { ++ ComponentListener[] l = panel.getComponentListeners(); ++ for (int i = 0; i < l.length; i++) ++ l[i].componentResized(event); ++ panel.validate(); ++ } ++ } ++ ++ public void componentMoved(ComponentEvent event) ++ { ++ if (panel != null) ++ { ++ ComponentListener[] l = panel.getComponentListeners(); ++ for (int i = 0; i < l.length; i++) ++ l[i].componentMoved(event); ++ panel.validate(); ++ } ++ } ++ }; ++ ++ HierarchyBoundsListener hierarchyBoundsListener = new HierarchyBoundsAdapter() { ++ public void ancestorMoved(HierarchyEvent e) ++ { ++ if (panel != null) ++ { ++ HierarchyBoundsListener[] l = panel.getHierarchyBoundsListeners(); ++ for (int i = 0; i < l.length; i++) ++ l[i].ancestorMoved(e); ++ panel.validate(); ++ } ++ } ++ ++ public void ancestorResized(HierarchyEvent e) ++ { ++ if (panel != null) ++ { ++ HierarchyBoundsListener[] l = panel.getHierarchyBoundsListeners(); ++ for (int i = 0; i < l.length; i++) ++ l[i].ancestorResized(e); ++ panel.validate(); ++ } ++ } ++ }; ++ ++ addWindowListener(windowEventListener); ++ addComponentListener(componentListener); ++ addHierarchyBoundsListener(hierarchyBoundsListener); ++ panel.addAppletListener(new AppletEventListener(this)); ++ ++ // Start the applet ++ showStatus(amh.getMessage("status.start")); ++ initEventQueue(); ++ } ++ ++ /** ++ * Send the initial set of events to the appletviewer event queue. ++ * On start-up the current behaviour is to load the applet and call ++ * Applet.init() and Applet.start(). ++ */ ++ private void initEventQueue() { ++ // appletviewer.send.event is an undocumented and unsupported system ++ // property which is used exclusively for testing purposes. ++ String eventList = System.getProperty("appletviewer.send.event"); ++ ++ if (eventList == null) { ++ // Add the standard events onto the event queue. ++ panel.sendEvent(AppletPanel.APPLET_LOAD); ++ panel.sendEvent(AppletPanel.APPLET_INIT); ++ panel.sendEvent(AppletPanel.APPLET_START); ++ } else { ++ // We're testing AppletViewer. Force the specified set of events ++ // onto the event queue, wait for the events to be processed, and ++ // exit. ++ ++ // The list of events that will be executed is provided as a ++ // ","-separated list. No error-checking will be done on the list. ++ String [] events = splitSeparator(",", eventList); ++ ++ for (int i = 0; i < events.length; i++) { ++ System.out.println("Adding event to queue: " + events[i]); ++ if (events[i].equals("dispose")) ++ panel.sendEvent(AppletPanel.APPLET_DISPOSE); ++ else if (events[i].equals("load")) ++ panel.sendEvent(AppletPanel.APPLET_LOAD); ++ else if (events[i].equals("init")) ++ panel.sendEvent(AppletPanel.APPLET_INIT); ++ else if (events[i].equals("start")) ++ panel.sendEvent(AppletPanel.APPLET_START); ++ else if (events[i].equals("stop")) ++ panel.sendEvent(AppletPanel.APPLET_STOP); ++ else if (events[i].equals("destroy")) ++ panel.sendEvent(AppletPanel.APPLET_DESTROY); ++ else if (events[i].equals("quit")) ++ panel.sendEvent(AppletPanel.APPLET_QUIT); ++ else if (events[i].equals("error")) ++ panel.sendEvent(AppletPanel.APPLET_ERROR); ++ else ++ // non-fatal error if we get an unrecognized event ++ System.out.println("Unrecognized event name: " + events[i]); ++ } ++ ++ while (!panel.emptyEventQueue()) ; ++ appletSystemExit(); ++ } ++ } ++ ++ /** ++ * Split a string based on the presence of a specified separator. Returns ++ * an array of arbitrary length. The end of each element in the array is ++ * indicated by the separator of the end of the string. If there is a ++ * separator immediately before the end of the string, the final element ++ * will be empty. None of the strings will contain the separator. Useful ++ * when separating strings such as "foo/bar/bas" using separator "/". ++ * ++ * @param sep The separator. ++ * @param s The string to split. ++ * @return An array of strings. Each string in the array is determined ++ * by the location of the provided sep in the original string, ++ * s. Whitespace not stripped. ++ */ ++ private String [] splitSeparator(String sep, String s) { ++ Vector v = new Vector(); ++ int tokenStart = 0; ++ int tokenEnd = 0; ++ ++ while ((tokenEnd = s.indexOf(sep, tokenStart)) != -1) { ++ v.addElement(s.substring(tokenStart, tokenEnd)); ++ tokenStart = tokenEnd+1; ++ } ++ // Add the final element. ++ v.addElement(s.substring(tokenStart)); ++ ++ String [] retVal = new String[v.size()]; ++ v.copyInto(retVal); ++ return retVal; ++ } ++ ++ /* ++ * Methods for java.applet.AppletContext ++ */ ++ ++ private static Map audioClips = new HashMap(); ++ ++ /** ++ * Get an audio clip. ++ */ ++ public AudioClip getAudioClip(URL url) { ++ checkConnect(url); ++ synchronized (audioClips) { ++ AudioClip clip = (AudioClip)audioClips.get(url); ++ if (clip == null) { ++ audioClips.put(url, clip = new AppletAudioClip(url)); ++ } ++ return clip; ++ } ++ } ++ ++ private static Map imageRefs = new HashMap(); ++ ++ /** ++ * Get an image. ++ */ ++ public Image getImage(URL url) { ++ return getCachedImage(url); ++ } ++ ++ static Image getCachedImage(URL url) { ++ // System.getSecurityManager().checkConnection(url.getHost(), url.getPort()); ++ return (Image)getCachedImageRef(url).get(); ++ } ++ ++ /** ++ * Get an image ref. ++ */ ++ static Ref getCachedImageRef(URL url) { ++ synchronized (imageRefs) { ++ AppletImageRef ref = (AppletImageRef)imageRefs.get(url); ++ if (ref == null) { ++ ref = new AppletImageRef(url); ++ imageRefs.put(url, ref); ++ } ++ return ref; ++ } ++ } ++ ++ /** ++ * Flush the image cache. ++ */ ++ static void flushImageCache() { ++ imageRefs.clear(); ++ } ++ ++ static Vector appletPanels = new Vector(); ++ ++ /** ++ * Get an applet by name. ++ */ ++ public Applet getApplet(String name) { ++ AppletSecurity security = (AppletSecurity)System.getSecurityManager(); ++ name = name.toLowerCase(); ++ SocketPermission panelSp = ++ new SocketPermission(panel.getCodeBase().getHost(), "connect"); ++ for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) { ++ AppletPanel p = (AppletPanel)e.nextElement(); ++ String param = p.getParameter("name"); ++ if (param != null) { ++ param = param.toLowerCase(); ++ } ++ if (name.equals(param) && ++ p.getDocumentBase().equals(panel.getDocumentBase())) { ++ ++ SocketPermission sp = ++ new SocketPermission(p.getCodeBase().getHost(), "connect"); ++ ++ if (panelSp.implies(sp)) { ++ return p.applet; ++ } ++ } ++ } ++ return null; ++ } ++ ++ /** ++ * Return an enumeration of all the accessible ++ * applets on this page. ++ */ ++ public Enumeration getApplets() { ++ AppletSecurity security = (AppletSecurity)System.getSecurityManager(); ++ Vector v = new Vector(); ++ SocketPermission panelSp = ++ new SocketPermission(panel.getCodeBase().getHost(), "connect"); ++ ++ for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) { ++ AppletPanel p = (AppletPanel)e.nextElement(); ++ if (p.getDocumentBase().equals(panel.getDocumentBase())) { ++ ++ SocketPermission sp = ++ new SocketPermission(p.getCodeBase().getHost(), "connect"); ++ if (panelSp.implies(sp)) { ++ v.addElement(p.applet); ++ } ++ } ++ } ++ return v.elements(); ++ } ++ ++ /** ++ * Ignore. ++ */ ++ public void showDocument(URL url) { ++ showDocument(url, "_self"); ++ } ++ ++ /** ++ * Ignore. ++ */ ++ public void showDocument(URL url, String target) { ++ try { ++ PluginMain.write("url " + url + " " + target); ++ } catch (IOException exception) { ++ // Deliberately ignore IOException. showDocument may be ++ // called from threads other than the main thread after ++ // PluginMain.pluginOutputStream has been closed. ++ } ++ } ++ ++ /** ++ * Show status. ++ */ ++ public void showStatus(String status) { ++ try { ++ PluginMain.write("status " + status); ++ } catch (IOException exception) { ++ // Deliberately ignore IOException. showStatus may be ++ // called from threads other than the main thread after ++ // PluginMain.pluginOutputStream has been closed. ++ } ++ } ++ ++ public void setStream(String key, InputStream stream)throws IOException{ ++ // We do nothing. ++ } ++ ++ public InputStream getStream(String key){ ++ // We do nothing. ++ return null; ++ } ++ ++ public Iterator getStreamKeys(){ ++ // We do nothing. ++ return null; ++ } ++ ++ /** ++ * System parameters. ++ */ ++ static Hashtable systemParam = new Hashtable(); ++ ++ static { ++ systemParam.put("codebase", "codebase"); ++ systemParam.put("code", "code"); ++ systemParam.put("alt", "alt"); ++ systemParam.put("width", "width"); ++ systemParam.put("height", "height"); ++ systemParam.put("align", "align"); ++ systemParam.put("vspace", "vspace"); ++ systemParam.put("hspace", "hspace"); ++ } ++ ++ /** ++ * Print the HTML tag. ++ */ ++ public static void printTag(PrintStream out, Hashtable atts) { ++ out.print("<applet"); ++ ++ String v = (String)atts.get("codebase"); ++ if (v != null) { ++ out.print(" codebase=\"" + v + "\""); ++ } ++ ++ v = (String)atts.get("code"); ++ if (v == null) { ++ v = "applet.class"; ++ } ++ out.print(" code=\"" + v + "\""); ++ v = (String)atts.get("width"); ++ if (v == null) { ++ v = "150"; ++ } ++ out.print(" width=" + v); ++ ++ v = (String)atts.get("height"); ++ if (v == null) { ++ v = "100"; ++ } ++ out.print(" height=" + v); ++ ++ v = (String)atts.get("name"); ++ if (v != null) { ++ out.print(" name=\"" + v + "\""); ++ } ++ out.println(">"); ++ ++ // A very slow sorting algorithm ++ int len = atts.size(); ++ String params[] = new String[len]; ++ len = 0; ++ for (Enumeration e = atts.keys() ; e.hasMoreElements() ;) { ++ String param = (String)e.nextElement(); ++ int i = 0; ++ for (; i < len ; i++) { ++ if (params[i].compareTo(param) >= 0) { ++ break; ++ } ++ } ++ System.arraycopy(params, i, params, i + 1, len - i); ++ params[i] = param; ++ len++; ++ } ++ ++ for (int i = 0 ; i < len ; i++) { ++ String param = params[i]; ++ if (systemParam.get(param) == null) { ++ out.println("<param name=" + param + ++ " value=\"" + atts.get(param) + "\">"); ++ } ++ } ++ out.println("</applet>"); ++ } ++ ++ /** ++ * Make sure the attributes are up-to-date. ++ */ ++ public void updateAtts(int width, int height) { ++ panel.atts.remove("width"); ++ panel.atts.remove("height"); ++ panel.atts.put("width", new Integer(width).toString()); ++ panel.atts.put("height", new Integer(height).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] ++ */ ++ AppletPanel.flushClassLoader(panel.getClassLoaderCacheKey()); ++ ++ /* ++ * Make sure we don't have two threads running through the event queue ++ * at the same time. ++ */ ++ try { ++ panel.joinAppletThread(); ++ panel.release(); ++ } catch (InterruptedException e) { ++ return; // abort the reload ++ } ++ ++ panel.createAppletThread(); ++ panel.sendEvent(AppletPanel.APPLET_LOAD); ++ panel.sendEvent(AppletPanel.APPLET_INIT); ++ panel.sendEvent(AppletPanel.APPLET_START); ++ } ++ ++ 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() ++ { ++ appletShutdown(p); ++ appletPanels.removeElement(p); ++ dispose(); ++ ++ if (countApplets() == 0) { ++ appletSystemExit(); ++ } ++ } ++ }).start(); ++ } ++ ++ /** ++ * Exit the program. ++ * Exit from the program (if not stand alone) - do no clean-up ++ */ ++ private void appletSystemExit() { ++ if (factory.isStandalone()) ++ System.exit(0); ++ } ++ ++ /** ++ * How many applets are running? ++ */ ++ ++ public static int countApplets() { ++ return appletPanels.size(); ++ } ++ ++ ++ /** ++ * The current character. ++ */ ++ static int c; ++ ++ /** ++ * Scan spaces. ++ */ ++ public static void skipSpace(Reader in) throws IOException { ++ while ((c >= 0) && ++ ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'))) { ++ c = in.read(); ++ } ++ } ++ ++ /** ++ * Scan identifier ++ */ ++ public static String scanIdentifier(Reader in) throws IOException { ++ StringBuffer buf = new StringBuffer(); ++ while (true) { ++ if (((c >= 'a') && (c <= 'z')) || ++ ((c >= 'A') && (c <= 'Z')) || ++ ((c >= '0') && (c <= '9')) || (c == '_')) { ++ buf.append((char)c); ++ c = in.read(); ++ } else { ++ return buf.toString(); ++ } ++ } ++ } ++ ++ /** ++ * Scan tag ++ */ ++ public static Hashtable scanTag(Reader in) throws IOException { ++ Hashtable atts = new Hashtable(); ++ skipSpace(in); ++ while (c >= 0 && c != '>') { ++ String att = scanIdentifier(in); ++ String val = ""; ++ skipSpace(in); ++ if (c == '=') { ++ int quote = -1; ++ c = in.read(); ++ skipSpace(in); ++ if ((c == '\'') || (c == '\"')) { ++ quote = c; ++ c = in.read(); ++ } ++ StringBuffer buf = new StringBuffer(); ++ while ((c > 0) && ++ (((quote < 0) && (c != ' ') && (c != '\t') && ++ (c != '\n') && (c != '\r') && (c != '>')) ++ || ((quote >= 0) && (c != quote)))) { ++ buf.append((char)c); ++ c = in.read(); ++ } ++ if (c == quote) { ++ c = in.read(); ++ } ++ skipSpace(in); ++ val = buf.toString(); ++ } ++ //statusMsgStream.println("PUT " + att + " = '" + val + "'"); ++ if (! val.equals("")) { ++ atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val); ++ } ++ while (true) { ++ if ((c == '>') || (c < 0) || ++ ((c >= 'a') && (c <= 'z')) || ++ ((c >= 'A') && (c <= 'Z')) || ++ ((c >= '0') && (c <= '9')) || (c == '_')) ++ break; ++ c = in.read(); ++ } ++ //skipSpace(in); ++ } ++ return atts; ++ } ++ ++ /* values used for placement of AppletViewer's frames */ ++ private static int x = 0; ++ private static int y = 0; ++ private static final int XDELTA = 30; ++ private static final int YDELTA = XDELTA; ++ ++ static String encoding = null; ++ ++ static private Reader makeReader(InputStream is) { ++ if (encoding != null) { ++ try { ++ return new BufferedReader(new InputStreamReader(is, encoding)); ++ } catch (IOException x) { } ++ } ++ InputStreamReader r = new InputStreamReader(is); ++ encoding = r.getEncoding(); ++ return new BufferedReader(r); ++ } ++ ++ /** ++ * Scan an html file for <applet> tags ++ */ ++ public static void parse(long handle, Reader in, URL url, String enc) ++ throws IOException { ++ encoding = enc; ++ parse(handle, 1, 1, in, url, System.out, new PluginAppletViewerFactory()); ++ } ++ ++ public static void parse(long handle, int width, int height, Reader in, URL url) ++ throws IOException { ++ parse(handle, width, height, ++ in, url, System.out, new PluginAppletViewerFactory()); ++ } ++ ++ public static void parse(long handle, int width, int height, Reader in, ++ URL url, ++ PrintStream statusMsgStream, ++ PluginAppletViewerFactory factory) ++ throws IOException ++ { ++ // <OBJECT> <EMBED> tag flags ++ boolean isAppletTag = false; ++ boolean isObjectTag = false; ++ boolean isEmbedTag = false; ++ ++ // warning messages ++ String requiresNameWarning = amh.getMessage("parse.warning.requiresname"); ++ String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside"); ++ String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode"); ++ String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight"); ++ String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth"); ++ String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode"); ++ String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight"); ++ String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth"); ++ String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode"); ++ String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight"); ++ String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth"); ++ String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported"); ++ ++ java.net.URLConnection conn = url.openConnection(); ++ /* The original URL may have been redirected - this ++ * sets it to whatever URL/codebase we ended up getting ++ */ ++ url = conn.getURL(); ++ ++ int ydisp = 1; ++ Hashtable atts = null; ++ ++ while(true) { ++ c = in.read(); ++ if (c == -1) ++ break; ++ ++ if (c == '<') { ++ c = in.read(); ++ if (c == '/') { ++ c = in.read(); ++ String nm = scanIdentifier(in); ++ if (nm.equalsIgnoreCase("applet") || ++ nm.equalsIgnoreCase("object") || ++ nm.equalsIgnoreCase("embed")) { ++ ++ // We can't test for a code tag until </OBJECT> ++ // because it is a parameter, not an attribute. ++ if(isObjectTag) { ++ if (atts.get("code") == null && atts.get("object") == null) { ++ statusMsgStream.println(objectRequiresCodeWarning); ++ atts = null; ++ } ++ } ++ ++ if (atts != null) { ++ atts.remove("width"); ++ atts.remove("height"); ++ atts.put("width", new Integer(width).toString()); ++ atts.put("height", new Integer(height).toString()); ++ ++ // XXX 5/18 In general this code just simply ++ // shouldn't be part of parsing. It's presence ++ // causes things to be a little too much of a ++ // hack. ++ factory.createAppletViewer(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(in); ++ if (nm.equalsIgnoreCase("param")) { ++ Hashtable t = scanTag(in); ++ String att = (String)t.get("name"); ++ if (att == null) { ++ statusMsgStream.println(requiresNameWarning); ++ } else { ++ String val = (String)t.get("value"); ++ if (val == null) { ++ statusMsgStream.println(requiresNameWarning); ++ } else if (atts != null) { ++ String name = att.toLowerCase(); ++ atts.put(name, val); ++ } else { ++ statusMsgStream.println(paramOutsideWarning); ++ } ++ } ++ } ++ else if (nm.equalsIgnoreCase("applet")) { ++ isAppletTag = true; ++ atts = scanTag(in); ++ if (atts.get("code") == null && atts.get("object") == null) { ++ statusMsgStream.println(appletRequiresCodeWarning); ++ atts = null; ++ } else if (atts.get("width") == null) { ++ statusMsgStream.println(appletRequiresWidthWarning); ++ atts = null; ++ } else if (atts.get("height") == null) { ++ statusMsgStream.println(appletRequiresHeightWarning); ++ atts = null; ++ } ++ } ++ else if (nm.equalsIgnoreCase("object")) { ++ isObjectTag = true; ++ atts = scanTag(in); ++ // The <OBJECT> attribute codebase isn't what ++ // we want. If its defined, remove it. ++ if(atts.get("codebase") != null) { ++ atts.remove("codebase"); ++ } ++ ++ if (atts.get("width") == null) { ++ statusMsgStream.println(objectRequiresWidthWarning); ++ atts = null; ++ } else if (atts.get("height") == null) { ++ statusMsgStream.println(objectRequiresHeightWarning); ++ atts = null; ++ } ++ } ++ else if (nm.equalsIgnoreCase("embed")) { ++ isEmbedTag = true; ++ atts = scanTag(in); ++ ++ if (atts.get("code") == null && atts.get("object") == null) { ++ statusMsgStream.println(embedRequiresCodeWarning); ++ atts = null; ++ } else if (atts.get("width") == null) { ++ statusMsgStream.println(embedRequiresWidthWarning); ++ atts = null; ++ } else if (atts.get("height") == null) { ++ statusMsgStream.println(embedRequiresHeightWarning); ++ atts = null; ++ } ++ } ++ else if (nm.equalsIgnoreCase("app")) { ++ statusMsgStream.println(appNotLongerSupportedWarning); ++ Hashtable atts2 = scanTag(in); ++ nm = (String)atts2.get("class"); ++ if (nm != null) { ++ atts2.remove("class"); ++ atts2.put("code", nm + ".class"); ++ } ++ nm = (String)atts2.get("src"); ++ if (nm != null) { ++ atts2.remove("src"); ++ atts2.put("codebase", nm); ++ } ++ if (atts2.get("width") == null) { ++ atts2.put("width", "100"); ++ } ++ if (atts2.get("height") == null) { ++ atts2.put("height", "100"); ++ } ++ printTag(statusMsgStream, atts2); ++ statusMsgStream.println(); ++ } ++ } ++ } ++ } ++ in.close(); ++ } ++ ++ /** ++ * Old main entry point. ++ * ++ * @deprecated ++ */ ++ @Deprecated ++ public static void main(String args[]) throws IOException { ++ PluginMain.main(args); ++ } ++ ++ 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()); ++ } ++ } ++ } ++}
--- a/plugin/gcj/java/src/main/sun/applet/PluginAppletViewer.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1008 +0,0 @@ -/* - * Copyright 1995-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.util.*; -import java.io.*; -import java.awt.*; -import java.awt.event.*; -import java.awt.print.*; -import javax.print.attribute.*; -import java.applet.*; -import java.net.URL; -import java.net.MalformedURLException; -import java.net.SocketPermission; -import sun.misc.Ref; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import sun.awt.SunToolkit; -import sun.awt.AppContext; -import sun.awt.X11.*; -import java.lang.ref.WeakReference; -import net.sourceforge.jnlp.NetxPanel; - -/** - * Lets us construct one using unix-style one shot behaviors - */ - -class PluginAppletViewerFactory -{ - public PluginAppletViewer createAppletViewer(long handle, int x, int y, - URL doc, Hashtable atts) { - PluginAppletViewer pluginappletviewer = new PluginAppletViewer(handle, x, y, doc, atts, System.out, this); - PluginMain.registerWindow(pluginappletviewer); - return pluginappletviewer; - } - - public boolean isStandalone() - { - return false; - } -} - -/* - */ -public class PluginAppletViewer extends XEmbeddedFrame - implements AppletContext, Printable { - /** - * Some constants... - */ - private static String defaultSaveFile = "Applet.ser"; - - /** - * The panel in which the applet is being displayed. - */ - AppletViewerPanel panel; - - /** - * The status line. - */ - Label label; - - /** - * output status messages to this stream - */ - - PrintStream statusMsgStream; - - /** - * For cloning - */ - PluginAppletViewerFactory factory; - - /** - * Create the applet viewer - */ - public PluginAppletViewer(long handle, int x, int y, final URL doc, - final Hashtable atts, PrintStream statusMsgStream, - PluginAppletViewerFactory factory) { - super(handle, true); - this.factory = factory; - this.statusMsgStream = statusMsgStream; - - try { - panel = new NetxPanel(doc, atts); - AppletViewerPanel.debug("Using NetX panel"); - } catch (Exception ex) { - AppletViewerPanel.debug("Unable to start NetX applet - defaulting to Sun applet", ex); - panel = new AppletViewerPanel(doc, atts); - } - add("Center", panel); - panel.init(); - appletPanels.addElement(panel); - - pack(); - setVisible(true); - - WindowListener windowEventListener = new WindowAdapter() { - - public void windowClosing(WindowEvent evt) { - appletClose(); - } - - public void windowIconified(WindowEvent evt) { - appletStop(); - } - - public void windowDeiconified(WindowEvent evt) { - appletStart(); - } - }; - - class AppletEventListener implements AppletListener - { - final Frame frame; - - public AppletEventListener(Frame frame) - { - this.frame = frame; - } - - public void appletStateChanged(AppletEvent evt) - { - AppletPanel src = (AppletPanel)evt.getSource(); - - switch (evt.getID()) { - case AppletPanel.APPLET_RESIZE: { - if(src != null) { - resize(preferredSize()); - validate(); - } - break; - } - case AppletPanel.APPLET_LOADING_COMPLETED: { - Applet a = src.getApplet(); // sun.applet.AppletPanel - - // Fixed #4754451: Applet can have methods running on main - // thread event queue. - // - // The cause of this bug is that the frame of the applet - // is created in main thread group. Thus, when certain - // AWT/Swing events are generated, the events will be - // dispatched through the wrong event dispatch thread. - // - // To fix this, we rearrange the AppContext with the frame, - // so the proper event queue will be looked up. - // - // Swing also maintains a Frame list for the AppContext, - // so we will have to rearrange it as well. - // - if (a != null) - AppletPanel.changeFrameAppContext(frame, SunToolkit.targetToAppContext(a)); - else - AppletPanel.changeFrameAppContext(frame, AppContext.getAppContext()); - - break; - } - } - } - }; - - ComponentListener componentListener = new ComponentAdapter() { - public void componentResized(ComponentEvent event) - { - if (panel != null) - { - ComponentListener[] l = panel.getComponentListeners(); - for (int i = 0; i < l.length; i++) - l[i].componentResized(event); - panel.validate(); - } - } - - public void componentMoved(ComponentEvent event) - { - if (panel != null) - { - ComponentListener[] l = panel.getComponentListeners(); - for (int i = 0; i < l.length; i++) - l[i].componentMoved(event); - panel.validate(); - } - } - }; - - HierarchyBoundsListener hierarchyBoundsListener = new HierarchyBoundsAdapter() { - public void ancestorMoved(HierarchyEvent e) - { - if (panel != null) - { - HierarchyBoundsListener[] l = panel.getHierarchyBoundsListeners(); - for (int i = 0; i < l.length; i++) - l[i].ancestorMoved(e); - panel.validate(); - } - } - - public void ancestorResized(HierarchyEvent e) - { - if (panel != null) - { - HierarchyBoundsListener[] l = panel.getHierarchyBoundsListeners(); - for (int i = 0; i < l.length; i++) - l[i].ancestorResized(e); - panel.validate(); - } - } - }; - - addWindowListener(windowEventListener); - addComponentListener(componentListener); - addHierarchyBoundsListener(hierarchyBoundsListener); - panel.addAppletListener(new AppletEventListener(this)); - - // Start the applet - showStatus(amh.getMessage("status.start")); - initEventQueue(); - } - - /** - * Send the initial set of events to the appletviewer event queue. - * On start-up the current behaviour is to load the applet and call - * Applet.init() and Applet.start(). - */ - private void initEventQueue() { - // appletviewer.send.event is an undocumented and unsupported system - // property which is used exclusively for testing purposes. - String eventList = System.getProperty("appletviewer.send.event"); - - if (eventList == null) { - // Add the standard events onto the event queue. - panel.sendEvent(AppletPanel.APPLET_LOAD); - panel.sendEvent(AppletPanel.APPLET_INIT); - panel.sendEvent(AppletPanel.APPLET_START); - } else { - // We're testing AppletViewer. Force the specified set of events - // onto the event queue, wait for the events to be processed, and - // exit. - - // The list of events that will be executed is provided as a - // ","-separated list. No error-checking will be done on the list. - String [] events = splitSeparator(",", eventList); - - for (int i = 0; i < events.length; i++) { - System.out.println("Adding event to queue: " + events[i]); - if (events[i].equals("dispose")) - panel.sendEvent(AppletPanel.APPLET_DISPOSE); - else if (events[i].equals("load")) - panel.sendEvent(AppletPanel.APPLET_LOAD); - else if (events[i].equals("init")) - panel.sendEvent(AppletPanel.APPLET_INIT); - else if (events[i].equals("start")) - panel.sendEvent(AppletPanel.APPLET_START); - else if (events[i].equals("stop")) - panel.sendEvent(AppletPanel.APPLET_STOP); - else if (events[i].equals("destroy")) - panel.sendEvent(AppletPanel.APPLET_DESTROY); - else if (events[i].equals("quit")) - panel.sendEvent(AppletPanel.APPLET_QUIT); - else if (events[i].equals("error")) - panel.sendEvent(AppletPanel.APPLET_ERROR); - else - // non-fatal error if we get an unrecognized event - System.out.println("Unrecognized event name: " + events[i]); - } - - while (!panel.emptyEventQueue()) ; - appletSystemExit(); - } - } - - /** - * Split a string based on the presence of a specified separator. Returns - * an array of arbitrary length. The end of each element in the array is - * indicated by the separator of the end of the string. If there is a - * separator immediately before the end of the string, the final element - * will be empty. None of the strings will contain the separator. Useful - * when separating strings such as "foo/bar/bas" using separator "/". - * - * @param sep The separator. - * @param s The string to split. - * @return An array of strings. Each string in the array is determined - * by the location of the provided sep in the original string, - * s. Whitespace not stripped. - */ - private String [] splitSeparator(String sep, String s) { - Vector v = new Vector(); - int tokenStart = 0; - int tokenEnd = 0; - - while ((tokenEnd = s.indexOf(sep, tokenStart)) != -1) { - v.addElement(s.substring(tokenStart, tokenEnd)); - tokenStart = tokenEnd+1; - } - // Add the final element. - v.addElement(s.substring(tokenStart)); - - String [] retVal = new String[v.size()]; - v.copyInto(retVal); - return retVal; - } - - /* - * Methods for java.applet.AppletContext - */ - - private static Map audioClips = new HashMap(); - - /** - * Get an audio clip. - */ - public AudioClip getAudioClip(URL url) { - checkConnect(url); - synchronized (audioClips) { - AudioClip clip = (AudioClip)audioClips.get(url); - if (clip == null) { - audioClips.put(url, clip = new AppletAudioClip(url)); - } - return clip; - } - } - - private static Map imageRefs = new HashMap(); - - /** - * Get an image. - */ - public Image getImage(URL url) { - return getCachedImage(url); - } - - static Image getCachedImage(URL url) { - // System.getSecurityManager().checkConnection(url.getHost(), url.getPort()); - return (Image)getCachedImageRef(url).get(); - } - - /** - * Get an image ref. - */ - static Ref getCachedImageRef(URL url) { - synchronized (imageRefs) { - AppletImageRef ref = (AppletImageRef)imageRefs.get(url); - if (ref == null) { - ref = new AppletImageRef(url); - imageRefs.put(url, ref); - } - return ref; - } - } - - /** - * Flush the image cache. - */ - static void flushImageCache() { - imageRefs.clear(); - } - - static Vector appletPanels = new Vector(); - - /** - * Get an applet by name. - */ - public Applet getApplet(String name) { - AppletSecurity security = (AppletSecurity)System.getSecurityManager(); - name = name.toLowerCase(); - SocketPermission panelSp = - new SocketPermission(panel.getCodeBase().getHost(), "connect"); - for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) { - AppletPanel p = (AppletPanel)e.nextElement(); - String param = p.getParameter("name"); - if (param != null) { - param = param.toLowerCase(); - } - if (name.equals(param) && - p.getDocumentBase().equals(panel.getDocumentBase())) { - - SocketPermission sp = - new SocketPermission(p.getCodeBase().getHost(), "connect"); - - if (panelSp.implies(sp)) { - return p.applet; - } - } - } - return null; - } - - /** - * Return an enumeration of all the accessible - * applets on this page. - */ - public Enumeration getApplets() { - AppletSecurity security = (AppletSecurity)System.getSecurityManager(); - Vector v = new Vector(); - SocketPermission panelSp = - new SocketPermission(panel.getCodeBase().getHost(), "connect"); - - for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) { - AppletPanel p = (AppletPanel)e.nextElement(); - if (p.getDocumentBase().equals(panel.getDocumentBase())) { - - SocketPermission sp = - new SocketPermission(p.getCodeBase().getHost(), "connect"); - if (panelSp.implies(sp)) { - v.addElement(p.applet); - } - } - } - return v.elements(); - } - - /** - * Ignore. - */ - public void showDocument(URL url) { - showDocument(url, "_self"); - } - - /** - * Ignore. - */ - public void showDocument(URL url, String target) { - try { - PluginMain.write("url " + url + " " + target); - } catch (IOException exception) { - // Deliberately ignore IOException. showDocument may be - // called from threads other than the main thread after - // PluginMain.pluginOutputStream has been closed. - } - } - - /** - * Show status. - */ - public void showStatus(String status) { - try { - PluginMain.write("status " + status); - } catch (IOException exception) { - // Deliberately ignore IOException. showStatus may be - // called from threads other than the main thread after - // PluginMain.pluginOutputStream has been closed. - } - } - - public void setStream(String key, InputStream stream)throws IOException{ - // We do nothing. - } - - public InputStream getStream(String key){ - // We do nothing. - return null; - } - - public Iterator getStreamKeys(){ - // We do nothing. - return null; - } - - /** - * System parameters. - */ - static Hashtable systemParam = new Hashtable(); - - static { - systemParam.put("codebase", "codebase"); - systemParam.put("code", "code"); - systemParam.put("alt", "alt"); - systemParam.put("width", "width"); - systemParam.put("height", "height"); - systemParam.put("align", "align"); - systemParam.put("vspace", "vspace"); - systemParam.put("hspace", "hspace"); - } - - /** - * Print the HTML tag. - */ - public static void printTag(PrintStream out, Hashtable atts) { - out.print("<applet"); - - String v = (String)atts.get("codebase"); - if (v != null) { - out.print(" codebase=\"" + v + "\""); - } - - v = (String)atts.get("code"); - if (v == null) { - v = "applet.class"; - } - out.print(" code=\"" + v + "\""); - v = (String)atts.get("width"); - if (v == null) { - v = "150"; - } - out.print(" width=" + v); - - v = (String)atts.get("height"); - if (v == null) { - v = "100"; - } - out.print(" height=" + v); - - v = (String)atts.get("name"); - if (v != null) { - out.print(" name=\"" + v + "\""); - } - out.println(">"); - - // A very slow sorting algorithm - int len = atts.size(); - String params[] = new String[len]; - len = 0; - for (Enumeration e = atts.keys() ; e.hasMoreElements() ;) { - String param = (String)e.nextElement(); - int i = 0; - for (; i < len ; i++) { - if (params[i].compareTo(param) >= 0) { - break; - } - } - System.arraycopy(params, i, params, i + 1, len - i); - params[i] = param; - len++; - } - - for (int i = 0 ; i < len ; i++) { - String param = params[i]; - if (systemParam.get(param) == null) { - out.println("<param name=" + param + - " value=\"" + atts.get(param) + "\">"); - } - } - out.println("</applet>"); - } - - /** - * Make sure the attributes are up-to-date. - */ - public void updateAtts(int width, int height) { - panel.atts.remove("width"); - panel.atts.remove("height"); - panel.atts.put("width", new Integer(width).toString()); - panel.atts.put("height", new Integer(height).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] - */ - AppletPanel.flushClassLoader(panel.getClassLoaderCacheKey()); - - /* - * Make sure we don't have two threads running through the event queue - * at the same time. - */ - try { - panel.joinAppletThread(); - panel.release(); - } catch (InterruptedException e) { - return; // abort the reload - } - - panel.createAppletThread(); - panel.sendEvent(AppletPanel.APPLET_LOAD); - panel.sendEvent(AppletPanel.APPLET_INIT); - panel.sendEvent(AppletPanel.APPLET_START); - } - - 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() - { - appletShutdown(p); - appletPanels.removeElement(p); - dispose(); - - if (countApplets() == 0) { - appletSystemExit(); - } - } - }).start(); - } - - /** - * Exit the program. - * Exit from the program (if not stand alone) - do no clean-up - */ - private void appletSystemExit() { - if (factory.isStandalone()) - System.exit(0); - } - - /** - * How many applets are running? - */ - - public static int countApplets() { - return appletPanels.size(); - } - - - /** - * The current character. - */ - static int c; - - /** - * Scan spaces. - */ - public static void skipSpace(Reader in) throws IOException { - while ((c >= 0) && - ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'))) { - c = in.read(); - } - } - - /** - * Scan identifier - */ - public static String scanIdentifier(Reader in) throws IOException { - StringBuffer buf = new StringBuffer(); - while (true) { - if (((c >= 'a') && (c <= 'z')) || - ((c >= 'A') && (c <= 'Z')) || - ((c >= '0') && (c <= '9')) || (c == '_')) { - buf.append((char)c); - c = in.read(); - } else { - return buf.toString(); - } - } - } - - /** - * Scan tag - */ - public static Hashtable scanTag(Reader in) throws IOException { - Hashtable atts = new Hashtable(); - skipSpace(in); - while (c >= 0 && c != '>') { - String att = scanIdentifier(in); - String val = ""; - skipSpace(in); - if (c == '=') { - int quote = -1; - c = in.read(); - skipSpace(in); - if ((c == '\'') || (c == '\"')) { - quote = c; - c = in.read(); - } - StringBuffer buf = new StringBuffer(); - while ((c > 0) && - (((quote < 0) && (c != ' ') && (c != '\t') && - (c != '\n') && (c != '\r') && (c != '>')) - || ((quote >= 0) && (c != quote)))) { - buf.append((char)c); - c = in.read(); - } - if (c == quote) { - c = in.read(); - } - skipSpace(in); - val = buf.toString(); - } - //statusMsgStream.println("PUT " + att + " = '" + val + "'"); - if (! val.equals("")) { - atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val); - } - while (true) { - if ((c == '>') || (c < 0) || - ((c >= 'a') && (c <= 'z')) || - ((c >= 'A') && (c <= 'Z')) || - ((c >= '0') && (c <= '9')) || (c == '_')) - break; - c = in.read(); - } - //skipSpace(in); - } - return atts; - } - - /* values used for placement of AppletViewer's frames */ - private static int x = 0; - private static int y = 0; - private static final int XDELTA = 30; - private static final int YDELTA = XDELTA; - - static String encoding = null; - - static private Reader makeReader(InputStream is) { - if (encoding != null) { - try { - return new BufferedReader(new InputStreamReader(is, encoding)); - } catch (IOException x) { } - } - InputStreamReader r = new InputStreamReader(is); - encoding = r.getEncoding(); - return new BufferedReader(r); - } - - /** - * Scan an html file for <applet> tags - */ - public static void parse(long handle, Reader in, URL url, String enc) - throws IOException { - encoding = enc; - parse(handle, 1, 1, in, url, System.out, new PluginAppletViewerFactory()); - } - - public static void parse(long handle, int width, int height, Reader in, URL url) - throws IOException { - parse(handle, width, height, - in, url, System.out, new PluginAppletViewerFactory()); - } - - public static void parse(long handle, int width, int height, Reader in, - URL url, - PrintStream statusMsgStream, - PluginAppletViewerFactory factory) - throws IOException - { - // <OBJECT> <EMBED> tag flags - boolean isAppletTag = false; - boolean isObjectTag = false; - boolean isEmbedTag = false; - - // warning messages - String requiresNameWarning = amh.getMessage("parse.warning.requiresname"); - String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside"); - String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode"); - String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight"); - String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth"); - String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode"); - String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight"); - String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth"); - String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode"); - String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight"); - String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth"); - String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported"); - - java.net.URLConnection conn = url.openConnection(); - /* The original URL may have been redirected - this - * sets it to whatever URL/codebase we ended up getting - */ - url = conn.getURL(); - - int ydisp = 1; - Hashtable atts = null; - - while(true) { - c = in.read(); - if (c == -1) - break; - - if (c == '<') { - c = in.read(); - if (c == '/') { - c = in.read(); - String nm = scanIdentifier(in); - if (nm.equalsIgnoreCase("applet") || - nm.equalsIgnoreCase("object") || - nm.equalsIgnoreCase("embed")) { - - // We can't test for a code tag until </OBJECT> - // because it is a parameter, not an attribute. - if(isObjectTag) { - if (atts.get("code") == null && atts.get("object") == null) { - statusMsgStream.println(objectRequiresCodeWarning); - atts = null; - } - } - - if (atts != null) { - atts.remove("width"); - atts.remove("height"); - atts.put("width", new Integer(width).toString()); - atts.put("height", new Integer(height).toString()); - - // XXX 5/18 In general this code just simply - // shouldn't be part of parsing. It's presence - // causes things to be a little too much of a - // hack. - factory.createAppletViewer(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(in); - if (nm.equalsIgnoreCase("param")) { - Hashtable t = scanTag(in); - String att = (String)t.get("name"); - if (att == null) { - statusMsgStream.println(requiresNameWarning); - } else { - String val = (String)t.get("value"); - if (val == null) { - statusMsgStream.println(requiresNameWarning); - } else if (atts != null) { - String name = att.toLowerCase(); - atts.put(name, val); - } else { - statusMsgStream.println(paramOutsideWarning); - } - } - } - else if (nm.equalsIgnoreCase("applet")) { - isAppletTag = true; - atts = scanTag(in); - if (atts.get("code") == null && atts.get("object") == null) { - statusMsgStream.println(appletRequiresCodeWarning); - atts = null; - } else if (atts.get("width") == null) { - statusMsgStream.println(appletRequiresWidthWarning); - atts = null; - } else if (atts.get("height") == null) { - statusMsgStream.println(appletRequiresHeightWarning); - atts = null; - } - } - else if (nm.equalsIgnoreCase("object")) { - isObjectTag = true; - atts = scanTag(in); - // The <OBJECT> attribute codebase isn't what - // we want. If its defined, remove it. - if(atts.get("codebase") != null) { - atts.remove("codebase"); - } - - if (atts.get("width") == null) { - statusMsgStream.println(objectRequiresWidthWarning); - atts = null; - } else if (atts.get("height") == null) { - statusMsgStream.println(objectRequiresHeightWarning); - atts = null; - } - } - else if (nm.equalsIgnoreCase("embed")) { - isEmbedTag = true; - atts = scanTag(in); - - if (atts.get("code") == null && atts.get("object") == null) { - statusMsgStream.println(embedRequiresCodeWarning); - atts = null; - } else if (atts.get("width") == null) { - statusMsgStream.println(embedRequiresWidthWarning); - atts = null; - } else if (atts.get("height") == null) { - statusMsgStream.println(embedRequiresHeightWarning); - atts = null; - } - } - else if (nm.equalsIgnoreCase("app")) { - statusMsgStream.println(appNotLongerSupportedWarning); - Hashtable atts2 = scanTag(in); - nm = (String)atts2.get("class"); - if (nm != null) { - atts2.remove("class"); - atts2.put("code", nm + ".class"); - } - nm = (String)atts2.get("src"); - if (nm != null) { - atts2.remove("src"); - atts2.put("codebase", nm); - } - if (atts2.get("width") == null) { - atts2.put("width", "100"); - } - if (atts2.get("height") == null) { - atts2.put("height", "100"); - } - printTag(statusMsgStream, atts2); - statusMsgStream.println(); - } - } - } - } - in.close(); - } - - /** - * Old main entry point. - * - * @deprecated - */ - @Deprecated - public static void main(String args[]) throws IOException { - PluginMain.main(args); - } - - 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()); - } - } - } -}
--- a/plugin/gcj/java/src/main/sun/applet/PluginMain.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,274 +0,0 @@ -/* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.io.*; -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; -import java.net.*; -import java.nio.charset.Charset; -import java.util.*; -import sun.net.www.ParseUtil; - -class PluginParseRequest -{ - long handle; - String tag; - String documentbase; - boolean alreadySent; -} - -/** - * The main entry point into PluginAppletViewer. - */ -public class PluginMain -{ - // A mapping of instance IDs to PluginAppletViewers. - private static HashMap appletWindows = new HashMap(); - private static HashMap parseRequests = new HashMap(); - private static String currentKey; - private static PluginAppletViewer currentWindow; - private static PluginParseRequest currentRequest; - private static BufferedReader pluginInputStream; - private static BufferedWriter pluginOutputStream; - // This is used in init(). Getting rid of this is desirable but depends - // on whether the property that uses it is necessary/standard. - public static final String theVersion = System.getProperty("java.version"); - - /** - * The main entry point into AppletViewer. - */ - public static void main(String args[]) - throws IOException - { - if(args.length != 2) { - // Indicate to plugin that appletviewer is installed correctly. - System.exit(0); - } - // INSTALL THE SECURITY MANAGER - init(); - start(new FileInputStream(args[0]), new FileOutputStream(args[1])); - System.exit(0); - } - - private static void init() { - Properties avProps = new Properties(); - - // ADD OTHER RANDOM PROPERTIES - // XXX 5/18 need to revisit why these are here, is there some - // standard for what is available? - - // Standard browser properties - avProps.put("browser", "sun.applet.AppletViewer"); - avProps.put("browser.version", "1.06"); - avProps.put("browser.vendor", "Sun Microsystems Inc."); - avProps.put("http.agent", "Java(tm) 2 SDK, Standard Edition v" + theVersion); - - // Define which packages can be extended by applets - // XXX 5/19 probably not needed, not checked in AppletSecurity - avProps.put("package.restrict.definition.java", "true"); - avProps.put("package.restrict.definition.sun", "true"); - - // Define which properties can be read by applets. - // A property named by "key" can be read only when its twin - // property "key.applet" is true. The following ten properties - // are open by default. Any other property can be explicitly - // opened up by the browser user by calling appletviewer with - // -J-Dkey.applet=true - avProps.put("java.version.applet", "true"); - avProps.put("java.vendor.applet", "true"); - avProps.put("java.vendor.url.applet", "true"); - avProps.put("java.class.version.applet", "true"); - avProps.put("os.name.applet", "true"); - avProps.put("os.version.applet", "true"); - avProps.put("os.arch.applet", "true"); - avProps.put("file.separator.applet", "true"); - avProps.put("path.separator.applet", "true"); - avProps.put("line.separator.applet", "true"); - - // Read in the System properties. If something is going to be - // over-written, warn about it. - Properties sysProps = System.getProperties(); - for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements(); ) { - String key = (String) e.nextElement(); - String val = (String) sysProps.getProperty(key); - avProps.setProperty(key, val); - } - - // INSTALL THE PROPERTY LIST - System.setProperties(avProps); - - // Create and install the security manager - System.setSecurityManager(new AppletSecurity()); - - // REMIND: Create and install a socket factory! - } - - static void registerWindow(PluginAppletViewer pluginappletviewer) - { - appletWindows.put(currentKey, pluginappletviewer); - currentWindow = (PluginAppletViewer)appletWindows.get(currentKey); - } - - private static void deregisterWindow(PluginAppletViewer pluginappletviewer) - { - appletWindows.remove(currentWindow); - currentWindow.dispose(); - currentWindow = null; - } - - static void start(InputStream inputstream, OutputStream outputstream) - throws MalformedURLException, IOException - { - // Set up input and output pipes. Use UTF-8 encoding. - pluginInputStream = - new BufferedReader(new InputStreamReader(inputstream, - Charset.forName("UTF-8"))); - pluginOutputStream = - new BufferedWriter(new OutputStreamWriter - (outputstream, Charset.forName("UTF-8"))); - - write("running"); - - // Read first message. - String message = read(); - - while(true) { - if (message.startsWith("instance")) { - // Read applet instance identifier. - currentKey = message.substring("instance".length() + 1); - currentWindow = - (PluginAppletViewer)appletWindows.get(currentKey); - currentRequest = null; - if (currentWindow == null) { - if (!parseRequests.containsKey(currentKey)) - parseRequests.put(currentKey, new PluginParseRequest()); - currentRequest = - (PluginParseRequest)parseRequests.get(currentKey); - } - } else if (message.startsWith("tag")) { - if (currentRequest != null) { - int index = message.indexOf(' ', "tag".length() + 1); - currentRequest.documentbase = - message.substring("tag".length() + 1, index); - currentRequest.tag = message.substring(index + 1); - if (currentRequest.handle != 0 - && !currentRequest.alreadySent) { - PluginAppletViewer.parse - (currentRequest.handle, 1, 1, - new StringReader(currentRequest.tag), - new URL(currentRequest.documentbase)); - parseRequests.remove(currentKey); - } - } - } else if (message.startsWith("handle")) { - if (currentRequest != null) { - currentRequest.handle = Long.parseLong - (message.substring("handle".length() + 1, - message.indexOf("width") - 1)); - int width = Integer.parseInt(message.substring - (message.indexOf("width") + - "width".length() + 1, - message.indexOf("height") - 1)); - int height = Integer.parseInt(message.substring( - message.indexOf("height") + - "height".length() + 1)); - if (currentRequest.tag != null - && !currentRequest.alreadySent) { - PluginAppletViewer.parse - (currentRequest.handle, width, height, - new StringReader(currentRequest.tag), - new URL(currentRequest.documentbase)); - parseRequests.remove(currentKey); - } - } - } else if (message.startsWith("width")) { - int width = - Integer.parseInt(message.substring("width".length() + 1)); - int height = currentWindow.getHeight(); - currentWindow.updateAtts(width, height); - currentWindow.setSize(width, height); - } else if (message.startsWith("height")) { - int height = - Integer.parseInt(message.substring("height".length() + 1)); - int width = currentWindow.getWidth(); - currentWindow.updateAtts(width, height); - currentWindow.setSize(width, height); - } else if (message.startsWith("destroy") - && currentWindow != null) { - deregisterWindow(currentWindow); - } - - // Read next message. - message = read(); - } - } - - /** - * Write string to plugin. - * - * @param message the message to write - * - * @exception IOException if an error occurs - */ - static void write(String message) - throws IOException - { - pluginOutputStream.write(message, 0, message.length()); - pluginOutputStream.newLine(); - pluginOutputStream.flush(); - - System.err.println(" PIPE: appletviewer wrote: " + message); - } - - /** - * Read string from plugin. - * - * @return the read string - * - * @exception IOException if an error occurs - */ - static String read() - throws IOException - { - String message = pluginInputStream.readLine(); - System.err.println(" PIPE: appletviewer read: " + message); - if (message == null || message.equals("shutdown")) { - try { - // Close input/output channels to plugin. - pluginInputStream.close(); - pluginOutputStream.close(); - } catch (IOException exception) { - // Deliberately ignore IOException caused by broken - // pipe since plugin may have already detached. - } - - System.err.println("APPLETVIEWER: exiting appletviewer"); - System.exit(0); - } - return message; - } -}
--- a/plugin/icedtea/java/src/main/netscape/javascript/JSException.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package netscape.javascript; - -/** - * JSException is an exception which is thrown when JavaScript code - * returns an error. - */ - -public -class JSException extends RuntimeException { - public static final int EXCEPTION_TYPE_EMPTY = -1; - public static final int EXCEPTION_TYPE_VOID = 0; - public static final int EXCEPTION_TYPE_OBJECT = 1; - public static final int EXCEPTION_TYPE_FUNCTION = 2; - public static final int EXCEPTION_TYPE_STRING = 3; - public static final int EXCEPTION_TYPE_NUMBER = 4; - public static final int EXCEPTION_TYPE_BOOLEAN = 5; - public static final int EXCEPTION_TYPE_ERROR = 6; - - public String filename; - public int lineno; - public String source; - public int tokenIndex; - public int wrappedExceptionType; - public Object wrappedException; - - /** - * Constructs a JSException without a detail message. - * A detail message is a String that describes this particular exception. - * - * @deprecated Not for public use in future versions. - */ - public JSException() { - super(); - filename = "unknown"; - lineno = 0; - source = ""; - tokenIndex = 0; - wrappedExceptionType = EXCEPTION_TYPE_EMPTY; - } - - /** - * Constructs a JSException with a detail message. - * A detail message is a String that describes this particular exception. - * @param s the detail message - * - * @deprecated Not for public use in future versions. - */ - public JSException(String s) { - super(s); - filename = "unknown"; - lineno = 0; - source = ""; - tokenIndex = 0; - wrappedExceptionType = EXCEPTION_TYPE_EMPTY; - } - - /** - * Constructs a JSException with a wrapped JavaScript exception object. - * This constructor needs to be public so that Java users can throw - * exceptions to JS cleanly. - */ - public JSException(int wrappedExceptionType, Object wrappedException) { - super(); - this.wrappedExceptionType = wrappedExceptionType; - this.wrappedException = wrappedException; - } - - /** - * Constructs a JSException with a detail message and all the - * other info that usually comes with a JavaScript error. - * @param s the detail message - * - * @deprecated Not for public use in future versions. - */ - public JSException(String s, String filename, int lineno, - String source, int tokenIndex) { - super(s); - this.filename = filename; - this.lineno = lineno; - this.source = source; - this.tokenIndex = tokenIndex; - wrappedExceptionType = EXCEPTION_TYPE_EMPTY; - } - - /** - * Instance method getWrappedExceptionType returns the int mapping of the - * type of the wrappedException Object. - */ - public int getWrappedExceptionType() { - return wrappedExceptionType; - } - - /** - * Instance method getWrappedException. - */ - public Object getWrappedException() { - return wrappedException; - } - -} -
--- a/plugin/icedtea/java/src/main/netscape/javascript/JSObject.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,258 +0,0 @@ -/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* more doc todo: - * threads - * gc - * - * - */ - -package netscape.javascript; - -import java.applet.Applet; -import java.io.IOException; -import sun.applet.PluginAppletViewer; - -/** - * JSObject allows Java to manipulate objects that are - * defined in JavaScript. - * Values passed from Java to JavaScript are converted as - * follows:<ul> - * <li>JSObject is converted to the original JavaScript object - * <li>Any other Java object is converted to a JavaScript wrapper, - * which can be used to access methods and fields of the java object. - * Converting this wrapper to a string will call the toString method - * on the original object, converting to a number will call the - * doubleValue method if possible and fail otherwise. Converting - * to a boolean will try to call the booleanValue method in the - * same way. - * <li>Java arrays are wrapped with a JavaScript object that understands - * array.length and array[index] - * <li>A Java boolean is converted to a JavaScript boolean - * <li>Java byte, char, short, int, long, float, and double are converted - * to JavaScript numbers - * </ul> - * Values passed from JavaScript to Java are converted as follows:<ul> - * <li>objects which are wrappers around java objects are unwrapped - * <li>other objects are wrapped with a JSObject - * <li>strings, numbers and booleans are converted to String, Double, - * and Boolean objects respectively - * </ul> - * This means that all JavaScript values show up as some kind - * of java.lang.Object in Java. In order to make much use of them, - * you will have to cast them to the appropriate subclass of Object, - * e.g. <code>(String) window.getMember("name");</code> or - * <code>(JSObject) window.getMember("document");</code>. - */ -public final class JSObject { - /* the internal object data */ - private int internal; - private long long_internal; - - /** - * initialize - */ - private static void initClass() { - System.err.println ("JSObject.initClass"); - } - - static { - System.err.println ("JSObject INITIALIZER"); - } - - /** - * it is illegal to construct a JSObject manually - */ - // FIXME: make private! - public JSObject(int jsobj_addr) { - System.err.println ("JSObject int CONSTRUCTOR"); - internal = jsobj_addr; - } - - private JSObject(long jsobj_addr) { - System.err.println ("JSObject long CONSTRUCTOR"); - long_internal = jsobj_addr; - } - - /** - * Retrieves a named member of a JavaScript object. - * Equivalent to "this.<i>name</i>" in JavaScript. - */ - public Object getMember(String name) - { - System.err.println ("JSObject.getMember " + name); - - Object o = PluginAppletViewer.getMember(internal, name); - System.out.println ("JSObject.getMember GOT " + o); - return o; - } - - - /** - * Retrieves an indexed member of a JavaScript object. - * Equivalent to "this[<i>index</i>]" in JavaScript. - */ - // public Object getMember(int index) { return getSlot(index); } - public Object getSlot(int index) - { - System.err.println ("JSObject.getSlot " + index); - - return PluginAppletViewer.getSlot(internal, index); - } - - - /** - * Sets a named member of a JavaScript object. - * Equivalent to "this.<i>name</i> = <i>value</i>" in JavaScript. - */ - public void setMember(String name, Object value) - { - System.err.println ("JSObject.setMember " + name + " " + value); - - PluginAppletViewer.setMember(internal, name, value); - } - - /** - * Sets an indexed member of a JavaScript object. - * Equivalent to "this[<i>index</i>] = <i>value</i>" in JavaScript. - */ - // public void setMember(int index, Object value) { - // setSlot(index, value); - // } - public void setSlot(int index, Object value) - { - System.err.println ("JSObject.setSlot " + index + " " + value); - - PluginAppletViewer.setSlot(internal, index, value); - } - - - // TODO: toString, finalize. - - /** - * Removes a named member of a JavaScript object. - */ - public void removeMember(String name) - { - System.err.println ("JSObject.removeMember " + name); - - PluginAppletViewer.removeMember(internal, name); - } - - - /** - * Calls a JavaScript method. - * Equivalent to "this.<i>methodName</i>(<i>args</i>[0], <i>args</i>[1], ...)" in JavaScript. - */ - public Object call(String methodName, Object args[]) - { - System.err.print ("JSObject.call " + methodName); - for (int i = 0; i < args.length; i++) - System.err.print (" " + args[i]); - System.err.println(""); - return PluginAppletViewer.call(internal, methodName, args); - } - - - /** - * Evaluates a JavaScript expression. The expression is a string - * of JavaScript source code which will be evaluated in the context - * given by "this". - */ - public Object eval(String s) - { - System.err.println("JSObject.eval " + s); - return PluginAppletViewer.eval(internal, s); - } - - - /** - * Converts a JSObject to a String. - */ - public String toString() - { - System.err.println("JSObject.toString"); - return PluginAppletViewer.javascriptToString(internal); - } - - - // should use some sort of identifier rather than String - // is "property" the right word? - // native String[] listProperties(); - - - /** - * get a JSObject for the window containing the given applet - */ - public static JSObject getWindow(Applet applet) - { - System.err.println("JSObject.getWindow"); - // FIXME: handle long case as well. - int internal = 0; - internal = ((PluginAppletViewer) - applet.getAppletContext()).getWindow(); - System.out.println ("GOT IT: " + internal); - return new JSObject(internal); - } - - - /** - * Finalization decrements the reference count on the corresponding - * JavaScript object. - */ - protected void finalize() - { - System.err.println("JSObject.finalize "); - PluginAppletViewer.JavaScriptFinalize(internal); - } - - - /** - * Override java.lang.Object.equals() because identity is not preserved - * with instances of JSObject. - */ - public boolean equals(Object obj) - { - System.err.println("JSObject.equals " + obj); - - return false; - } - -}
--- a/plugin/icedtea/java/src/main/netscape/javascript/JSProxy.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/** - * The JSProxy interface allows applets and plugins to - * share javascript contexts. - */ - -package netscape.javascript; -import java.applet.Applet; - -public interface JSProxy { - Object getMember(JSObject jso, String name); - Object getSlot(JSObject jso, int index); - void setMember(JSObject jso, String name, Object value); - void setSlot(JSObject jso, int index, Object value); - void removeMember(JSObject jso, String name); - Object call(JSObject jso, String methodName, Object args[]); - Object eval(JSObject jso, String s); - String toString(JSObject jso); - JSObject getWindow(Applet applet); -}
--- a/plugin/icedtea/java/src/main/netscape/javascript/JSRunnable.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package netscape.javascript; - -/** - * Runs a JavaScript object with a run() method in a separate thread. - */ -public class JSRunnable implements Runnable { - private JSObject runnable; - - public JSRunnable(JSObject runnable) { - this.runnable = runnable; - synchronized(this) { - new Thread(this).start(); - try { - this.wait(); - } catch (InterruptedException ie) { - } - } - } - - public void run() { - try { - runnable.call("run", null); - synchronized(this) { - notifyAll(); - } - } catch (Throwable t) { - System.err.println(t); - t.printStackTrace(System.err); - } - } -}
--- a/plugin/icedtea/java/src/main/netscape/javascript/JSUtil.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* ** */ - -package netscape.javascript; -import java.io.*; - -public class JSUtil { - - /* Return the stack trace of an exception or error as a String */ - public static String getStackTrace(Throwable t) { - ByteArrayOutputStream captureStream; - PrintWriter p; - - captureStream = new ByteArrayOutputStream(); - p = new PrintWriter(captureStream); - - t.printStackTrace(p); - p.flush(); - - return captureStream.toString(); - } -}
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* GetMemberPluginCallRequest -- represent Java-to-JavaScript requests - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -import sun.applet.AppletSecurityContextManager; -import sun.applet.PluginCallRequest; - -public class GetMemberPluginCallRequest extends PluginCallRequest { - Object object = null; - - public GetMemberPluginCallRequest(String message, String returnString) { - super(message, returnString); - System.out.println ("GetMEMBerPLUGINCAlL " + message + " " + returnString); - } - - public void parseReturn(String message) { - System.out.println ("GetMEMBerparseReturn GOT: " + message); - String[] args = message.split(" "); - // FIXME: add thread ID to messages to support multiple - // threads using the netscape.javascript package. - object = AppletSecurityContextManager.getSecurityContext(0).getObject(Integer.parseInt(args[1])); - setDone(true); - } - - /** - * Returns whether the given message is serviceable by this object - * - * @param message The message to service - * @return boolean indicating if message is serviceable - */ - public boolean serviceable(String message) { - return message.contains("JavaScriptCall") || - message.contains("JavaScriptEval") || - message.contains("JavaScriptGetMember") || - message.contains("JavaScriptGetSlot") || - message.contains("JavaScriptToString"); - } - - public Object getObject() { - return this.object; - } -} -
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* GetWindowPluginCallRequest -- represent Java-to-JavaScript requests - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -import java.security.AccessControlContext; -import java.security.ProtectionDomain; - -import sun.applet.PluginCallRequest; - - -public class GetWindowPluginCallRequest extends PluginCallRequest { - // FIXME: look into int vs long JavaScript internal values. - int internal; - - public GetWindowPluginCallRequest(String message, String returnString) { - super(message, returnString); - } - - public void parseReturn(String message) { - System.out.println ("GetWINDOWparseReturn GOT: " + message); - String[] args = message.split(" "); - // FIXME: add thread ID to messages to support multiple - // threads using the netscape.javascript package. - internal = Integer.parseInt(args[1]); - setDone(true); - } - - /** - * Returns whether the given message is serviceable by this object - * - * @param message The message to service - * @return boolean indicating if message is serviceable - */ - public boolean serviceable(String message) { - return message.contains("JavaScriptGetWindow"); - } - - public Integer getObject() { - return this.internal; - } -}
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,855 +0,0 @@ -/* PluginAppletSecurityContext -- execute plugin JNI messages - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -import java.io.FilePermission; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.StringTokenizer; - -import sun.applet.AppletSecurityContext; -import sun.applet.PluginDebug; -import sun.applet.PluginException; - - -class Signature { - private String signature; - private int currentIndex; - private List<Class> typeList; - private static final char ARRAY = '['; - private static final char OBJECT = 'L'; - private static final char SIGNATURE_ENDCLASS = ';'; - private static final char SIGNATURE_FUNC = '('; - private static final char SIGNATURE_ENDFUNC = ')'; - private static final char VOID = 'V'; - private static final char BOOLEAN = 'Z'; - private static final char BYTE = 'B'; - private static final char CHARACTER = 'C'; - private static final char SHORT = 'S'; - private static final char INTEGER = 'I'; - private static final char LONG = 'J'; - private static final char FLOAT = 'F'; - private static final char DOUBLE = 'D'; - - private String nextTypeName() { - char key = signature.charAt(currentIndex++); - - switch (key) { - case ARRAY: - return nextTypeName() + "[]"; - - case OBJECT: - int endClass = signature.indexOf(SIGNATURE_ENDCLASS, currentIndex); - String retVal = signature.substring(currentIndex, endClass); - retVal = retVal.replace('/', '.'); - currentIndex = endClass + 1; - return retVal; - - // FIXME: generated bytecode with classes named after - // primitives will not work in this scheme -- those - // classes will be incorrectly treated as primitive - // types. - case VOID: - return "void"; - case BOOLEAN: - return "boolean"; - case BYTE: - return "byte"; - case CHARACTER: - return "char"; - case SHORT: - return "short"; - case INTEGER: - return "int"; - case LONG: - return "long"; - case FLOAT: - return "float"; - case DOUBLE: - return "double"; - - case SIGNATURE_ENDFUNC: - case SIGNATURE_FUNC: - return nextTypeName(); - - default: - throw new IllegalArgumentException( - "Invalid JNI signature character '" + key + "'"); - } - } - - public Signature(String signature, String src) { - this.signature = signature; - currentIndex = 0; - typeList = new ArrayList<Class>(10); - - String elem; - while (currentIndex < signature.length()) { - elem = nextTypeName(); - // System.out.println ("NEXT TYPE: " + elem); - Class primitive = primitiveNameToType(elem); - if (primitive != null) - typeList.add(primitive); - else { - // System.out.println ("HERE1"); - int dimsize = 0; - int n = elem.indexOf('['); - if (n != -1) { - // System.out.println ("HERE2"); - String arrayType = elem.substring(0, n); - dimsize++; - n = elem.indexOf('[', n + 1); - // System.out.println ("HERE2.5"); - while (n != -1) { - dimsize++; - n = elem.indexOf('[', n + 1); - // System.out.println ("HERE2.8"); - } - int[] dims = new int[dimsize]; - primitive = primitiveNameToType(arrayType); - // System.out.println ("HERE3"); - if (primitive != null) { - typeList.add(Array.newInstance(primitive, dims) - .getClass()); - // System.out.println ("HERE4"); - } else - typeList.add(Array.newInstance( - getClass(arrayType, src), dims).getClass()); - } else { - typeList.add(getClass(elem, src)); - } - } - } - if (typeList.size() == 0) { - throw new IllegalArgumentException("Invalid JNI signature '" - + signature + "'"); - } - } - - public static Class getClass(String name, String src) { - - Class c = null; - - try { - c = Class.forName(name); - } catch (ClassNotFoundException cnfe) { - - StringTokenizer st = new StringTokenizer(src, ","); - - while (st.hasMoreTokens()) { - - String tok = st.nextToken(); - System.err.println("Searching for " + name + " at key " + tok); - - try { - c = PluginAppletSecurityContext.classLoaders.get(tok).loadClass(name); - } catch (ClassNotFoundException e) { - // do nothing .. thrown below - } - - if (c != null) - break; - } - } - - if (c == null) { - throw (new RuntimeException(new ClassNotFoundException("Unable to find class " + name))); - } - - return c; - } - - public static Class primitiveNameToType(String name) { - if (name.equals("void")) - return Void.TYPE; - else if (name.equals("boolean")) - return Boolean.TYPE; - else if (name.equals("byte")) - return Byte.TYPE; - else if (name.equals("char")) - return Character.TYPE; - else if (name.equals("short")) - return Short.TYPE; - else if (name.equals("int")) - return Integer.TYPE; - else if (name.equals("long")) - return Long.TYPE; - else if (name.equals("float")) - return Float.TYPE; - else if (name.equals("double")) - return Double.TYPE; - else - return null; - } - - public Class[] getClassArray() { - return typeList.subList(0, typeList.size() - 1).toArray(new Class[] {}); - } -} - -public class PluginAppletSecurityContext extends AppletSecurityContext { - - public static HashMap<String, ClassLoader> classLoaders = new HashMap<String, ClassLoader>(); - - // FIXME: make private - public PluginObjectStore store = new PluginObjectStore(); - private Throwable throwable = null; - private ClassLoader liveconnectLoader = ClassLoader.getSystemClassLoader(); - int identifier = 0; - - public PluginAppletSecurityContext(int identifier) { - this.identifier = identifier; - } - - private static <V> V parseCall(String s, String src, Class<V> c) { - if (c == Integer.class) - return (V) new Integer(s); - else if (c == String.class) - return (V) new String(s); - else if (c == Signature.class) - return (V) new Signature(s, src); - else - throw new RuntimeException("Unexpected call value."); - } - - private Object parseArgs(String s, Class c) { - if (c == Boolean.TYPE || c == Boolean.class) - return new Boolean(s); - else if (c == Byte.TYPE || c == Byte.class) - return new Byte(s); - else if (c == Character.TYPE || c == Character.class) { - String[] bytes = s.split("_"); - int low = Integer.parseInt(bytes[0]); - int high = Integer.parseInt(bytes[1]); - int full = ((high << 8) & 0x0ff00) | (low & 0x0ff); - return new Character((char) full); - } else if (c == Short.TYPE || c == Short.class) - return new Short(s); - else if (c == Integer.TYPE || c == Integer.class) - return new Integer(s); - else if (c == Long.TYPE || c == Long.class) - return new Long(s); - else if (c == Float.TYPE || c == Float.class) - return new Float(s); - else if (c == Double.TYPE || c == Double.class) - return new Double(s); - else - return store.getObject(new Integer(s)); - } - - public void addClassLoader(String id, ClassLoader cl) { - this.classLoaders.put(id, cl); - } - - public void handleMessage(String src, int reference, String message) { - - try { - if (message.startsWith("FindClass")) { - ClassLoader cl = null; - Class c = null; - cl = liveconnectLoader; - String className = message.substring("FindClass".length() + 1) - .replace('/', '.'); - - try { - c = cl.loadClass(className); - store.reference(c); - write(reference, "FindClass " + store.getIdentifier(c)); - } catch (ClassNotFoundException cnfe) { - write(reference, "FindClass 0"); - } - - } else if (message.startsWith("GetStaticMethodID") - || message.startsWith("GetMethodID")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - String methodName = parseCall(args[2], src, String.class); - Signature signature = parseCall(args[3], src, Signature.class); - Object[] a = signature.getClassArray(); - - Class c = (Class) store.getObject(classID); - Method m = null; - Constructor cs = null; - Object o = null; - if (methodName.equals("<init>") - || methodName.equals("<clinit>")) { - o = cs = c.getConstructor(signature.getClassArray()); - store.reference(cs); - } else { - o = m = c.getMethod(methodName, signature.getClassArray()); - store.reference(m); - } - PluginDebug.debug(o + " has id " + store.getIdentifier(o)); - write(reference, args[0] + " " + store.getIdentifier(o)); - } else if (message.startsWith("GetStaticFieldID") - || message.startsWith("GetFieldID")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - String fieldName = parseCall(args[2], src, String.class); - Signature signature = parseCall(args[3], src, Signature.class); - - Class c = (Class) store.getObject(classID); - Field f = null; - f = c.getField(fieldName); - - store.reference(f); - - write(reference, "GetStaticFieldID " + store.getIdentifier(f)); - } else if (message.startsWith("GetStaticField")) { - String[] args = message.split(" "); - String type = parseCall(args[1], src, String.class); - Integer classID = parseCall(args[1], src, Integer.class); - Integer fieldID = parseCall(args[2], src, Integer.class); - - Class c = (Class) store.getObject(classID); - Field f = (Field) store.getObject(fieldID); - - Object ret = null; - ret = f.get(c); - - // System.out.println ("FIELD VALUE: " + ret); - if (ret == null) { - write(reference, "GetStaticField 0"); - } else if (f.getType() == Boolean.TYPE - || f.getType() == Byte.TYPE - || f.getType() == Character.TYPE - || f.getType() == Short.TYPE - || f.getType() == Integer.TYPE - || f.getType() == Long.TYPE - || f.getType() == Float.TYPE - || f.getType() == Double.TYPE) { - write(reference, "GetStaticField " + ret); - } else { - // Track returned object. - store.reference(ret); - write(reference, "GetStaticField " - + store.getIdentifier(ret)); - } - } else if (message.startsWith("SetStaticField")) { - String[] args = message.split(" "); - String type = parseCall(args[1], src, String.class); - Integer classID = parseCall(args[2], src, Integer.class); - Integer fieldID = parseCall(args[3], src, Integer.class); - - Object value = null; - if (Signature.primitiveNameToType(type) != null) { - value = parseArgs(args[4], Signature - .primitiveNameToType(type)); - // System.out.println ("HERE1: " + value); - } else { - value = parseArgs(args[3], Object.class); - // System.out.println ("HERE2: " + value); - } - - Class c = (Class) store.getObject(classID); - Field f = (Field) store.getObject(fieldID); - - f.set(c, value); - - write(reference, "SetStaticField"); - } else if (message.startsWith("SetField")) { - String[] args = message.split(" "); - String type = parseCall(args[1], src, String.class); - Integer objectID = parseCall(args[2], src, Integer.class); - Integer fieldID = parseCall(args[3], src, Integer.class); - - Object value = null; - if (Signature.primitiveNameToType(type) != null) { - value = parseArgs(args[4], Signature - .primitiveNameToType(type)); - // System.out.println ("HERE1: " + value); - } else { - value = parseArgs(args[3], Object.class); - // System.out.println ("HERE2: " + value); - } - - Object o = (Object) store.getObject(objectID); - Field f = (Field) store.getObject(fieldID); - - f.set(o, value); - - write(reference, "SetField"); - } else if (message.startsWith("GetObjectArrayElement")) { - String[] args = message.split(" "); - Integer arrayID = parseCall(args[1], src, Integer.class); - Integer index = parseCall(args[2], src, Integer.class); - - Object[] o = (Object[]) store.getObject(arrayID); - Object ret = null; - - ret = o[index]; - - // Track returned object. - store.reference(ret); - // System.out.println ("array element: " + index + " " + ret); - write(reference, "GetObjectArrayElement " - + store.getIdentifier(ret)); - } else if (message.startsWith("SetObjectArrayElement")) { - String[] args = message.split(" "); - Integer arrayID = parseCall(args[1], src, Integer.class); - Integer index = parseCall(args[2], src, Integer.class); - Integer objectID = parseCall(args[3], src, Integer.class); - - Object[] o = (Object[]) store.getObject(arrayID); - Object toSet = (Object) store.getObject(objectID); - - o[index] = toSet; - - write(reference, "SetObjectArrayElement"); - } else if (message.startsWith("GetArrayLength")) { - String[] args = message.split(" "); - Integer arrayID = parseCall(args[1], src, Integer.class); - - System.out.println("ARRAYID: " + arrayID); - Object o = (Object) store.getObject(arrayID); - int len = 0; - len = Array.getLength(o); - // System.out.println ("Returning array length: " + len); - - // System.out.println ("array length: " + o + " " + len); - write(reference, "GetArrayLength " + Array.getLength(o)); - } else if (message.startsWith("GetField")) { - String[] args = message.split(" "); - String type = parseCall(args[1], src, String.class); - Integer objectID = parseCall(args[1], src, Integer.class); - Integer fieldID = parseCall(args[2], src, Integer.class); - - Object o = (Object) store.getObject(objectID); - Field f = (Field) store.getObject(fieldID); - - Object ret = null; - ret = f.get(o); - - // System.out.println ("FIELD VALUE: " + ret); - if (ret == null) { - write(reference, "GetField 0"); - } else if (f.getType() == Boolean.TYPE - || f.getType() == Byte.TYPE - || f.getType() == Character.TYPE - || f.getType() == Short.TYPE - || f.getType() == Integer.TYPE - || f.getType() == Long.TYPE - || f.getType() == Float.TYPE - || f.getType() == Double.TYPE) { - write(reference, "GetField " + ret); - } else { - // Track returned object. - store.reference(ret); - write(reference, "GetField " + store.getIdentifier(ret)); - } - } else if (message.startsWith("GetObjectClass")) { - int oid = Integer.parseInt(message.substring("GetObjectClass" - .length() + 1)); - // System.out.println ("GETTING CLASS FOR: " + oid); - Class c = store.getObject(oid).getClass(); - // System.out.println (" OBJ: " + store.getObject(oid)); - // System.out.println (" CLS: " + c); - store.reference(c); - - write(reference, "GetObjectClass " + store.getIdentifier(c)); - } else if (message.startsWith("CallStaticMethod")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - Integer methodID = parseCall(args[2], src, Integer.class); - - System.out.println("GETTING: " + methodID); - Method m = (Method) store.getObject(methodID); - System.out.println("GOT: " + m); - Class[] argTypes = m.getParameterTypes(); - - Object[] arguments = new Object[argTypes.length]; - for (int i = 0; i < argTypes.length; i++) { - arguments[i] = parseArgs(args[3 + i], argTypes[i]); - // System.out.println ("GOT ARG: " + argTypes[i] + " " + - // arguments[i]); - } - - // System.out.println ("Calling " + m); - Object ret = null; - ret = m.invoke(null, arguments); - - // if (ret != null) - // System.out.println ("RETURN VALUE: " + ret + " " + - // ret.getClass()); - // else - // System.out.println ("RETURN VALUE: " + ret); - if (ret == null) { - write(reference, "CallStaticMethod void"); - } else if (m.getReturnType() == Boolean.TYPE - || m.getReturnType() == Byte.TYPE - || m.getReturnType() == Short.TYPE - || m.getReturnType() == Integer.TYPE - || m.getReturnType() == Long.TYPE - || m.getReturnType() == Float.TYPE - || m.getReturnType() == Double.TYPE) { - write(reference, "CallStaticMethod " + ret); - } else if (m.getReturnType() == Character.TYPE) { - char ch = (Character) ret; - int high = (((int) ch) >> 8) & 0x0ff; - int low = ((int) ch) & 0x0ff; - write(reference, "CallStaticMethod " + low + "_" + high); - } else { - // Track returned object. - store.reference(ret); - write(reference, "CallStaticMethod " - + store.getIdentifier(ret)); - } - } else if (message.startsWith("CallMethod")) { - String[] args = message.split(" "); - Integer objectID = parseCall(args[1], src, Integer.class); - Integer methodID = parseCall(args[2], src, Integer.class); - - Object o = (Object) store.getObject(objectID); - Method m = (Method) store.getObject(methodID); - Class[] argTypes = m.getParameterTypes(); - - Object[] arguments = new Object[argTypes.length]; - for (int i = 0; i < argTypes.length; i++) { - arguments[i] = parseArgs(args[3 + i], argTypes[i]); - PluginDebug.debug("GOT ARG: " + argTypes[i] + " " - + arguments[i]); - } - - String collapsedArgs = ""; - for (String s : args) { - collapsedArgs += " " + s; - } - - PluginDebug.debug("Calling method " + m + " on object " + o - + " with " + arguments); - Object ret = null; - ret = m.invoke(o, arguments); - - String retO; - if (ret == null) { - retO = "null"; - } else { - retO = ret.getClass().toString(); - } - - PluginDebug.debug("Calling " + m + " on " + o + " with " - + collapsedArgs + " and that returned: " + ret - + " of type " + retO); - - if (ret == null) { - write(reference, "CallMethod void"); - } else if (m.getReturnType() == Boolean.TYPE - || m.getReturnType() == Byte.TYPE - || m.getReturnType() == Short.TYPE - || m.getReturnType() == Integer.TYPE - || m.getReturnType() == Long.TYPE - || m.getReturnType() == Float.TYPE - || m.getReturnType() == Double.TYPE) { - write(reference, "CallMethod " + ret); - } else if (m.getReturnType() == Character.TYPE) { - char ch = (Character) ret; - int high = (((int) ch) >> 8) & 0x0ff; - int low = ((int) ch) & 0x0ff; - write(reference, "CallMethod " + low + "_" + high); - } else { - // Track returned object. - store.reference(ret); - write(reference, "CallMethod " + store.getIdentifier(ret)); - } - } else if (message.startsWith("GetSuperclass")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - Class c = null; - Class ret = null; - - c = (Class) store.getObject(classID); - ret = c.getSuperclass(); - store.reference(ret); - - write(reference, "GetSuperclass " + store.getIdentifier(ret)); - } else if (message.startsWith("IsAssignableFrom")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - Integer superclassID = parseCall(args[2], src, Integer.class); - - boolean result = false; - Class clz = (Class) store.getObject(classID); - Class sup = (Class) store.getObject(superclassID); - - result = sup.isAssignableFrom(clz); - - write(reference, "IsAssignableFrom " + (result ? "1" : "0")); - } else if (message.startsWith("IsInstanceOf")) { - String[] args = message.split(" "); - Integer objectID = parseCall(args[1], src, Integer.class); - Integer classID = parseCall(args[2], src, Integer.class); - - boolean result = false; - Object o = (Object) store.getObject(objectID); - Class c = (Class) store.getObject(classID); - - result = c.isInstance(o); - - write(reference, "IsInstanceOf " + (result ? "1" : "0")); - } else if (message.startsWith("GetStringUTFLength")) { - String[] args = message.split(" "); - Integer stringID = parseCall(args[1], src, Integer.class); - - String o = null; - byte[] b = null; - o = (String) store.getObject(stringID); - b = o.getBytes("UTF-8"); - // System.out.println ("STRING UTF-8 LENGTH: " + o + " " + - // b.length); - - write(reference, "GetStringUTFLength " + o.length()); - } else if (message.startsWith("GetStringLength")) { - String[] args = message.split(" "); - Integer stringID = parseCall(args[1], src, Integer.class); - - String o = null; - byte[] b = null; - o = (String) store.getObject(stringID); - b = o.getBytes("UTF-16LE"); - // System.out.println ("STRING UTF-16 LENGTH: " + o + " " + - // b.length); - - // System.out.println ("Java: GetStringLength " + b.length); - write(reference, "GetStringLength " + o.length()); - } else if (message.startsWith("GetStringUTFChars")) { - String[] args = message.split(" "); - Integer stringID = parseCall(args[1], src, Integer.class); - - String o = null; - byte[] b = null; - StringBuffer buf = null; - o = (String) store.getObject(stringID); - b = o.getBytes("UTF-8"); - buf = new StringBuffer(b.length * 2); - buf.append(b.length); - for (int i = 0; i < b.length; i++) - buf - .append(" " - + Integer - .toString(((int) b[i]) & 0x0ff, 16)); - - // System.out.println ("Java: GetStringUTFChars: " + o); - // //System.out.println ("String UTF BYTES: " + buf); - write(reference, "GetStringUTFChars " + buf); - } else if (message.startsWith("GetStringChars")) { - String[] args = message.split(" "); - Integer stringID = parseCall(args[1], src, Integer.class); - - String o = null; - byte[] b = null; - StringBuffer buf = null; - o = (String) store.getObject(stringID); - // FIXME: LiveConnect uses UCS-2. - b = o.getBytes("UTF-16LE"); - buf = new StringBuffer(b.length * 2); - buf.append(b.length); - for (int i = 0; i < b.length; i++) - buf - .append(" " - + Integer - .toString(((int) b[i]) & 0x0ff, 16)); - - System.out.println("Java: GetStringChars: " + o); - System.out.println(" String BYTES: " + buf); - write(reference, "GetStringChars " + buf); - } else if (message.startsWith("NewArray")) { - String[] args = message.split(" "); - String type = parseCall(args[1], src, String.class); - Integer length = parseCall(args[2], src, Integer.class); - - // System.out.println ("CALLING: NewArray: " + type + " " + - // length + " " - // + Signature.primitiveNameToType(type)); - - Object newArray = null; - newArray = Array.newInstance(Signature - .primitiveNameToType(type), length); - - store.reference(newArray); - write(reference, "NewArray " + store.getIdentifier(newArray)); - } else if (message.startsWith("NewObjectArray")) { - String[] args = message.split(" "); - Integer length = parseCall(args[1], src, Integer.class); - Integer classID = parseCall(args[2], src, Integer.class); - Integer objectID = parseCall(args[3], src, Integer.class); - - // System.out.println ("CALLING: NewObjectArray: " + - // classID + " " + length + " " - // + objectID); - - Object newArray = null; - newArray = Array.newInstance((Class) store.getObject(classID), - length); - - Object[] array = (Object[]) newArray; - for (int i = 0; i < array.length; i++) - array[i] = store.getObject(objectID); - store.reference(newArray); - write(reference, "NewObjectArray " - + store.getIdentifier(newArray)); - } else if (message.startsWith("NewObject")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - Integer methodID = parseCall(args[2], src, Integer.class); - - final Constructor m = (Constructor) store.getObject(methodID); - Class[] argTypes = m.getParameterTypes(); - - // System.out.println ("NEWOBJ: HERE1"); - final Object[] arguments = new Object[argTypes.length]; - // System.out.println ("NEWOBJ: HERE2"); - for (int i = 0; i < argTypes.length; i++) { - arguments[i] = parseArgs(args[3 + i], argTypes[i]); - // System.out.println ("NEWOBJ: GOT ARG: " + arguments[i]); - } - - Object ret = m.newInstance(arguments); - store.reference(ret); - - write(reference, "NewObject " + store.getIdentifier(ret)); - - } else if (message.startsWith("NewString")) { - System.out.println("MESSAGE: " + message); - String[] args = message.split(" "); - Integer strlength = parseCall(args[1], src, Integer.class); - int bytelength = 2 * strlength; - byte[] byteArray = new byte[bytelength]; - String ret = null; - for (int i = 0; i < strlength; i++) { - int c = parseCall(args[2 + i], src, Integer.class); - System.out.println("char " + i + " " + c); - // Low. - byteArray[2 * i] = (byte) (c & 0x0ff); - // High. - byteArray[2 * i + 1] = (byte) ((c >> 8) & 0x0ff); - } - ret = new String(byteArray, 0, bytelength, "UTF-16LE"); - System.out.println("NEWSTRING: " + ret); - - // System.out.println ("NEWOBJ: CALLED: " + ret); - // System.out.println ("NEWOBJ: CALLED: " + - // store.getObject(ret)); - store.reference(ret); - write(reference, "NewString " + store.getIdentifier(ret)); - } else if (message.startsWith("NewStringUTF")) { - System.out.println("MESSAGE: " + message); - String[] args = message.split(" "); - byte[] byteArray = new byte[60]; - String ret = null; - int i = 0; - int c = 0; - while (((byte) c) != 0) { - c = parseCall(args[1 + i], src, Integer.class); - byteArray[i] = (byte) c; - i++; - if (i == byteArray.length) { - byte[] newByteArray = new byte[2 * byteArray.length]; - System.arraycopy(byteArray, 0, newByteArray, 0, - byteArray.length); - byteArray = newByteArray; - } - } - byteArray[i] = (byte) 0; - ret = new String(byteArray, "UTF-8"); - System.out.println("NEWSTRINGUTF: " + ret); - - store.reference(ret); - write(reference, "NewStringUTF " + store.getIdentifier(ret)); - } else if (message.startsWith("ExceptionOccurred")) { - System.out.println("EXCEPTION: " + throwable); - if (throwable != null) - store.reference(throwable); - write(reference, "ExceptionOccurred " - + store.getIdentifier(throwable)); - } else if (message.startsWith("ExceptionClear")) { - if (throwable != null) - store.unreference(store.getIdentifier(throwable)); - throwable = null; - write(reference, "ExceptionClear"); - } else if (message.startsWith("DeleteGlobalRef")) { - String[] args = message.split(" "); - Integer id = parseCall(args[1], src, Integer.class); - store.unreference(id); - write(reference, "DeleteGlobalRef"); - } else if (message.startsWith("DeleteLocalRef")) { - String[] args = message.split(" "); - Integer id = parseCall(args[1], src, Integer.class); - store.unreference(id); - write(reference, "DeleteLocalRef"); - } else if (message.startsWith("NewGlobalRef")) { - String[] args = message.split(" "); - Integer id = parseCall(args[1], src, Integer.class); - store.reference(store.getObject(id)); - write(reference, "NewGlobalRef " + id); - } - } catch (Throwable t) { - t.printStackTrace(); - throwable = t; - PluginException p = new PluginException(this.streamhandler, identifier, reference, t); - } - } - - private void write(int reference, String message) { - PluginDebug.debug("appletviewer writing " + message); - streamhandler.write("context " + identifier + " reference " + reference - + " " + message); - } - - public void dumpStore() { - store.dump(); - } - - public Object getObject(int identifier) { - return store.getObject(identifier); - } - - public int getIdentifier(Object o) { - return store.getIdentifier(o); - } - - public void store(Object o) { - store.reference(o); - } -}
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -package org.classpath.icedtea.plugin; - -import sun.applet.PluginCallRequest; -import sun.applet.PluginCallRequestFactory; - -public class PluginCallRequestFactoryImpl implements PluginCallRequestFactory { - - public PluginCallRequest getPluginCallRequest(String id, String message, String returnString) { - - if (id == "member") { - return new GetMemberPluginCallRequest(message, returnString); - } else if (id == "void") { - return new VoidPluginCallRequest(message, returnString); - } else if (id == "window") { - return new GetWindowPluginCallRequest(message, returnString); - } else { - throw new RuntimeException ("Unknown plugin call request type requested from factory"); - } - - } - -}
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMain.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +0,0 @@ -/* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package org.classpath.icedtea.plugin; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.net.Socket; -import java.util.Enumeration; -import java.util.Properties; - -import sun.applet.AppletSecurityContext; -import sun.applet.AppletSecurityContextManager; -import sun.applet.PluginAppletViewer; -import sun.applet.PluginStreamHandler; - -/** - * The main entry point into PluginAppletViewer. - */ -public class PluginMain -{ - final boolean redirectStreams = true; - static PluginStreamHandler streamHandler; - - // This is used in init(). Getting rid of this is desirable but depends - // on whether the property that uses it is necessary/standard. - public static final String theVersion = System.getProperty("java.version"); - - private AppletSecurityContext securityContext; - - /** - * The main entry point into AppletViewer. - */ - public static void main(String args[]) - throws IOException - { - - if (args.length != 1) { - // Indicate to plugin that appletviewer is installed correctly. - System.exit(0); - } - - int port = 0; - try { - port = Integer.parseInt(args[0]); - } catch (NumberFormatException e) { - System.err.println("Failed to parse port number: " + e); - System.exit(1); - } - - PluginMain pm = new PluginMain(); - - } - - public PluginMain() { - - if (redirectStreams) { - try { - File errFile = new File("/tmp/java.stderr"); - File outFile = new File("/tmp/java.stdout"); - - System.setErr(new PrintStream(new FileOutputStream(errFile))); - System.setOut(new PrintStream(new FileOutputStream(outFile))); - - } catch (Exception e) { - System.err.println("Unable to redirect streams"); - e.printStackTrace(); - } - } - - // INSTALL THE SECURITY MANAGER - init(); - - connect(50007); - - securityContext = new PluginAppletSecurityContext(0); - securityContext.setStreamhandler(streamHandler); - AppletSecurityContextManager.addContext(0, securityContext); - - PluginAppletViewer.setStreamhandler(streamHandler); - PluginAppletViewer.setPluginCallRequestFactory(new PluginCallRequestFactoryImpl()); - - // Streams set. Start processing. - streamHandler.startProcessing(); - } - - public void connect(int port) { - /* - * Code for TCP/IP communication - */ - Socket socket = null; - - try { - socket = new Socket("localhost", port); - } catch (Exception e) { - e.printStackTrace(); - } - - System.err.println("Socket initialized. Proceeding with start()"); - - try { - streamHandler = new PluginStreamHandlerImpl(socket.getInputStream(), socket.getOutputStream()); - System.err.println("Streams initialized"); - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - - private static void init() { - Properties avProps = new Properties(); - - // ADD OTHER RANDOM PROPERTIES - // XXX 5/18 need to revisit why these are here, is there some - // standard for what is available? - - // Standard browser properties - avProps.put("browser", "sun.applet.AppletViewer"); - avProps.put("browser.version", "1.06"); - avProps.put("browser.vendor", "Sun Microsystems Inc."); - avProps.put("http.agent", "Java(tm) 2 SDK, Standard Edition v" + theVersion); - - // Define which packages can be extended by applets - // XXX 5/19 probably not needed, not checked in AppletSecurity - avProps.put("package.restrict.definition.java", "true"); - avProps.put("package.restrict.definition.sun", "true"); - - // Define which properties can be read by applets. - // A property named by "key" can be read only when its twin - // property "key.applet" is true. The following ten properties - // are open by default. Any other property can be explicitly - // opened up by the browser user by calling appletviewer with - // -J-Dkey.applet=true - avProps.put("java.version.applet", "true"); - avProps.put("java.vendor.applet", "true"); - avProps.put("java.vendor.url.applet", "true"); - avProps.put("java.class.version.applet", "true"); - avProps.put("os.name.applet", "true"); - avProps.put("os.version.applet", "true"); - avProps.put("os.arch.applet", "true"); - avProps.put("file.separator.applet", "true"); - avProps.put("path.separator.applet", "true"); - avProps.put("line.separator.applet", "true"); - - // Read in the System properties. If something is going to be - // over-written, warn about it. - Properties sysProps = System.getProperties(); - for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements(); ) { - String key = (String) e.nextElement(); - String val = (String) sysProps.getProperty(key); - avProps.setProperty(key, val); - } - - // INSTALL THE PROPERTY LIST - System.setProperties(avProps); - - // Create and install the security manager - //System.setSecurityManager(new AppletSecurity()); - - // REMIND: Create and install a socket factory! - } - - static boolean messageAvailable() { - return streamHandler.messageAvailable(); - } - - static String getMessage() { - return streamHandler.getMessage(); - } -}
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMessageConsumer.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -package org.classpath.icedtea.plugin; - -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.LinkedList; - -import sun.applet.PluginDebug; -import sun.applet.PluginStreamHandler; - - - -class PluginMessageConsumer { - - int MAX_WORKERS = 3; - LinkedList<String> readQueue = new LinkedList<String>(); - ArrayList<PluginMessageHandlerWorker> workers = new ArrayList<PluginMessageHandlerWorker>(); - PluginStreamHandler streamHandler = null; - - public PluginMessageConsumer(PluginStreamHandler streamHandler) { - - this.streamHandler = streamHandler; - - for (int i=0; i < MAX_WORKERS; i++) { - System.err.println("Creating worker " + i); - PluginMessageHandlerWorker worker = new PluginMessageHandlerWorker(streamHandler, i); - worker.start(); - workers.add(worker); - } - } - - public void consume(String message) { - - PluginDebug.debug("Consumer received message " + message); - - synchronized(readQueue) { - readQueue.add(message); - } - - PluginDebug.debug("Message " + message + " added to queue. Looking for free worker..."); - final PluginMessageHandlerWorker worker = getFreeWorker(); - - synchronized(readQueue) { - if (readQueue.size() > 0) { - worker.setmessage(readQueue.poll()); - } - } - - AccessController.doPrivileged(new PrivilegedAction() { - public Object run () { - worker.interrupt(); - return null; - } - }); - } - - private PluginMessageHandlerWorker getFreeWorker() { - - // FIXME: Can be made more efficient by having an idle worker pool - - while (true) { - for (PluginMessageHandlerWorker worker: workers) { - if (worker.isFree()) { - PluginDebug.debug("Found free worker with id " + worker.getWorkerId()); - // mark it busy before returning - worker.busy(); - return worker; - } - } - Thread.yield(); - } - - //throw new RuntimeException("Out of message handler workers"); - } - -}
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -package org.classpath.icedtea.plugin; - -import sun.applet.PluginException; -import sun.applet.PluginStreamHandler; - -class PluginMessageHandlerWorker extends Thread { - - private boolean free = true; - private int id; - private String message = null; - PluginStreamHandler streamHandler = null; - - public PluginMessageHandlerWorker(PluginStreamHandler streamHandler, int id) { - this.id = id; - this.streamHandler = streamHandler; - } - - public void setmessage(String message) { - this.message = message; - } - - public void run() { - while (true) { - - if (message != null) { - - // ideally, whoever returns things object should mark it - // busy first, but just in case.. - busy(); - System.err.println("Thread " + id + " picking up " + message + " from queue..."); - - try { - streamHandler.handleMessage(message); - } catch (PluginException pe) { - /* - catch the exception and DO NOTHING. The plugin should take over after - this error and let the user know. We don't quit because otherwise the - exception will spread to the rest of the applets which is a no-no - */ - } - - this.message = null; - } else { - - // Sleep when there is nothing to do - try { - Thread.sleep(Integer.MAX_VALUE); - System.err.println("Consumer thread " + id + " sleeping..."); - } catch (InterruptedException ie) { - System.err.println("Consumer thread " + id + " woken..."); - // nothing.. someone woke us up, see if there - // is work to do - } - } - - // mark ourselves free again - free(); - } - } - - - - public int getWorkerId() { - return id; - } - - public void busy() { - this.free = false; - } - - - public void free() { - this.free = true; - } - - public boolean isFree() { - return free; - } -}
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginObjectStore.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* PluginObjectStore -- manage identifier-to-object mapping - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -import java.util.*; -import java.lang.reflect.*; -import java.io.*; - -public class PluginObjectStore -{ - private static HashMap<Integer, Object> objects = new HashMap(); - private static HashMap<Integer, Integer> counts = new HashMap(); - private static HashMap<Object, Integer> identifiers = new HashMap(); - // FIXME: - // - // IF uniqueID == MAX_LONG, uniqueID = - // 0 && wrapped = true - // - // if (wrapped), check if - // objects.get(uniqueID) returns null - // - // if yes, use uniqueID, if no, - // uniqueID++ and keep checking - // or: - // stack of available ids: - // derefed id -> derefed id -> nextUniqueIdentifier - private static int nextUniqueIdentifier = 1; - - public Object getObject(Integer identifier) { - return objects.get(identifier); - } - - public Integer getIdentifier(Object object) { - if (object == null) - return 0; - return identifiers.get(object); - } - - public void reference(Object object) { - Integer identifier = identifiers.get(object); - if (identifier == null) { - objects.put(nextUniqueIdentifier, object); - counts.put(nextUniqueIdentifier, 1); - identifiers.put(object, nextUniqueIdentifier); - System.out.println("JAVA ADDED: " + nextUniqueIdentifier); - System.out.println("JAVA REFERENCED: " + nextUniqueIdentifier - + " to: 1"); - nextUniqueIdentifier++; - } else { - counts.put(identifier, counts.get(identifier) + 1); - System.out.println("JAVA REFERENCED: " + identifier + - " to: " + counts.get(identifier)); - } - } - - public void unreference(int identifier) { - Integer currentCount = counts.get(identifier); - if (currentCount == null) - System.out.println("ERROR UNREFERENCING: " + identifier); - if (currentCount == 1) { - System.out.println("JAVA DEREFERENCED: " + identifier - + " to: 0"); - Object object = objects.get(identifier); - objects.remove(identifier); - counts.remove(identifier); - identifiers.remove(object); - System.out.println("JAVA REMOVED: " + identifier); - } else { - counts.put(identifier, currentCount - 1); - System.out.println("JAVA DEREFERENCED: " + - identifier + " to: " + - counts.get(identifier)); - } - } - - public void dump() { - Iterator i = objects.keySet().iterator(); - while (i.hasNext()) { - Object key = i.next(); - System.err.println(key + "::" + objects.get(key)); - } - } -} -
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,362 +0,0 @@ -package org.classpath.icedtea.plugin; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.StreamTokenizer; -import java.net.MalformedURLException; -import java.nio.charset.Charset; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.LinkedList; -import java.util.StringTokenizer; - -import sun.applet.AppletSecurityContextManager; -import sun.applet.PluginAppletViewer; -import sun.applet.PluginCallRequest; -import sun.applet.PluginDebug; -import sun.applet.PluginException; -import sun.applet.PluginStreamHandler; - -public class PluginStreamHandlerImpl implements PluginStreamHandler { - - private BufferedReader pluginInputReader; - private StreamTokenizer pluginInputTokenizer; - private BufferedWriter pluginOutputWriter; - - private RequestQueue queue = new RequestQueue(); - - LinkedList<String> writeQueue = new LinkedList<String>(); - - PluginMessageConsumer consumer; - Boolean shuttingDown = false; - - PluginAppletViewer pav; - - public PluginStreamHandlerImpl(InputStream inputstream, OutputStream outputstream) - throws MalformedURLException, IOException - { - - System.err.println("Current context CL=" + Thread.currentThread().getContextClassLoader()); - try { - pav = (PluginAppletViewer) ClassLoader.getSystemClassLoader().loadClass("sun.applet.PluginAppletViewer").newInstance(); - System.err.println("Loaded: " + pav + " CL=" + pav.getClass().getClassLoader()); - } catch (InstantiationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ClassNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - System.err.println("Creating consumer..."); - consumer = new PluginMessageConsumer(this); - - // Set up input and output pipes. Use UTF-8 encoding. - pluginInputReader = - new BufferedReader(new InputStreamReader(inputstream, - Charset.forName("UTF-8"))); - pluginInputTokenizer = new StreamTokenizer(pluginInputReader); - pluginInputTokenizer.resetSyntax(); - pluginInputTokenizer.whitespaceChars('\u0000', '\u0000'); - pluginInputTokenizer.wordChars('\u0001', '\u00FF'); - pluginOutputWriter = - new BufferedWriter(new OutputStreamWriter - (outputstream, Charset.forName("UTF-8"))); - - /* - while(true) { - String message = read(); - PluginDebug.debug(message); - handleMessage(message); - // TODO: - // write(queue.peek()); - } - */ - } - - public void startProcessing() { - - Thread listenerThread = new Thread() { - - public void run() { - while (true) { - - System.err.println("Waiting for data..."); - - int readChar = -1; - // blocking read, discard first character - try { - readChar = pluginInputReader.read(); - } catch (IOException ioe) { - // plugin may have detached - } - - // if not disconnected - if (readChar != -1) { - String s = read(); - System.err.println("Got data, consuming " + s); - consumer.consume(s); - } else { - try { - // Close input/output channels to plugin. - pluginInputReader.close(); - pluginOutputWriter.close(); - } catch (IOException exception) { - // Deliberately ignore IOException caused by broken - // pipe since plugin may have already detached. - } - AppletSecurityContextManager.dumpStore(0); - System.err.println("APPLETVIEWER: exiting appletviewer"); - System.exit(0); - } - } - } - }; - - listenerThread.start(); - } - - public void postMessage(String s) { - - if (s == null || s.equals("shutdown")) { - try { - // Close input/output channels to plugin. - pluginInputReader.close(); - pluginOutputWriter.close(); - } catch (IOException exception) { - // Deliberately ignore IOException caused by broken - // pipe since plugin may have already detached. - } - AppletSecurityContextManager.dumpStore(0); - System.err.println("APPLETVIEWER: exiting appletviewer"); - System.exit(0); - } - - //PluginAppletSecurityContext.contexts.get(0).store.dump(); - PluginDebug.debug("Plugin posted: " + s); - - System.err.println("Consuming " + s); - consumer.consume(s); - - PluginDebug.debug("Added to queue"); - } - - public void handleMessage(String message) throws PluginException { - - StringTokenizer st = new StringTokenizer(message, " "); - - String type = st.nextToken(); - final int identifier = Integer.parseInt(st.nextToken()); - - String rest = ""; - int reference = -1; - String src = null; - - String potentialReference = st.hasMoreTokens() ? st.nextToken() : ""; - - // if the next token is reference, read it, else reset "rest" - if (potentialReference.equals("reference")) { - reference = Integer.parseInt(st.nextToken()); - } else { - rest += potentialReference + " "; - } - - String potentialSrc = st.hasMoreTokens() ? st.nextToken() : ""; - - if (potentialSrc.equals("src")) { - src = st.nextToken(); - } else { - rest += potentialSrc + " "; - } - - while (st.hasMoreElements()) { - rest += st.nextToken(); - rest += " "; - } - - rest = rest.trim(); - - try { - - System.err.println("Breakdown -- type: " + type + " identifier: " + identifier + " reference: " + reference + " src: " + src + " rest: " + rest); - - if (rest.contains("JavaScriptGetWindow") - || rest.contains("JavaScriptGetMember") - || rest.contains("JavaScriptSetMember") - || rest.contains("JavaScriptGetSlot") - || rest.contains("JavaScriptSetSlot") - || rest.contains("JavaScriptEval") - || rest.contains("JavaScriptRemoveMember") - || rest.contains("JavaScriptCall") - || rest.contains("JavaScriptFinalize") - || rest.contains("JavaScriptToString")) { - - finishCallRequest(rest); - return; - } - - final int freference = reference; - final String frest = rest; - - if (type.equals("instance")) { - PluginAppletViewer.handleMessage(identifier, freference,frest); - } else if (type.equals("context")) { - PluginDebug.debug("Sending to PASC: " + identifier + "/" + reference + " and " + rest); - AppletSecurityContextManager.handleMessage(identifier, src, reference, rest); - } - } catch (Exception e) { - throw new PluginException(this, identifier, reference, e); - } - } - - public void postCallRequest(PluginCallRequest request) { - synchronized(queue) { - queue.post(request); - } - } - - private void finishCallRequest(String message) { - PluginDebug.debug ("DISPATCHCALLREQUESTS 1"); - synchronized(queue) { - PluginDebug.debug ("DISPATCHCALLREQUESTS 2"); - PluginCallRequest request = queue.pop(); - - // make sure we give the message to the right request - // in the queue.. for the love of God, MAKE SURE! - - // first let's be efficient.. if there was only one - // request in queue, we're already set - if (queue.size() != 0) { - - int size = queue.size(); - int count = 0; - - while (!request.serviceable(message)) { - - // something is very wrong.. we have a message to - // process, but no one to service it - if (count >= size) { - throw new RuntimeException("Unable to find processor for message " + message); - } - - // post request at the end of the queue - queue.post(request); - - // Look at the next request - request = queue.pop(); - - count++; - } - - } - - PluginDebug.debug ("DISPATCHCALLREQUESTS 3"); - if (request != null) { - PluginDebug.debug ("DISPATCHCALLREQUESTS 5"); - synchronized(request) { - request.parseReturn(message); - request.notifyAll(); - } - PluginDebug.debug ("DISPATCHCALLREQUESTS 6"); - PluginDebug.debug ("DISPATCHCALLREQUESTS 7"); - } - } - PluginDebug.debug ("DISPATCHCALLREQUESTS 8"); - } - - /** - * Read string from plugin. - * - * @return the read string - * - * @exception IOException if an error occurs - */ - private String read() - { - try { - pluginInputTokenizer.nextToken(); - } catch (IOException e) { - throw new RuntimeException(e); - } - String message = pluginInputTokenizer.sval; - PluginDebug.debug(" PIPE: appletviewer read: " + message); - if (message == null || message.equals("shutdown")) { - synchronized(shuttingDown) { - shuttingDown = true; - } - try { - // Close input/output channels to plugin. - pluginInputReader.close(); - pluginOutputWriter.close(); - } catch (IOException exception) { - // Deliberately ignore IOException caused by broken - // pipe since plugin may have already detached. - } - AppletSecurityContextManager.dumpStore(0); - System.err.println("APPLETVIEWER: exiting appletviewer"); - System.exit(0); - } - return message; - } - - /** - * Write string to plugin. - * - * @param message the message to write - * - * @exception IOException if an error occurs - */ - public void write(String message) - { - - System.err.println(" PIPE: appletviewer wrote: " + message); - synchronized(pluginOutputWriter) { - try { - pluginOutputWriter.write(message, 0, message.length()); - pluginOutputWriter.write(0); - pluginOutputWriter.flush(); - } catch (IOException e) { - // if we are shutting down, ignore write failures as - // pipe may have closed - synchronized(shuttingDown) { - if (!shuttingDown) { - e.printStackTrace(); - } - } - - // either ways, if the pipe is broken, there is nothing - // we can do anymore. Don't hang around. - System.err.println("Unable to write to PIPE. APPLETVIEWER exiting"); - System.exit(1); - } - } - - return; - /* - synchronized(writeQueue) { - writeQueue.add(message); - System.err.println(" PIPE: appletviewer wrote: " + message); - } - */ - - } - - public boolean messageAvailable() { - return writeQueue.size() != 0; - } - - public String getMessage() { - synchronized(writeQueue) { - String ret = writeQueue.size() > 0 ? writeQueue.poll() : ""; - return ret; - } - } -}
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/RequestQueue.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -package org.classpath.icedtea.plugin; - -import sun.applet.PluginCallRequest; - -public class RequestQueue { - PluginCallRequest head = null; - PluginCallRequest tail = null; - private int size = 0; - - public void post(PluginCallRequest request) { - System.err.println("Securitymanager=" + System.getSecurityManager()); - if (head == null) { - head = tail = request; - tail.setNext(null); - } else { - tail.setNext(request); - tail = request; - tail.setNext(null); - } - - size++; - } - - public PluginCallRequest pop() { - if (head == null) - return null; - - PluginCallRequest ret = head; - head = head.getNext(); - ret.setNext(null); - - size--; - - return ret; - } - - public int size() { - return size; - } -} \ No newline at end of file
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/TestEnv.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,172 +0,0 @@ -/* TestEnv -- test JavaScript-to-Java calls - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -public class TestEnv -{ - public static int intField = 103; - public int intInstanceField = 7822; - public String stringField = "hello"; - // z <musical G clef> <chinese water> - public String complexStringField = "z\uD834\uDD1E\u6C34"; - - public static void TestIt() { - System.out.println("TestIt"); - } - - public static void TestItBool(boolean arg) { - System.out.println("TestItBool: " + arg); - } - - public static void TestItByte(byte arg) { - System.out.println("TestItByte: " + arg); - } - - public static void TestItChar(char arg) { - System.out.println("TestItChar: " + arg); - } - - public static void TestItShort(short arg) { - System.out.println("TestItShort: " + arg); - } - - public static void TestItInt(int arg) { - System.out.println("TestItInt: " + arg); - } - - public static void TestItLong(long arg) { - System.out.println("TestItLong: " + arg); - } - - public static void TestItFloat(float arg) { - System.out.println("TestItFloat: " + arg); - } - - public static void TestItDouble(double arg) { - System.out.println("TestItDouble: " + arg); - } - - public static void TestItObject(TestEnv arg) { - System.out.println("TestItObject: " + arg); - } - - public static void TestItObjectString(String arg) { - System.out.println("TestItObjectString: " + arg); - } - - public static void TestItIntArray(int[] arg) { - System.out.println("TestItIntArray: " + arg); - for (int i = 0; i < arg.length; i++) - System.out.println ("ELEMENT: " + i + " " + arg[i]); - } - - public static void TestItObjectArray(String[] arg) { - System.out.println("TestItObjectArray: " + arg); - for (int i = 0; i < arg.length; i++) - System.out.println ("ELEMENT: " + i + " " + arg[i]); - } - - public static void TestItObjectArrayMulti(String[][] arg) { - System.out.println("TestItObjectArrayMulti: " + arg); - for (int i = 0; i < arg.length; i++) - for (int j = 0; j < arg[i].length; j++) - System.out.println ("ELEMENT: " + i + " " + j + " " + arg[i][j]); - } - - public static boolean TestItBoolReturnTrue() { - return true; - } - - public static boolean TestItBoolReturnFalse() { - return false; - } - - public static byte TestItByteReturn() { - return (byte) 0xfe; - } - - public static char TestItCharReturn() { - return 'K'; - } - - public static char TestItCharUnicodeReturn() { - return '\u6C34'; - } - - public static short TestItShortReturn() { - return 23; - } - - public static int TestItIntReturn() { - return 3445; - } - - public static long TestItLongReturn() { - return 3242883; - } - - public static float TestItFloatReturn() { - return 9.21E4f; - } - - public static double TestItDoubleReturn() { - return 8.33E88; - } - - public static Object TestItObjectReturn() { - return new String("Thomas"); - } - - public static int[] TestItIntArrayReturn() { - return new int[] { 6, 7, 8 }; - } - - public static String[] TestItObjectArrayReturn() { - return new String[] { "Thomas", "Brigitte" }; - } - - public static String[][] TestItObjectArrayMultiReturn() { - return new String[][] { {"Thomas", "Brigitte"}, - {"Lindsay", "Michael"} }; - } - - public int TestItIntInstance(int arg) { - System.out.println("TestItIntInstance: " + this + " " + arg); - return 899; - } -}
--- a/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/VoidPluginCallRequest.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* VoidPluginCallRequest -- represent Java-to-JavaScript requests - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -import sun.applet.PluginCallRequest; - -public class VoidPluginCallRequest extends PluginCallRequest { - public VoidPluginCallRequest(String message, String returnString) { - super(message, returnString); - System.out.println ("VoidPLUGINCAlL " + message + " " + returnString); - } - - public void parseReturn(String message) { - setDone(true); - } - - - /** - * Returns whether the given message is serviceable by this object - * - * @param message The message to service - * @return boolean indicating if message is serviceable - */ - public boolean serviceable(String message) { - return message.contains("JavaScriptFinalize") || - message.contains("JavaScriptRemoveMember") || - message.contains("JavaScriptSetMember") || - message.contains("JavaScriptSetSlot"); - } - - public Object getObject() { - return null; - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletAudioClip.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * Copyright 1995-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.io.IOException; -import java.io.InputStream; -import java.io.ByteArrayInputStream; -import java.net.URL; -import java.net.URLConnection; -import java.applet.AudioClip; - -import com.sun.media.sound.JavaSoundAudioClip; - - -/** - * Applet audio clip; - * - * @author Arthur van Hoff, Kara Kytle - */ - -public class AppletAudioClip implements AudioClip { - - // url that this AudioClip is based on - private URL url = null; - - // the audio clip implementation - private AudioClip audioClip = null; - - boolean DEBUG = false /*true*/; - - /** - * Constructs an AppletAudioClip from an URL. - */ - public AppletAudioClip(URL url) { - - // store the url - this.url = url; - - try { - // create a stream from the url, and use it - // in the clip. - InputStream in = url.openStream(); - createAppletAudioClip(in); - - } catch (IOException e) { - /* just quell it */ - if (DEBUG) { - System.err.println("IOException creating AppletAudioClip" + e); - } - } - } - - /** - * Constructs an AppletAudioClip from a URLConnection. - */ - public AppletAudioClip(URLConnection uc) { - - try { - // create a stream from the url, and use it - // in the clip. - createAppletAudioClip(uc.getInputStream()); - - } catch (IOException e) { - /* just quell it */ - if (DEBUG) { - System.err.println("IOException creating AppletAudioClip" + e); - } - } - } - - - /** - * For constructing directly from Jar entries, or any other - * raw Audio data. Note that the data provided must include the format - * header. - */ - public AppletAudioClip(byte [] data) { - - try { - - // construct a stream from the byte array - InputStream in = new ByteArrayInputStream(data); - - createAppletAudioClip(in); - - } catch (IOException e) { - /* just quell it */ - if (DEBUG) { - System.err.println("IOException creating AppletAudioClip " + e); - } - } - } - - - /* - * Does the real work of creating an AppletAudioClip from an InputStream. - * This function is used by both constructors. - */ - void createAppletAudioClip(InputStream in) throws IOException { - - try { - audioClip = new JavaSoundAudioClip(in); - } catch (Exception e3) { - // no matter what happened, we throw an IOException to avoid changing the interfaces.... - throw new IOException("Failed to construct the AudioClip: " + e3); - } - } - - - public synchronized void play() { - - if (audioClip != null) - audioClip.play(); - } - - - public synchronized void loop() { - - if (audioClip != null) - audioClip.loop(); - } - - public synchronized void stop() { - - if (audioClip != null) - audioClip.stop(); - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletClassLoader.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,861 +0,0 @@ -/* - * Copyright 1995-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.lang.NullPointerException; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.SocketPermission; -import java.net.URLConnection; -import java.net.MalformedURLException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.io.File; -import java.io.FilePermission; -import java.io.IOException; -import java.io.BufferedInputStream; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.NoSuchElementException; -import java.security.AccessController; -import java.security.AccessControlContext; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; -import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import sun.awt.AppContext; -import sun.awt.SunToolkit; -import sun.net.www.ParseUtil; -import sun.security.util.SecurityConstants; - -/** - * This class defines the class loader for loading applet classes and - * resources. It extends URLClassLoader to search the applet code base - * for the class or resource after checking any loaded JAR files. - */ -public class AppletClassLoader extends URLClassLoader { - private URL base; /* applet code base URL */ - private CodeSource codesource; /* codesource for the base URL */ - private AccessControlContext acc; - private boolean exceptionStatus = false; - - private final Object threadGroupSynchronizer = new Object(); - private final Object grabReleaseSynchronizer = new Object(); - - private boolean codebaseLookup = true; - - /* - * Creates a new AppletClassLoader for the specified base URL. - */ - protected AppletClassLoader(URL base) { - super(new URL[0]); - this.base = base; - this.codesource = - new CodeSource(base, (java.security.cert.Certificate[]) null); - acc = AccessController.getContext(); - } - - /** - * Set the codebase lookup flag. - */ - void setCodebaseLookup(boolean codebaseLookup) { - this.codebaseLookup = codebaseLookup; - } - - /* - * Returns the applet code base URL. - */ - URL getBaseURL() { - return base; - } - - /* - * Returns the URLs used for loading classes and resources. - */ - public URL[] getURLs() { - URL[] jars = super.getURLs(); - URL[] urls = new URL[jars.length + 1]; - System.arraycopy(jars, 0, urls, 0, jars.length); - urls[urls.length - 1] = base; - return urls; - } - - /* - * Adds the specified JAR file to the search path of loaded JAR files. - * Changed modifier to protected in order to be able to overwrite addJar() - * in PluginClassLoader.java - */ - protected void addJar(String name) throws IOException { - URL url; - try { - url = new URL(base, name); - } catch (MalformedURLException e) { - throw new IllegalArgumentException("name"); - } - addURL(url); - // DEBUG - //URL[] urls = getURLs(); - //for (int i = 0; i < urls.length; i++) { - // System.out.println("url[" + i + "] = " + urls[i]); - //} - } - - /* - * Override loadClass so that class loading errors can be caught in - * order to print better error messages. - */ - public synchronized Class loadClass(String name, boolean resolve) - throws ClassNotFoundException - { - // First check if we have permission to access the package. This - // should go away once we've added support for exported packages. - int i = name.lastIndexOf('.'); - if (i != -1) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPackageAccess(name.substring(0, i)); - } - try { - return super.loadClass(name, resolve); - } catch (ClassNotFoundException e) { - //printError(name, e.getException()); - throw e; - } catch (RuntimeException e) { - //printError(name, e); - throw e; - } catch (Error e) { - //printError(name, e); - throw e; - } - } - - /* - * Finds the applet class with the specified name. First searches - * loaded JAR files then the applet code base for the class. - */ - protected Class findClass(String name) throws ClassNotFoundException { - - int index = name.indexOf(";"); - String cookie = ""; - if(index != -1) { - cookie = name.substring(index, name.length()); - name = name.substring(0, index); - } - - // check loaded JAR files - try { - return super.findClass(name); - } catch (ClassNotFoundException e) { - } - - // Otherwise, try loading the class from the code base URL - - // 4668479: Option to turn off codebase lookup in AppletClassLoader - // during resource requests. [stanley.ho] - if (codebaseLookup == false) - throw new ClassNotFoundException(name); - -// final String path = name.replace('.', '/').concat(".class").concat(cookie); - String encodedName = ParseUtil.encodePath(name.replace('.', '/'), false); - final String path = (new StringBuffer(encodedName)).append(".class").append(cookie).toString(); - try { - byte[] b = (byte[]) AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Object run() throws IOException { - return getBytes(new URL(base, path)); - } - }, acc); - - if (b != null) { - return defineClass(name, b, 0, b.length, codesource); - } else { - throw new ClassNotFoundException(name); - } - } catch (PrivilegedActionException e) { - throw new ClassNotFoundException(name, e.getException()); - } - } - - /** - * Returns the permissions for the given codesource object. - * The implementation of this method first calls super.getPermissions, - * to get the permissions - * granted by the super class, and then adds additional permissions - * based on the URL of the codesource. - * <p> - * If the protocol is "file" - * and the path specifies a file, permission is granted to read all files - * and (recursively) all files and subdirectories contained in - * that directory. This is so applets with a codebase of - * file:/blah/some.jar can read in file:/blah/, which is needed to - * be backward compatible. We also add permission to connect back to - * the "localhost". - * - * @param codesource the codesource - * @return the permissions granted to the codesource - */ - protected PermissionCollection getPermissions(CodeSource codesource) - { - final PermissionCollection perms = super.getPermissions(codesource); - - URL url = codesource.getLocation(); - - String path = null; - Permission p; - - try { - p = url.openConnection().getPermission(); - } catch (java.io.IOException ioe) { - p = null; - } - - if (p instanceof FilePermission) { - path = p.getName(); - } else if ((p == null) && (url.getProtocol().equals("file"))) { - path = url.getFile().replace('/', File.separatorChar); - path = ParseUtil.decode(path); - } - - if (path != null) { - if (!path.endsWith(File.separator)) { - int endIndex = path.lastIndexOf(File.separatorChar); - if (endIndex != -1) { - path = path.substring(0, endIndex+1) + "-"; - perms.add(new FilePermission(path, - SecurityConstants.FILE_READ_ACTION)); - } - } - perms.add(new SocketPermission("localhost", - SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION)); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - try { - String host = InetAddress.getLocalHost().getHostName(); - perms.add(new SocketPermission(host, - SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION)); - } catch (UnknownHostException uhe) { - - } - return null; - } - }); - - Permission bperm; - try { - bperm = base.openConnection().getPermission(); - } catch (java.io.IOException ioe) { - bperm = null; - } - if (bperm instanceof FilePermission) { - String bpath = bperm.getName(); - if (bpath.endsWith(File.separator)) { - bpath += "-"; - } - perms.add(new FilePermission(bpath, - SecurityConstants.FILE_READ_ACTION)); - } else if ((bperm == null) && (base.getProtocol().equals("file"))) { - String bpath = base.getFile().replace('/', File.separatorChar); - bpath = ParseUtil.decode(bpath); - if (bpath.endsWith(File.separator)) { - bpath += "-"; - } - perms.add(new FilePermission(bpath, SecurityConstants.FILE_READ_ACTION)); - } - - } - return perms; - } - - /* - * Returns the contents of the specified URL as an array of bytes. - */ - private static byte[] getBytes(URL url) throws IOException { - URLConnection uc = url.openConnection(); - if (uc instanceof java.net.HttpURLConnection) { - java.net.HttpURLConnection huc = (java.net.HttpURLConnection) uc; - int code = huc.getResponseCode(); - if (code >= java.net.HttpURLConnection.HTTP_BAD_REQUEST) { - throw new IOException("open HTTP connection failed."); - } - } - int len = uc.getContentLength(); - - // Fixed #4507227: Slow performance to load - // class and resources. [stanleyh] - // - // Use buffered input stream [stanleyh] - InputStream in = new BufferedInputStream(uc.getInputStream()); - - byte[] b; - try { - if (len != -1) { - // Read exactly len bytes from the input stream - b = new byte[len]; - while (len > 0) { - int n = in.read(b, b.length - len, len); - if (n == -1) { - throw new IOException("unexpected EOF"); - } - len -= n; - } - } else { - // Read until end of stream is reached - use 8K buffer - // to speed up performance [stanleyh] - b = new byte[8192]; - int total = 0; - while ((len = in.read(b, total, b.length - total)) != -1) { - total += len; - if (total >= b.length) { - byte[] tmp = new byte[total * 2]; - System.arraycopy(b, 0, tmp, 0, total); - b = tmp; - } - } - // Trim array to correct size, if necessary - if (total != b.length) { - byte[] tmp = new byte[total]; - System.arraycopy(b, 0, tmp, 0, total); - b = tmp; - } - } - } finally { - in.close(); - } - return b; - } - - // Object for synchronization around getResourceAsStream() - private Object syncResourceAsStream = new Object(); - private Object syncResourceAsStreamFromJar = new Object(); - - // Flag to indicate getResourceAsStream() is in call - private boolean resourceAsStreamInCall = false; - private boolean resourceAsStreamFromJarInCall = false; - - /** - * Returns an input stream for reading the specified resource. - * - * The search order is described in the documentation for {@link - * #getResource(String)}.<p> - * - * @param name the resource name - * @return an input stream for reading the resource, or <code>null</code> - * if the resource could not be found - * @since JDK1.1 - */ - public InputStream getResourceAsStream(String name) - { - - if (name == null) { - throw new NullPointerException("name"); - } - - try - { - InputStream is = null; - - // Fixed #4507227: Slow performance to load - // class and resources. [stanleyh] - // - // The following is used to avoid calling - // AppletClassLoader.findResource() in - // super.getResourceAsStream(). Otherwise, - // unnecessary connection will be made. - // - synchronized(syncResourceAsStream) - { - resourceAsStreamInCall = true; - - // Call super class - is = super.getResourceAsStream(name); - - resourceAsStreamInCall = false; - } - - // 4668479: Option to turn off codebase lookup in AppletClassLoader - // during resource requests. [stanley.ho] - if (codebaseLookup == true && is == null) - { - // If resource cannot be obtained, - // try to download it from codebase - URL url = new URL(base, ParseUtil.encodePath(name, false)); - is = url.openStream(); - } - - return is; - } - catch (Exception e) - { - return null; - } - } - - - /** - * Returns an input stream for reading the specified resource from the - * the loaded jar files. - * - * The search order is described in the documentation for {@link - * #getResource(String)}.<p> - * - * @param name the resource name - * @return an input stream for reading the resource, or <code>null</code> - * if the resource could not be found - * @since JDK1.1 - */ - public InputStream getResourceAsStreamFromJar(String name) { - - if (name == null) { - throw new NullPointerException("name"); - } - - try { - InputStream is = null; - synchronized(syncResourceAsStreamFromJar) { - resourceAsStreamFromJarInCall = true; - // Call super class - is = super.getResourceAsStream(name); - resourceAsStreamFromJarInCall = false; - } - - return is; - } catch (Exception e) { - return null; - } - } - - - /* - * Finds the applet resource with the specified name. First checks - * loaded JAR files then the applet code base for the resource. - */ - public URL findResource(String name) { - // check loaded JAR files - URL url = super.findResource(name); - - // 6215746: Disable META-INF/* lookup from codebase in - // applet/plugin classloader. [stanley.ho] - if (name.startsWith("META-INF/")) - return url; - - // 4668479: Option to turn off codebase lookup in AppletClassLoader - // during resource requests. [stanley.ho] - if (codebaseLookup == false) - return url; - - if (url == null) - { - //#4805170, if it is a call from Applet.getImage() - //we should check for the image only in the archives - boolean insideGetResourceAsStreamFromJar = false; - synchronized(syncResourceAsStreamFromJar) { - insideGetResourceAsStreamFromJar = resourceAsStreamFromJarInCall; - } - - if (insideGetResourceAsStreamFromJar) { - return null; - } - - // Fixed #4507227: Slow performance to load - // class and resources. [stanleyh] - // - // Check if getResourceAsStream is called. - // - boolean insideGetResourceAsStream = false; - - synchronized(syncResourceAsStream) - { - insideGetResourceAsStream = resourceAsStreamInCall; - } - - // If getResourceAsStream is called, don't - // trigger the following code. Otherwise, - // unnecessary connection will be made. - // - if (insideGetResourceAsStream == false) - { - // otherwise, try the code base - try { - url = new URL(base, ParseUtil.encodePath(name, false)); - // check if resource exists - if(!resourceExists(url)) - url = null; - } catch (Exception e) { - // all exceptions, including security exceptions, are caught - url = null; - } - } - } - return url; - } - - - private boolean resourceExists(URL url) { - // Check if the resource exists. - // It almost works to just try to do an openConnection() but - // HttpURLConnection will return true on HTTP_BAD_REQUEST - // when the requested name ends in ".html", ".htm", and ".txt" - // and we want to be able to handle these - // - // Also, cannot just open a connection for things like FileURLConnection, - // because they succeed when connecting to a nonexistent file. - // So, in those cases we open and close an input stream. - boolean ok = true; - try { - URLConnection conn = url.openConnection(); - if (conn instanceof java.net.HttpURLConnection) { - java.net.HttpURLConnection hconn = - (java.net.HttpURLConnection) conn; - - // To reduce overhead, using http HEAD method instead of GET method - hconn.setRequestMethod("HEAD"); - - int code = hconn.getResponseCode(); - if (code == java.net.HttpURLConnection.HTTP_OK) { - return true; - } - if (code >= java.net.HttpURLConnection.HTTP_BAD_REQUEST) { - return false; - } - } else { - /** - * Fix for #4182052 - stanleyh - * - * The same connection should be reused to avoid multiple - * HTTP connections - */ - - // our best guess for the other cases - InputStream is = conn.getInputStream(); - is.close(); - } - } catch (Exception ex) { - ok = false; - } - return ok; - } - - /* - * Returns an enumeration of all the applet resources with the specified - * name. First checks loaded JAR files then the applet code base for all - * available resources. - */ - public Enumeration findResources(String name) throws IOException { - - final Enumeration e = super.findResources(name); - - // 6215746: Disable META-INF/* lookup from codebase in - // applet/plugin classloader. [stanley.ho] - if (name.startsWith("META-INF/")) - return e; - - // 4668479: Option to turn off codebase lookup in AppletClassLoader - // during resource requests. [stanley.ho] - if (codebaseLookup == false) - return e; - - URL u = new URL(base, ParseUtil.encodePath(name, false)); - if (!resourceExists(u)) { - u = null; - } - - final URL url = u; - return new Enumeration() { - private boolean done; - public Object nextElement() { - if (!done) { - if (e.hasMoreElements()) { - return e.nextElement(); - } - done = true; - if (url != null) { - return url; - } - } - throw new NoSuchElementException(); - } - public boolean hasMoreElements() { - return !done && (e.hasMoreElements() || url != null); - } - }; - } - - /* - * Load and resolve the file specified by the applet tag CODE - * attribute. The argument can either be the relative path - * of the class file itself or just the name of the class. - */ - Class loadCode(String name) throws ClassNotFoundException { - // first convert any '/' or native file separator to . - name = name.replace('/', '.'); - name = name.replace(File.separatorChar, '.'); - - // deal with URL rewriting - String cookie = null; - int index = name.indexOf(";"); - if(index != -1) { - cookie = name.substring(index, name.length()); - name = name.substring(0, index); - } - - // save that name for later - String fullName = name; - // then strip off any suffixes - if (name.endsWith(".class") || name.endsWith(".java")) { - name = name.substring(0, name.lastIndexOf('.')); - } - try { - if(cookie != null) - name = (new StringBuffer(name)).append(cookie).toString(); - return loadClass(name); - } catch (ClassNotFoundException e) { - } - // then if it didn't end with .java or .class, or in the - // really pathological case of a class named class or java - if(cookie != null) - fullName = (new StringBuffer(fullName)).append(cookie).toString(); - - return loadClass(fullName); - } - - /* - * The threadgroup that the applets loaded by this classloader live - * in. In the sun.* implementation of applets, the security manager's - * (AppletSecurity) getThreadGroup returns the thread group of the - * first applet on the stack, which is the applet's thread group. - */ - private AppletThreadGroup threadGroup; - private AppContext appContext; - - public ThreadGroup getThreadGroup() { - synchronized (threadGroupSynchronizer) { - if (threadGroup == null || threadGroup.isDestroyed()) { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - threadGroup = new AppletThreadGroup(base + "-threadGroup"); - // threadGroup.setDaemon(true); - // threadGroup is now destroyed by AppContext.dispose() - - // Create the new AppContext from within a Thread belonging - // to the newly created ThreadGroup, and wait for the - // creation to complete before returning from this method. - AppContextCreator creatorThread = new AppContextCreator(threadGroup); - - // Since this thread will later be used to launch the - // applet's AWT-event dispatch thread and we want the applet - // code executing the AWT callbacks to use their own class - // loader rather than the system class loader, explicitly - // set the context class loader to the AppletClassLoader. - creatorThread.setContextClassLoader(AppletClassLoader.this); - - synchronized(creatorThread.syncObject) { - creatorThread.start(); - try { - creatorThread.syncObject.wait(); - } catch (InterruptedException e) { } - appContext = creatorThread.appContext; - } - return null; - } - }); - } - return threadGroup; - } - } - - /* - * Get the AppContext, if any, corresponding to this AppletClassLoader. - */ - public AppContext getAppContext() { - return appContext; - } - - int usageCount = 0; - - /** - * Grab this AppletClassLoader and its ThreadGroup/AppContext, so they - * won't be destroyed. - */ - void grab() { - synchronized(grabReleaseSynchronizer) { - usageCount++; - } - getThreadGroup(); // Make sure ThreadGroup/AppContext exist - } - - protected void setExceptionStatus() - { - exceptionStatus = true; - } - - public boolean getExceptionStatus() - { - return exceptionStatus; - } - - /** - * Release this AppletClassLoader and its ThreadGroup/AppContext. - * If nothing else has grabbed this AppletClassLoader, its ThreadGroup - * and AppContext will be destroyed. - * - * Because this method may destroy the AppletClassLoader's ThreadGroup, - * this method should NOT be called from within the AppletClassLoader's - * ThreadGroup. - * - * Changed modifier to protected in order to be able to overwrite this - * function in PluginClassLoader.java - */ - protected void release() { - - AppContext tempAppContext = null; - - synchronized(grabReleaseSynchronizer) { - if (usageCount > 1) { - --usageCount; - } else { - synchronized(threadGroupSynchronizer) { - // Store app context in temp variable - tempAppContext = appContext; - usageCount = 0; - appContext = null; - threadGroup = null; - } - } - } - - // Dispose appContext outside any sync block to - // prevent potential deadlock. - if (tempAppContext != null) { - try { - tempAppContext.dispose(); // nuke the world! - } catch (IllegalThreadStateException e) { } - } - } - - // Hash map to store applet compatibility info - private HashMap jdk11AppletInfo = new HashMap(); - private HashMap jdk12AppletInfo = new HashMap(); - - /** - * Set applet target level as JDK 1.1. - * - * @param clazz Applet class. - * @param bool true if JDK is targeted for JDK 1.1; - * false otherwise. - */ - void setJDK11Target(Class clazz, boolean bool) - { - jdk11AppletInfo.put(clazz.toString(), Boolean.valueOf(bool)); - } - - /** - * Set applet target level as JDK 1.2. - * - * @param clazz Applet class. - * @param bool true if JDK is targeted for JDK 1.2; - * false otherwise. - */ - void setJDK12Target(Class clazz, boolean bool) - { - jdk12AppletInfo.put(clazz.toString(), Boolean.valueOf(bool)); - } - - /** - * Determine if applet is targeted for JDK 1.1. - * - * @param applet Applet class. - * @return TRUE if applet is targeted for JDK 1.1; - * FALSE if applet is not; - * null if applet is unknown. - */ - Boolean isJDK11Target(Class clazz) - { - return (Boolean) jdk11AppletInfo.get(clazz.toString()); - } - - /** - * Determine if applet is targeted for JDK 1.2. - * - * @param applet Applet class. - * @return TRUE if applet is targeted for JDK 1.2; - * FALSE if applet is not; - * null if applet is unknown. - */ - Boolean isJDK12Target(Class clazz) - { - return (Boolean) jdk12AppletInfo.get(clazz.toString()); - } - - private static AppletMessageHandler mh = - new AppletMessageHandler("appletclassloader"); - - /* - * Prints a class loading error message. - */ - private static void printError(String name, Throwable e) { - String s = null; - if (e == null) { - s = mh.getMessage("filenotfound", name); - } else if (e instanceof IOException) { - s = mh.getMessage("fileioexception", name); - } else if (e instanceof ClassFormatError) { - s = mh.getMessage("fileformat", name); - } else if (e instanceof ThreadDeath) { - s = mh.getMessage("filedeath", name); - } else if (e instanceof Error) { - s = mh.getMessage("fileerror", e.toString(), name); - } - if (s != null) { - System.err.println(s); - } - } -} - -/* - * The AppContextCreator class is used to create an AppContext from within - * a Thread belonging to the new AppContext's ThreadGroup. To wait for - * this operation to complete before continuing, wait for the notifyAll() - * operation on the syncObject to occur. - */ -class AppContextCreator extends Thread { - Object syncObject = new Object(); - AppContext appContext = null; - - AppContextCreator(ThreadGroup group) { - super(group, "AppContextCreator"); - } - - public void run() { - synchronized(syncObject) { - appContext = SunToolkit.createNewAppContext(); - syncObject.notifyAll(); - } - } // run() - -} // class AppContextCreator
--- a/plugin/icedtea/java/src/main/sun/applet/AppletEvent.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.util.EventObject; - - -/** - * AppletEvent class. - * - * @author Sunita Mani - */ - -public class AppletEvent extends EventObject { - - private Object arg; - private int id; - - - public AppletEvent(Object source, int id, Object argument) { - super(source); - this.arg = argument; - this.id = id; - } - - public int getID() { - return id; - } - - public Object getArgument() { - return arg; - } - - public String toString() { - String str = getClass().getName() + "[source=" + source + " + id="+ id; - if (arg != null) { - str += " + arg=" + arg; - } - str += " ]"; - return str; - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletEventMulticaster.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.util.EventListener; -import java.io.Serializable; -import java.io.ObjectOutputStream; -import java.io.IOException; - -/** - * AppletEventMulticaster class. This class manages an immutable - * structure consisting of a chain of AppletListeners and is - * responsible for dispatching events to them. - * - * @author Sunita Mani - */ -public class AppletEventMulticaster implements AppletListener { - - private final AppletListener a, b; - - public AppletEventMulticaster(AppletListener a, AppletListener b) { - this.a = a; this.b = b; - } - - public void appletStateChanged(AppletEvent e) { - a.appletStateChanged(e); - b.appletStateChanged(e); - } - - /** - * Adds Applet-listener-a with Applet-listener-b and - * returns the resulting multicast listener. - * @param a Applet-listener-a - * @param b Applet-listener-b - */ - public static AppletListener add(AppletListener a, AppletListener b) { - return addInternal(a, b); - } - - /** - * Removes the old Applet-listener from Applet-listener-l and - * returns the resulting multicast listener. - * @param l Applet-listener-l - * @param oldl the Applet-listener being removed - */ - public static AppletListener remove(AppletListener l, AppletListener oldl) { - return removeInternal(l, oldl); - } - - /** - * Returns the resulting multicast listener from adding listener-a - * and listener-b together. - * If listener-a is null, it returns listener-b; - * If listener-b is null, it returns listener-a - * If neither are null, then it creates and returns - * a new AppletEventMulticaster instance which chains a with b. - * @param a event listener-a - * @param b event listener-b - */ - private static AppletListener addInternal(AppletListener a, AppletListener b) { - if (a == null) return b; - if (b == null) return a; - return new AppletEventMulticaster(a, b); - } - - - /** - * Removes a listener from this multicaster and returns the - * resulting multicast listener. - * @param oldl the listener to be removed - */ - protected AppletListener remove(AppletListener oldl) { - if (oldl == a) return b; - if (oldl == b) return a; - AppletListener a2 = removeInternal(a, oldl); - AppletListener b2 = removeInternal(b, oldl); - if (a2 == a && b2 == b) { - return this; // it's not here - } - return addInternal(a2, b2); - } - - - /** - * Returns the resulting multicast listener after removing the - * old listener from listener-l. - * If listener-l equals the old listener OR listener-l is null, - * returns null. - * Else if listener-l is an instance of AppletEventMulticaster - * then it removes the old listener from it. - * Else, returns listener l. - * @param l the listener being removed from - * @param oldl the listener being removed - */ - private static AppletListener removeInternal(AppletListener l, AppletListener oldl) { - if (l == oldl || l == null) { - return null; - } else if (l instanceof AppletEventMulticaster) { - return ((AppletEventMulticaster)l).remove(oldl); - } else { - return l; // it's not here - } - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletIOException.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright 1996 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.io.IOException; - -/** - * An applet IO exception. - * - * @author Koji Uno - */ -public -class AppletIOException extends IOException { - private String key = null; - private Object msgobj = null; - - public AppletIOException(String key) { - super(key); - this.key = key; - - } - public AppletIOException(String key, Object arg) { - this(key); - msgobj = arg; - } - - public String getLocalizedMessage() { - if( msgobj != null) - return amh.getMessage(key, msgobj); - else - return amh.getMessage(key); - } - - private static AppletMessageHandler amh = new AppletMessageHandler("appletioexception"); - -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletIllegalArgumentException.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright 1996 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -/** - * An applet security exception. - * - * @author Arthur van Hoff - */ -public -class AppletIllegalArgumentException extends IllegalArgumentException { - private String key = null; - - public AppletIllegalArgumentException(String key) { - super(key); - this.key = key; - - } - - public String getLocalizedMessage() { - return amh.getMessage(key); - } - - private static AppletMessageHandler amh = new AppletMessageHandler("appletillegalargumentexception"); -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletImageRef.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright 1996 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.awt.Toolkit; -import java.awt.Image; -import sun.awt.image.URLImageSource; -import java.net.URL; - -class AppletImageRef extends sun.misc.Ref { - URL url; - - /** - * Create the Ref - */ - AppletImageRef(URL url) { - this.url = url; - } - - public void flush() { - super.flush(); - } - - /** - * Reconsitute the image. Only called when the ref has been flushed. - */ - public Object reconstitute() { - Image img = Toolkit.getDefaultToolkit().createImage(new URLImageSource(url)); - return img; - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletListener.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.util.EventListener; - -/** - * Applet Listener interface. This interface is to be implemented - * by objects interested in AppletEvents. - * - * @author Sunita Mani - */ - -public interface AppletListener extends EventListener { - public void appletStateChanged(AppletEvent e); -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletMessageHandler.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/* - * Copyright 1996-1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.util.ResourceBundle; -import java.util.MissingResourceException; -import java.text.MessageFormat; - -/** - * An hanlder of localized messages. - * - * @author Koji Uno - */ -class AppletMessageHandler { - private static ResourceBundle rb; - private String baseKey = null; - - static { - try { - rb = ResourceBundle.getBundle - ("sun.applet.resources.MsgAppletViewer"); - } catch (MissingResourceException e) { - System.out.println(e.getMessage()); - System.exit(1); - } - } - - AppletMessageHandler(String baseKey) { - this.baseKey = baseKey; - } - - String getMessage(String key) { - return (String)rb.getString(getQualifiedKey(key)); - } - - String getMessage(String key, Object arg){ - String basemsgfmt = (String)rb.getString(getQualifiedKey(key)); - MessageFormat msgfmt = new MessageFormat(basemsgfmt); - Object msgobj[] = new Object[1]; - if (arg == null) { - arg = "null"; // mimic java.io.PrintStream.print(String) - } - msgobj[0] = arg; - return msgfmt.format(msgobj); - } - - String getMessage(String key, Object arg1, Object arg2) { - String basemsgfmt = (String)rb.getString(getQualifiedKey(key)); - MessageFormat msgfmt = new MessageFormat(basemsgfmt); - Object msgobj[] = new Object[2]; - if (arg1 == null) { - arg1 = "null"; - } - if (arg2 == null) { - arg2 = "null"; - } - msgobj[0] = arg1; - msgobj[1] = arg2; - return msgfmt.format(msgobj); - } - - String getMessage(String key, Object arg1, Object arg2, Object arg3) { - String basemsgfmt = (String)rb.getString(getQualifiedKey(key)); - MessageFormat msgfmt = new MessageFormat(basemsgfmt); - Object msgobj[] = new Object[3]; - if (arg1 == null) { - arg1 = "null"; - } - if (arg2 == null) { - arg2 = "null"; - } - if (arg3 == null) { - arg3 = "null"; - } - msgobj[0] = arg1; - msgobj[1] = arg2; - msgobj[2] = arg3; - return msgfmt.format(msgobj); - } - - String getMessage(String key, Object arg[]) { - String basemsgfmt = (String)rb.getString(getQualifiedKey(key)); - MessageFormat msgfmt = new MessageFormat(basemsgfmt); - return msgfmt.format(arg); - } - - String getQualifiedKey(String subKey) { - return baseKey + "." + subKey; - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletObjectInputStream.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -/* - * Copyright 1996-1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ -/* - * COPYRIGHT goes here - */ - -package sun.applet; - -import java.io.*; -import java.lang.reflect.Array; - -/** - * This subclass of ObjectInputStream delegates loading of classes to - * an existing ClassLoader. - */ - -class AppletObjectInputStream extends ObjectInputStream -{ - private AppletClassLoader loader; - - /** - * Loader must be non-null; - */ - - public AppletObjectInputStream(InputStream in, AppletClassLoader loader) - throws IOException, StreamCorruptedException { - - super(in); - if (loader == null) { - throw new AppletIllegalArgumentException("appletillegalargumentexception.objectinputstream"); - - } - this.loader = loader; - } - - /** - * Make a primitive array class - */ - - private Class primitiveType(char type) { - switch (type) { - case 'B': return byte.class; - case 'C': return char.class; - case 'D': return double.class; - case 'F': return float.class; - case 'I': return int.class; - case 'J': return long.class; - case 'S': return short.class; - case 'Z': return boolean.class; - default: return null; - } - } - - /** - * Use the given ClassLoader rather than using the system class - */ - protected Class resolveClass(ObjectStreamClass classDesc) - throws IOException, ClassNotFoundException { - - String cname = classDesc.getName(); - if (cname.startsWith("[")) { - // An array - Class component; // component class - int dcount; // dimension - for (dcount=1; cname.charAt(dcount)=='['; dcount++) ; - if (cname.charAt(dcount) == 'L') { - component = loader.loadClass(cname.substring(dcount+1, - cname.length()-1)); - } else { - if (cname.length() != dcount+1) { - throw new ClassNotFoundException(cname);// malformed - } - component = primitiveType(cname.charAt(dcount)); - } - int dim[] = new int[dcount]; - for (int i=0; i<dcount; i++) { - dim[i]=0; - } - return Array.newInstance(component, dim).getClass(); - } else { - return loader.loadClass(cname); - } - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletPanel.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1334 +0,0 @@ -/* - * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.applet.*; -import java.awt.*; -import java.awt.event.*; -import java.awt.image.ColorModel; -import java.awt.image.MemoryImageSource; -import java.io.*; -import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.InetAddress; -import java.net.JarURLConnection; -import java.net.MalformedURLException; -import java.net.SocketPermission; -import java.net.URL; -import java.net.UnknownHostException; -import java.security.*; -import java.util.*; -import javax.swing.SwingUtilities; -import sun.awt.AppContext; -import sun.awt.EmbeddedFrame; -import sun.awt.SunToolkit; -import sun.misc.MessageUtils; -import sun.misc.PerformanceLogger; -import sun.misc.Queue; -import sun.security.util.SecurityConstants; - -/** - * Applet panel class. The panel manages and manipulates the - * applet as it is being loaded. It forks a separate thread in a new - * thread group to call the applet's init(), start(), stop(), and - * destroy() methods. - * - * @author Arthur van Hoff - */ -public -abstract class AppletPanel extends Panel implements AppletStub, Runnable { - - /** - * The applet (if loaded). - */ - protected Applet applet; - - /** - * Applet will allow initialization. Should be - * set to false if loading a serialized applet - * that was pickled in the init=true state. - */ - protected boolean doInit = true; - - - /** - * The classloader for the applet. - */ - AppletClassLoader loader; - - /* applet event ids */ - public final static int APPLET_DISPOSE = 0; - public final static int APPLET_LOAD = 1; - public final static int APPLET_INIT = 2; - public final static int APPLET_START = 3; - public final static int APPLET_STOP = 4; - public final static int APPLET_DESTROY = 5; - public final static int APPLET_QUIT = 6; - public final static int APPLET_ERROR = 7; - - /* send to the parent to force relayout */ - public final static int APPLET_RESIZE = 51234; - - /* sent to a (distant) parent to indicate that the applet is being - * loaded or as completed loading - */ - public final static int APPLET_LOADING = 51235; - public final static int APPLET_LOADING_COMPLETED = 51236; - - /** - * The current status. One of: - * APPLET_DISPOSE, - * APPLET_LOAD, - * APPLET_INIT, - * APPLET_START, - * APPLET_STOP, - * APPLET_DESTROY, - * APPLET_ERROR. - */ - protected int status; - - /** - * The thread for the applet. - */ - protected Thread handler; - - - /** - * The initial applet size. - */ - Dimension defaultAppletSize = new Dimension(10, 10); - - /** - * The current applet size. - */ - Dimension currentAppletSize = new Dimension(10, 10); - - MessageUtils mu = new MessageUtils(); - - /** - * The thread to use during applet loading - */ - - Thread loaderThread = null; - - /** - * Flag to indicate that a loading has been cancelled - */ - boolean loadAbortRequest = false; - - /* abstract classes */ - abstract protected String getCode(); - abstract protected String getJarFiles(); - abstract protected String getSerializedObject(); - - abstract public int getWidth(); - abstract public int getHeight(); - abstract public boolean hasInitialFocus(); - - private static int threadGroupNumber = 0; - - protected void setupAppletAppContext() { - // do nothing - } - - /* - * Creates a thread to run the applet. This method is called - * each time an applet is loaded and reloaded. - */ - //Overridden by NetxPanel. - protected synchronized void createAppletThread() { - // Create a thread group for the applet, and start a new - // thread to load the applet. - String nm = "applet-" + getCode(); - loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey()); - loader.grab(); // Keep this puppy around! - - // 4668479: Option to turn off codebase lookup in AppletClassLoader - // during resource requests. [stanley.ho] - String param = getParameter("codebase_lookup"); - - if (param != null && param.equals("false")) - loader.setCodebaseLookup(false); - else - loader.setCodebaseLookup(true); - - - ThreadGroup appletGroup = loader.getThreadGroup(); - - handler = new Thread(appletGroup, this, "thread " + nm); - // set the context class loader for this thread - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - handler.setContextClassLoader(loader); - return null; - } - }); - handler.start(); - } - - void joinAppletThread() throws InterruptedException { - if (handler != null) { - handler.join(); - handler = null; - } - } - - void release() { - if (loader != null) { - loader.release(); - loader = null; - } - } - - /** - * Construct an applet viewer and start the applet. - */ - public void init() { - try { - // Get the width (if any) - defaultAppletSize.width = getWidth(); - currentAppletSize.width = defaultAppletSize.width; - - // Get the height (if any) - defaultAppletSize.height = getHeight(); - currentAppletSize.height = defaultAppletSize.height; - - } catch (NumberFormatException e) { - // Turn on the error flag and let TagAppletPanel - // do the right thing. - status = APPLET_ERROR; - showAppletStatus("badattribute.exception"); - showAppletLog("badattribute.exception"); - showAppletException(e); - } - - setLayout(new BorderLayout()); - - createAppletThread(); - } - - /** - * Minimum size - */ - public Dimension minimumSize() { - return new Dimension(defaultAppletSize.width, - defaultAppletSize.height); - } - - /** - * Preferred size - */ - public Dimension preferredSize() { - return new Dimension(currentAppletSize.width, - currentAppletSize.height); - } - - private AppletListener listeners; - - /** - * AppletEvent Queue - */ - private Queue queue = null; - - - synchronized public void addAppletListener(AppletListener l) { - listeners = AppletEventMulticaster.add(listeners, l); - } - - synchronized public void removeAppletListener(AppletListener l) { - listeners = AppletEventMulticaster.remove(listeners, l); - } - - /** - * Dispatch event to the listeners.. - */ - public void dispatchAppletEvent(int id, Object argument) { - //System.out.println("SEND= " + id); - if (listeners != null) { - AppletEvent evt = new AppletEvent(this, id, argument); - listeners.appletStateChanged(evt); - } - } - - /** - * Send an event. Queue it for execution by the handler thread. - */ - public void sendEvent(int id) { - synchronized(this) { - if (queue == null) { - //System.out.println("SEND0= " + id); - queue = new Queue(); - } - Integer eventId = new Integer(id); - queue.enqueue(eventId); - notifyAll(); - } - if (id == APPLET_QUIT) { - try { - joinAppletThread(); // Let the applet event handler exit - } catch (InterruptedException e) { - } - - // AppletClassLoader.release() must be called by a Thread - // not within the applet's ThreadGroup - if (loader == null) - loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey()); - release(); - } - } - - /** - * Get an event from the queue. - */ - protected synchronized AppletEvent getNextEvent() throws InterruptedException { - while (queue == null || queue.isEmpty()) { - wait(); - } - Integer eventId = (Integer)queue.dequeue(); - return new AppletEvent(this, eventId.intValue(), null); - } - - boolean emptyEventQueue() { - if ((queue == null) || (queue.isEmpty())) - return true; - else - return false; - } - - /** - * This kludge is specific to get over AccessControlException thrown during - * Applet.stop() or destroy() when static thread is suspended. Set a flag - * in AppletClassLoader to indicate that an - * AccessControlException for RuntimePermission "modifyThread" or - * "modifyThreadGroup" had occurred. - */ - private void setExceptionStatus(AccessControlException e) { - Permission p = e.getPermission(); - if (p instanceof RuntimePermission) { - if (p.getName().startsWith("modifyThread")) { - if (loader == null) - loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey()); - loader.setExceptionStatus(); - } - } - } - - /** - * Execute applet events. - * Here is the state transition diagram - * - * Note: (XXX) is the action - * APPLET_XXX is the state - * (applet code loaded) --> APPLET_LOAD -- (applet init called)--> APPLET_INIT -- ( - * applet start called) --> APPLET_START -- (applet stop called) -->APPLET_STOP --(applet - * destroyed called) --> APPLET_DESTROY -->(applet gets disposed) --> - * APPLET_DISPOSE -->.... - * - * In the legacy lifecycle model. The applet gets loaded, inited and started. So it stays - * in the APPLET_START state unless the applet goes away(refresh page or leave the page). - * So the applet stop method called and the applet enters APPLET_STOP state. Then if the applet - * is revisited, it will call applet start method and enter the APPLET_START state and stay there. - * - * In the modern lifecycle model. When the applet first time visited, it is same as legacy lifecycle - * model. However, when the applet page goes away. It calls applet stop method and enters APPLET_STOP - * state and then applet destroyed method gets called and enters APPLET_DESTROY state. - * - * This code is also called by AppletViewer. In AppletViewer "Restart" menu, the applet is jump from - * APPLET_STOP to APPLET_DESTROY and to APPLET_INIT . - * - * Also, the applet can jump from APPLET_INIT state to APPLET_DESTROY (in Netscape/Mozilla case). - * Same as APPLET_LOAD to - * APPLET_DISPOSE since all of this are triggered by browser. - * - * - */ - public void run() { - - Thread curThread = Thread.currentThread(); - if (curThread == loaderThread) { - // if we are in the loader thread, cause - // loading to occur. We may exit this with - // status being APPLET_DISPOSE, APPLET_ERROR, - // or APPLET_LOAD - runLoader(); - return; - } - - boolean disposed = false; - while (!disposed && !curThread.isInterrupted()) { - AppletEvent evt; - try { - evt = getNextEvent(); - } catch (InterruptedException e) { - showAppletStatus("bail"); - return; - } - - //showAppletStatus("EVENT = " + evt.getID()); - try { - switch (evt.getID()) { - case APPLET_LOAD: - if (!okToLoad()) { - break; - } - // This complexity allows loading of applets to be - // interruptable. The actual thread loading runs - // in a separate thread, so it can be interrupted - // without harming the applet thread. - // So that we don't have to worry about - // concurrency issues, the main applet thread waits - // until the loader thread terminates. - // (one way or another). - if (loaderThread == null) { - // REMIND: do we want a name? - //System.out.println("------------------- loading applet"); - setLoaderThread(new Thread(this)); - loaderThread.start(); - // we get to go to sleep while this runs - loaderThread.join(); - setLoaderThread(null); - } else { - // REMIND: issue an error -- this case should never - // occur. - } - break; - - case APPLET_INIT: - // AppletViewer "Restart" will jump from destroy method to - // init, that is why we need to check status w/ APPLET_DESTROY - if (status != APPLET_LOAD && status != APPLET_DESTROY) { - showAppletStatus("notloaded"); - break; - } - applet.resize(defaultAppletSize); - if (doInit) { - if (PerformanceLogger.loggingEnabled()) { - PerformanceLogger.setTime("Applet Init"); - PerformanceLogger.outputLog(); - } - applet.init(); - } - - //Need the default(fallback) font to be created in this AppContext - Font f = getFont(); - if (f == null || - "dialog".equals(f.getFamily().toLowerCase(Locale.ENGLISH)) && - f.getSize() == 12 && f.getStyle() == Font.PLAIN) { - setFont(new Font(Font.DIALOG, Font.PLAIN, 12)); - } - - doInit = true; // allow restarts - - // Validate the applet in event dispatch thread - // to avoid deadlock. - try { - final AppletPanel p = this; - - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - p.validate(); - } - }); - } - catch(InterruptedException ie) { - } - catch(InvocationTargetException ite) { - } - - status = APPLET_INIT; - showAppletStatus("inited"); - break; - - case APPLET_START: - { - if (status != APPLET_INIT && status != APPLET_STOP) { - showAppletStatus("notinited"); - break; - } - applet.resize(currentAppletSize); - applet.start(); - - // Validate and show the applet in event dispatch thread - // to avoid deadlock. - try { - final AppletPanel p = this; - final Applet a = applet; - - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - p.validate(); - a.setVisible(true); - - // Fix for BugTraq ID 4041703. - // Set the default focus for an applet. - if (hasInitialFocus()) - setDefaultFocus(); - } - }); - } - catch(InterruptedException ie) { - } - catch(InvocationTargetException ite) { - } - - status = APPLET_START; - showAppletStatus("started"); - - // reset size to make up for applets that specify height in % - try { - javax.swing.SwingUtilities.invokeLater(new Runnable() { - public void run() { - int width = getWidth(); - int height = getHeight(); - - appletResize(width, height); - validate(); - } - }); - } catch (Exception e) { - System.err.println("Applet resize failed."); - e.printStackTrace(); - } - - break; - } - case APPLET_STOP: - if (status != APPLET_START) { - showAppletStatus("notstarted"); - break; - } - status = APPLET_STOP; - - // Hide the applet in event dispatch thread - // to avoid deadlock. - try { - final Applet a = applet; - - SwingUtilities.invokeAndWait(new Runnable() { - public void run() - { - a.setVisible(false); - } - }); - } - catch(InterruptedException ie) { - } - catch(InvocationTargetException ite) { - } - - - // During Applet.stop(), any AccessControlException on an involved Class remains in - // the "memory" of the AppletClassLoader. If the same instance of the ClassLoader is - // reused, the same exception will occur during class loading. Set the AppletClassLoader's - // exceptionStatusSet flag to allow recognition of what had happened - // when reusing AppletClassLoader object. - try { - applet.stop(); - } catch (java.security.AccessControlException e) { - setExceptionStatus(e); - // rethrow exception to be handled as it normally would be. - throw e; - } - showAppletStatus("stopped"); - break; - - case APPLET_DESTROY: - if (status != APPLET_STOP && status != APPLET_INIT) { - showAppletStatus("notstopped"); - break; - } - status = APPLET_DESTROY; - - // During Applet.destroy(), any AccessControlException on an involved Class remains in - // the "memory" of the AppletClassLoader. If the same instance of the ClassLoader is - // reused, the same exception will occur during class loading. Set the AppletClassLoader's - // exceptionStatusSet flag to allow recognition of what had happened - // when reusing AppletClassLoader object. - try { - applet.destroy(); - } catch (java.security.AccessControlException e) { - setExceptionStatus(e); - // rethrow exception to be handled as it normally would be. - throw e; - } - showAppletStatus("destroyed"); - break; - - case APPLET_DISPOSE: - if (status != APPLET_DESTROY && status != APPLET_LOAD) { - showAppletStatus("notdestroyed"); - break; - } - status = APPLET_DISPOSE; - - try - { - final Applet a = applet; - - EventQueue.invokeAndWait(new Runnable() - { - public void run() - { - remove(a); - } - }); - } - catch(InterruptedException ie) - { - } - catch(InvocationTargetException ite) - { - } - applet = null; - showAppletStatus("disposed"); - disposed = true; - break; - - case APPLET_QUIT: - return; - } - } catch (Exception e) { - status = APPLET_ERROR; - if (e.getMessage() != null) { - showAppletStatus("exception2", e.getClass().getName(), - e.getMessage()); - } else { - showAppletStatus("exception", e.getClass().getName()); - } - showAppletException(e); - } catch (ThreadDeath e) { - showAppletStatus("death"); - return; - } catch (Error e) { - status = APPLET_ERROR; - if (e.getMessage() != null) { - showAppletStatus("error2", e.getClass().getName(), - e.getMessage()); - } else { - showAppletStatus("error", e.getClass().getName()); - } - showAppletException(e); - } - clearLoadAbortRequest(); - } - } - - /** - * Gets most recent focus owner component associated with the given window. - * It does that without calling Window.getMostRecentFocusOwner since it - * provides its own logic contradicting with setDefautlFocus. Instead, it - * calls KeyboardFocusManager directly. - */ - private Component getMostRecentFocusOwnerForWindow(Window w) { - Method meth = (Method)AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - Method meth = null; - try { - meth = KeyboardFocusManager.class.getDeclaredMethod("getMostRecentFocusOwner", new Class[] {Window.class}); - meth.setAccessible(true); - } catch (Exception e) { - // Must never happen - e.printStackTrace(); - } - return meth; - } - }); - if (meth != null) { - // Meth refers static method - try { - return (Component)meth.invoke(null, new Object[] {w}); - } catch (Exception e) { - // Must never happen - e.printStackTrace(); - } - } - // Will get here if exception was thrown or meth is null - return w.getMostRecentFocusOwner(); - } - - /* - * Fix for BugTraq ID 4041703. - * Set the focus to a reasonable default for an Applet. - */ - private void setDefaultFocus() { - Component toFocus = null; - Container parent = getParent(); - - if(parent != null) { - if (parent instanceof Window) { - toFocus = getMostRecentFocusOwnerForWindow((Window)parent); - if (toFocus == parent || toFocus == null) { - toFocus = parent.getFocusTraversalPolicy(). - getInitialComponent((Window)parent); - } - } else if (parent.isFocusCycleRoot()) { - toFocus = parent.getFocusTraversalPolicy(). - getDefaultComponent(parent); - } - } - - if (toFocus != null) { - if (parent instanceof EmbeddedFrame) { - ((EmbeddedFrame)parent).synthesizeWindowActivation(true); - } - // EmbeddedFrame might have focus before the applet was added. - // Thus after its activation the most recent focus owner will be - // restored. We need the applet's initial focusabled component to - // be focused here. - toFocus.requestFocusInWindow(); - } - } - - /** - * Load the applet into memory. - * Runs in a seperate (and interruptible) thread from the rest of the - * applet event processing so that it can be gracefully interrupted from - * things like HotJava. - */ - //Overridden by NetxPanel. - protected void runLoader() { - if (status != APPLET_DISPOSE) { - showAppletStatus("notdisposed"); - return; - } - - dispatchAppletEvent(APPLET_LOADING, null); - - // REMIND -- might be cool to visually indicate loading here -- - // maybe do animation? - status = APPLET_LOAD; - - // Create a class loader - loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey()); - - // Load the archives if present. - // REMIND - this probably should be done in a separate thread, - // or at least the additional archives (epll). - - String code = getCode(); - - // setup applet AppContext - // this must be called before loadJarFiles - setupAppletAppContext(); - - try { - loadJarFiles(loader); - applet = createApplet(loader); - } catch (ClassNotFoundException e) { - status = APPLET_ERROR; - showAppletStatus("notfound", code); - showAppletLog("notfound", code); - showAppletException(e); - return; - } catch (InstantiationException e) { - status = APPLET_ERROR; - showAppletStatus("nocreate", code); - showAppletLog("nocreate", code); - showAppletException(e); - return; - } catch (IllegalAccessException e) { - status = APPLET_ERROR; - showAppletStatus("noconstruct", code); - showAppletLog("noconstruct", code); - showAppletException(e); - // sbb -- I added a return here - return; - } catch (Exception e) { - status = APPLET_ERROR; - showAppletStatus("exception", e.getMessage()); - showAppletException(e); - return; - } catch (ThreadDeath e) { - status = APPLET_ERROR; - showAppletStatus("death"); - return; - } catch (Error e) { - status = APPLET_ERROR; - showAppletStatus("error", e.getMessage()); - showAppletException(e); - return; - } finally { - // notify that loading is no longer going on - dispatchAppletEvent(APPLET_LOADING_COMPLETED, null); - } - - // Fixed #4508194: NullPointerException thrown during - // quick page switch - // - if (applet != null) - { - // Stick it in the frame - applet.setStub(this); - applet.hide(); - add("Center", applet); - showAppletStatus("loaded"); - validate(); - } - } - - protected Applet createApplet(final AppletClassLoader loader) throws ClassNotFoundException, - IllegalAccessException, IOException, InstantiationException, InterruptedException { - final String serName = getSerializedObject(); - String code = getCode(); - - if (code != null && serName != null) { - System.err.println(amh.getMessage("runloader.err")); -// return null; - throw new InstantiationException("Either \"code\" or \"object\" should be specified, but not both."); - } - if (code == null && serName == null) { - String msg = "nocode"; - status = APPLET_ERROR; - showAppletStatus(msg); - showAppletLog(msg); - repaint(); - } - if (code != null) { - applet = (Applet)loader.loadCode(code).newInstance(); - doInit = true; - } else { - // serName is not null; - InputStream is = (InputStream) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - return loader.getResourceAsStream(serName); - } - }); - ObjectInputStream ois = - new AppletObjectInputStream(is, loader); - Object serObject = ois.readObject(); - applet = (Applet) serObject; - doInit = false; // skip over the first init - } - - // Determine the JDK level that the applet targets. - // This is critical for enabling certain backward - // compatibility switch if an applet is a JDK 1.1 - // applet. [stanley.ho] - findAppletJDKLevel(applet); - - if (Thread.interrupted()) { - try { - status = APPLET_DISPOSE; // APPLET_ERROR? - applet = null; - // REMIND: This may not be exactly the right thing: the - // status is set by the stop button and not necessarily - // here. - showAppletStatus("death"); - } finally { - Thread.currentThread().interrupt(); // resignal interrupt - } - return null; - } - return applet; - } - - protected void loadJarFiles(AppletClassLoader loader) throws IOException, - InterruptedException { - // Load the archives if present. - // REMIND - this probably should be done in a separate thread, - // or at least the additional archives (epll). - String jarFiles = getJarFiles(); - - if (jarFiles != null) { - StringTokenizer st = new StringTokenizer(jarFiles, ",", false); - while(st.hasMoreTokens()) { - String tok = st.nextToken().trim(); - try { - loader.addJar(tok); - } catch (IllegalArgumentException e) { - // bad archive name - continue; - } - } - } - } - - /** - * Request that the loading of the applet be stopped. - */ - protected synchronized void stopLoading() { - // REMIND: fill in the body - if (loaderThread != null) { - //System.out.println("Interrupting applet loader thread: " + loaderThread); - loaderThread.interrupt(); - } else { - setLoadAbortRequest(); - } - } - - - protected synchronized boolean okToLoad() { - return !loadAbortRequest; - } - - protected synchronized void clearLoadAbortRequest() { - loadAbortRequest = false; - } - - protected synchronized void setLoadAbortRequest() { - loadAbortRequest = true; - } - - - private synchronized void setLoaderThread(Thread loaderThread) { - this.loaderThread = loaderThread; - } - - /** - * Return true when the applet has been started. - */ - public boolean isActive() { - return status == APPLET_START; - } - - private EventQueue appEvtQ = null; - - /** - * Is called when the applet wants to be resized. - */ - public void appletResize(int width, int height) { - currentAppletSize.width = width; - currentAppletSize.height = height; - final Dimension currentSize = new Dimension(currentAppletSize.width, - currentAppletSize.height); - - if(loader != null) { - AppContext appCtxt = loader.getAppContext(); - if(appCtxt != null) - appEvtQ = (java.awt.EventQueue)appCtxt.get(AppContext.EVENT_QUEUE_KEY); - } - - final AppletPanel ap = this; - if (appEvtQ != null){ - appEvtQ.postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), - new Runnable(){ - public void run(){ - if(ap != null) - { - ap.dispatchAppletEvent(APPLET_RESIZE, currentSize); - } - } - })); - } - } - - public void setBounds(int x, int y, int width, int height) { - super.setBounds(x, y, width, height); - currentAppletSize.width = width; - currentAppletSize.height = height; - } - - public Applet getApplet() { - return applet; - } - - /** - * Status line. Called by the AppletPanel to provide - * feedback on the Applet's state. - */ - protected void showAppletStatus(String status) { - getAppletContext().showStatus(amh.getMessage(status)); - } - - protected void showAppletStatus(String status, Object arg) { - getAppletContext().showStatus(amh.getMessage(status, arg)); - } - protected void showAppletStatus(String status, Object arg1, Object arg2) { - getAppletContext().showStatus(amh.getMessage(status, arg1, arg2)); - } - - /** - * Called by the AppletPanel to print to the log. - */ - protected void showAppletLog(String msg) { - System.out.println(amh.getMessage(msg)); - } - - protected void showAppletLog(String msg, Object arg) { - System.out.println(amh.getMessage(msg, arg)); - } - - /** - * Called by the AppletPanel to provide - * feedback when an exception has happened. - */ - protected void showAppletException(Throwable t) { - t.printStackTrace(); - repaint(); - } - - /** - * Get caching key for classloader cache - */ - public String getClassLoaderCacheKey() - { - /** - * Fixed #4501142: Classlaoder sharing policy doesn't - * take "archive" into account. This will be overridden - * by Java Plug-in. [stanleyh] - */ - return getCodeBase().toString(); - } - - /** - * The class loaders - */ - private static HashMap classloaders = new HashMap(); - - /** - * Flush a class loader. - */ - public static synchronized void flushClassLoader(String key) { - classloaders.remove(key); - } - - /** - * Flush all class loaders. - */ - public static synchronized void flushClassLoaders() { - classloaders = new HashMap(); - } - - /** - * This method actually creates an AppletClassLoader. - * - * It can be override by subclasses (such as the Plug-in) - * to provide different classloaders. - */ - protected AppletClassLoader createClassLoader(final URL codebase) { - return new AppletClassLoader(codebase); - } - - /** - * Get a class loader. Create in a restricted context - */ - synchronized AppletClassLoader getClassLoader(final URL codebase, final String key) { - AppletClassLoader c = (AppletClassLoader)classloaders.get(key); - if (c == null) { - AccessControlContext acc = - getAccessControlContext(codebase); - c = (AppletClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - AppletClassLoader ac = createClassLoader(codebase); - /* Should the creation of the classloader be - * within the class synchronized block? Since - * this class is used by the plugin, take care - * to avoid deadlocks, or specialize - * AppletPanel within the plugin. It may take - * an arbitrary amount of time to create a - * class loader (involving getting Jar files - * etc.) and may block unrelated applets from - * finishing createAppletThread (due to the - * class synchronization). If - * createAppletThread does not finish quickly, - * the applet cannot process other messages, - * particularly messages such as destroy - * (which timeout when called from the browser). - */ - synchronized (getClass()) { - AppletClassLoader res = - (AppletClassLoader)classloaders.get(key); - if (res == null) { - classloaders.put(key, ac); - return ac; - } else { - return res; - } - } - } - },acc); - } - return c; - } - - /** - * get the context for the AppletClassLoader we are creating. - * the context is granted permission to create the class loader, - * connnect to the codebase, and whatever else the policy grants - * to all codebases. - */ - private AccessControlContext getAccessControlContext(final URL codebase) { - - PermissionCollection perms = (PermissionCollection) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - Policy p = java.security.Policy.getPolicy(); - if (p != null) { - return p.getPermissions(new CodeSource(null, - (java.security.cert.Certificate[]) null)); - } else { - return null; - } - } - }); - - if (perms == null) - perms = new Permissions(); - - //XXX: this is needed to be able to create the classloader itself! - - perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION); - - Permission p; - java.net.URLConnection urlConnection = null; - try { - urlConnection = codebase.openConnection(); - p = urlConnection.getPermission(); - } catch (java.io.IOException ioe) { - p = null; - } - - if (p != null) - perms.add(p); - - if (p instanceof FilePermission) { - - String path = p.getName(); - - int endIndex = path.lastIndexOf(File.separatorChar); - - if (endIndex != -1) { - path = path.substring(0, endIndex+1); - - if (path.endsWith(File.separator)) { - path += "-"; - } - perms.add(new FilePermission(path, - SecurityConstants.FILE_READ_ACTION)); - } - } else { - URL locUrl = codebase; - if (urlConnection instanceof JarURLConnection) { - locUrl = ((JarURLConnection)urlConnection).getJarFileURL(); - } - String host = locUrl.getHost(); - if (host != null && (host.length() > 0)) - perms.add(new SocketPermission(host, - SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION)); - } - - ProtectionDomain domain = - new ProtectionDomain(new CodeSource(codebase, - (java.security.cert.Certificate[]) null), perms); - AccessControlContext acc = - new AccessControlContext(new ProtectionDomain[] { domain }); - - return acc; - } - - public Thread getAppletHandlerThread() { - return handler; - } - - public int getAppletWidth() { - return currentAppletSize.width; - } - - public int getAppletHeight() { - return currentAppletSize.height; - } - - public static void changeFrameAppContext(Frame frame, AppContext newAppContext) - { - // 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. - - // Check if frame's AppContext has already been set properly - AppContext oldAppContext = SunToolkit.targetToAppContext(frame); - - if (oldAppContext == newAppContext) - return; - - // Synchronization on Window.class is needed for locking the - // critical section of the window list in AppContext. - synchronized (Window.class) - { - WeakReference weakRef = null; - // Remove frame from the Window list in wrong AppContext - { - // Lookup current frame's AppContext - Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>)oldAppContext.get(Window.class); - if (windowList != null) { - for (WeakReference ref : windowList) { - if (ref.get() == frame) { - weakRef = ref; - break; - } - } - // Remove frame from wrong AppContext - if (weakRef != null) - windowList.remove(weakRef); - } - } - - // Put the frame into the applet's AppContext map - SunToolkit.insertTargetMapping(frame, newAppContext); - - // Insert frame into the Window list in the applet's AppContext map - { - Vector<WeakReference<Window>> windowList = (Vector)newAppContext.get(Window.class); - if (windowList == null) { - windowList = new Vector<WeakReference<Window>>(); - newAppContext.put(Window.class, windowList); - } - // use the same weakRef here as it is used elsewhere - windowList.add(weakRef); - } - } - } - - // Flag to indicate if applet is targeted for JDK 1.1. - private boolean jdk11Applet = false; - - // Flag to indicate if applet is targeted for JDK 1.2. - private boolean jdk12Applet = false; - - /** - * Determine JDK level of an applet. - */ - private void findAppletJDKLevel(Applet applet) - { - // To determine the JDK level of an applet, the - // most reliable way is to check the major version - // of the applet class file. - - // synchronized on applet class object, so calling from - // different instances of the same applet will be - // serialized. - Class appletClass = applet.getClass(); - - synchronized(appletClass) { - // Determine if the JDK level of an applet has been - // checked before. - Boolean jdk11Target = (Boolean) loader.isJDK11Target(appletClass); - Boolean jdk12Target = (Boolean) loader.isJDK12Target(appletClass); - - // if applet JDK level has been checked before, retrieve - // value and return. - if (jdk11Target != null || jdk12Target != null) { - jdk11Applet = (jdk11Target == null) ? false : jdk11Target.booleanValue(); - jdk12Applet = (jdk12Target == null) ? false : jdk12Target.booleanValue(); - return; - } - - String name = appletClass.getName(); - - // first convert any '.' to '/' - name = name.replace('.', '/'); - - // append .class - final String resourceName = name + ".class"; - - InputStream is = null; - byte[] classHeader = new byte[8]; - - try { - is = (InputStream) java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - return loader.getResourceAsStream(resourceName); - } - }); - - // Read the first 8 bytes of the class file - int byteRead = is.read(classHeader, 0, 8); - is.close(); - - // return if the header is not read in entirely - // for some reasons. - if (byteRead != 8) - return; - } - catch (IOException e) { - return; - } - - // Check major version in class file header - int major_version = readShort(classHeader, 6); - - // Major version in class file is as follows: - // 45 - JDK 1.1 - // 46 - JDK 1.2 - // 47 - JDK 1.3 - // 48 - JDK 1.4 - // 49 - JDK 1.5 - if (major_version < 46) - jdk11Applet = true; - else if (major_version == 46) - jdk12Applet = true; - - // Store applet JDK level in AppContext for later lookup, - // e.g. page switch. - loader.setJDK11Target(appletClass, jdk11Applet); - loader.setJDK12Target(appletClass, jdk12Applet); - } - } - - /** - * Return true if applet is targeted to JDK 1.1. - */ - protected boolean isJDK11Applet() { - return jdk11Applet; - } - - /** - * Return true if applet is targeted to JDK1.2. - */ - protected boolean isJDK12Applet() { - return jdk12Applet; - } - - /** - * Read short from byte array. - */ - private int readShort(byte[] b, int off) { - int hi = readByte(b[off]); - int lo = readByte(b[off + 1]); - return (hi << 8) | lo; - } - - private int readByte(byte b) { - return ((int)b) & 0xFF; - } - - - private static AppletMessageHandler amh = new AppletMessageHandler("appletpanel"); -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletProps.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,221 +0,0 @@ -/* - * Copyright 1995-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.awt.*; -import java.io.*; -import java.util.Properties; -import sun.net.www.http.HttpClient; -import sun.net.ftp.FtpClient; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; - -import sun.security.action.*; - -class AppletProps extends Frame { - - TextField proxyHost; - TextField proxyPort; - Choice accessMode; - - AppletProps() { - setTitle(amh.getMessage("title")); - Panel p = new Panel(); - p.setLayout(new GridLayout(0, 2)); - - p.add(new Label(amh.getMessage("label.http.server", "Http proxy server:"))); - p.add(proxyHost = new TextField()); - - p.add(new Label(amh.getMessage("label.http.proxy"))); - p.add(proxyPort = new TextField()); - - p.add(new Label(amh.getMessage("label.class"))); - p.add(accessMode = new Choice()); - accessMode.addItem(amh.getMessage("choice.class.item.restricted")); - accessMode.addItem(amh.getMessage("choice.class.item.unrestricted")); - - add("Center", p); - p = new Panel(); - p.add(new Button(amh.getMessage("button.apply"))); - p.add(new Button(amh.getMessage("button.reset"))); - p.add(new Button(amh.getMessage("button.cancel"))); - add("South", p); - move(200, 150); - pack(); - reset(); - } - - void reset() { - AppletSecurity security = (AppletSecurity) System.getSecurityManager(); - if (security != null) - security.reset(); - - String proxyhost = (String) AccessController.doPrivileged( - new GetPropertyAction("http.proxyHost")); - String proxyport = (String) AccessController.doPrivileged( - new GetPropertyAction("http.proxyPort")); - - Boolean tmp = (Boolean) AccessController.doPrivileged( - new GetBooleanAction("package.restrict.access.sun")); - - boolean packageRestrict = tmp.booleanValue(); - if (packageRestrict) { - accessMode.select(amh.getMessage("choice.class.item.restricted")); - } else { - accessMode.select(amh.getMessage("choice.class.item.unrestricted")); - } - - if (proxyhost != null) { - proxyHost.setText(proxyhost); - proxyPort.setText(proxyport); - } else { - proxyHost.setText(""); - proxyPort.setText(""); - } - } - - void apply() { - String proxyHostValue = proxyHost.getText().trim(); - String proxyPortValue = proxyPort.getText().trim(); - - // Get properties - final Properties props = (Properties) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return System.getProperties(); - } - }); - - if (proxyHostValue.length() != 0) { - /* 4066402 */ - /* Check for parsable value in proxy port number field before */ - /* applying. Display warning to user until parsable value is */ - /* entered. */ - int proxyPortNumber = 0; - try { - proxyPortNumber = Integer.parseInt(proxyPortValue); - } catch (NumberFormatException e) {} - - if (proxyPortNumber <= 0) { - proxyPort.selectAll(); - proxyPort.requestFocus(); - (new AppletPropsErrorDialog(this, - amh.getMessage("title.invalidproxy"), - amh.getMessage("label.invalidproxy"), - amh.getMessage("button.ok"))).show(); - return; - } - /* end 4066402 */ - - props.put("http.proxyHost", proxyHostValue); - props.put("http.proxyPort", proxyPortValue); - } else { - props.put("http.proxyHost", ""); - } - - if (amh.getMessage("choice.class.item.restricted").equals(accessMode.getSelectedItem())) { - props.put("package.restrict.access.sun", "true"); - } else { - props.put("package.restrict.access.sun", "false"); - } - - // Save properties - try { - reset(); - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws IOException { - File dotAV = Main.theUserPropertiesFile; - FileOutputStream out = new FileOutputStream(dotAV); - Properties avProps = new Properties(); - for (int i = 0; i < Main.avDefaultUserProps.length; i++) { - String avKey = Main.avDefaultUserProps[i][0]; - avProps.setProperty(avKey, props.getProperty(avKey)); - } - avProps.store(out, amh.getMessage("prop.store")); - out.close(); - return null; - } - }); - hide(); - } catch (java.security.PrivilegedActionException e) { - System.out.println(amh.getMessage("apply.exception", - e.getException())); - // XXX what's the general feeling on stack traces to System.out? - e.printStackTrace(); - reset(); - } - } - - public boolean action(Event evt, Object obj) { - if (amh.getMessage("button.apply").equals(obj)) { - apply(); - return true; - } - if (amh.getMessage("button.reset").equals(obj)) { - reset(); - return true; - } - if (amh.getMessage("button.cancel").equals(obj)) { - reset(); - hide(); - return true; - } - return false; - } - - private static AppletMessageHandler amh = new AppletMessageHandler("appletprops"); - -} - -/* 4066432 */ -/* Dialog class to display property-related errors to user */ - -class AppletPropsErrorDialog extends Dialog { - public AppletPropsErrorDialog(Frame parent, String title, String message, - String buttonText) { - super(parent, title, true); - Panel p = new Panel(); - add("Center", new Label(message)); - p.add(new Button(buttonText)); - add("South", p); - pack(); - - Dimension dDim = size(); - Rectangle fRect = parent.bounds(); - move(fRect.x + ((fRect.width - dDim.width) / 2), - fRect.y + ((fRect.height - dDim.height) / 2)); - } - - public boolean action(Event event, Object object) { - hide(); - dispose(); - return true; - } -} - -/* end 4066432 */
--- a/plugin/icedtea/java/src/main/sun/applet/AppletResourceLoader.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright 1996-1998 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.net.URL; -import java.awt.Image; -import sun.misc.Ref; - -/** - * Part of this class still remains only to support legacy, 100%-impure - * applications such as HotJava 1.0.1. - */ -public class AppletResourceLoader { - public static Image getImage(URL url) { - return AppletViewer.getCachedImage(url); - } - - public static Ref getImageRef(URL url) { - return AppletViewer.getCachedImageRef(url); - } - - public static void flushImages() { - AppletViewer.flushImageCache(); - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletSecurity.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,371 +0,0 @@ -/* - * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.io.File; -import java.io.FilePermission; -import java.io.IOException; -import java.io.FileDescriptor; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.net.SocketPermission; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.HashSet; -import java.util.StringTokenizer; -import java.security.*; -import java.lang.reflect.*; -import sun.awt.AWTSecurityManager; -import sun.awt.AppContext; -import sun.security.provider.*; -import sun.security.util.SecurityConstants; - - -/** - * This class defines an applet security policy - * - */ -public -class AppletSecurity extends AWTSecurityManager { - private AppContext mainAppContext; - - //URLClassLoader.acc - private static Field facc = null; - - //AccessControlContext.context; - private static Field fcontext = null; - - static { - try { - facc = URLClassLoader.class.getDeclaredField("acc"); - facc.setAccessible(true); - fcontext = AccessControlContext.class.getDeclaredField("context"); - fcontext.setAccessible(true); - } catch (NoSuchFieldException e) { - throw new UnsupportedOperationException(e); - } - } - - - /** - * Construct and initialize. - */ - public AppletSecurity() { - reset(); - mainAppContext = AppContext.getAppContext(); - } - - // Cache to store known restricted packages - private HashSet restrictedPackages = new HashSet(); - - /** - * Reset from Properties - */ - public void reset() - { - // Clear cache - restrictedPackages.clear(); - - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() - { - // Enumerate system properties - Enumeration e = System.getProperties().propertyNames(); - - while (e.hasMoreElements()) - { - String name = (String) e.nextElement(); - - if (name != null && name.startsWith("package.restrict.access.")) - { - String value = System.getProperty(name); - - if (value != null && value.equalsIgnoreCase("true")) - { - String pkg = name.substring(24); - - // Cache restricted packages - restrictedPackages.add(pkg); - } - } - } - return null; - } - }); - } - - /** - * get the current (first) instance of an AppletClassLoader on the stack. - */ - private AppletClassLoader currentAppletClassLoader() - { - // try currentClassLoader first - ClassLoader loader = currentClassLoader(); - - if ((loader == null) || (loader instanceof AppletClassLoader)) - return (AppletClassLoader)loader; - - // if that fails, get all the classes on the stack and check them. - Class[] context = getClassContext(); - for (int i = 0; i < context.length; i++) { - loader = context[i].getClassLoader(); - if (loader instanceof AppletClassLoader) - return (AppletClassLoader)loader; - } - - /* - * fix bug # 6433620 the logic here is : try to find URLClassLoader from - * class context, check its AccessControlContext to see if - * AppletClassLoader is in stack when it's created. for this kind of - * URLClassLoader, return the AppContext assocated with the - * AppletClassLoader. - */ - for (int i = 0; i < context.length; i++) { - final ClassLoader currentLoader = context[i].getClassLoader(); - - if (currentLoader instanceof URLClassLoader) { - loader = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - - AccessControlContext acc = null; - ProtectionDomain[] pds = null; - - try { - acc = (AccessControlContext) facc.get(currentLoader); - if (acc == null) { - return null; - } - - pds = (ProtectionDomain[]) fcontext.get(acc); - if (pds == null) { - return null; - } - } catch (Exception e) { - throw new UnsupportedOperationException(e); - } - - for (int i=0; i<pds.length; i++) { - ClassLoader cl = pds[i].getClassLoader(); - - if (cl instanceof AppletClassLoader) { - return cl; - } - } - - return null; - } - }); - - if (loader != null) { - return (AppletClassLoader) loader; - } - } - } - - // if that fails, try the context class loader - loader = Thread.currentThread().getContextClassLoader(); - if (loader instanceof AppletClassLoader) - return (AppletClassLoader)loader; - - // no AppletClassLoaders on the stack - return (AppletClassLoader)null; - } - - /** - * Returns true if this threadgroup is in the applet's own thread - * group. This will return false if there is no current class - * loader. - */ - protected boolean inThreadGroup(ThreadGroup g) { - if (currentAppletClassLoader() == null) - return false; - else - return getThreadGroup().parentOf(g); - } - - /** - * Returns true of the threadgroup of thread is in the applet's - * own threadgroup. - */ - protected boolean inThreadGroup(Thread thread) { - return inThreadGroup(thread.getThreadGroup()); - } - - /** - * Applets are not allowed to manipulate threads outside - * applet thread groups. However a terminated thread no longer belongs - * to any group. - */ - public void checkAccess(Thread t) { - /* When multiple applets is reloaded simultaneously, there will be - * multiple invocations to this method from plugin's SecurityManager. - * This method should not be synchronized to avoid deadlock when - * a page with multiple applets is reloaded - */ - if ((t.getState() != Thread.State.TERMINATED) && !inThreadGroup(t)) { - checkPermission(SecurityConstants.MODIFY_THREAD_PERMISSION); - } - } - - private boolean inThreadGroupCheck = false; - - /** - * Applets are not allowed to manipulate thread groups outside - * applet thread groups. - */ - public synchronized void checkAccess(ThreadGroup g) { - if (inThreadGroupCheck) { - // if we are in a recursive check, it is because - // inThreadGroup is calling appletLoader.getThreadGroup - // in that case, only do the super check, as appletLoader - // has a begin/endPrivileged - checkPermission(SecurityConstants.MODIFY_THREADGROUP_PERMISSION); - } else { - try { - inThreadGroupCheck = true; - if (!inThreadGroup(g)) { - checkPermission(SecurityConstants.MODIFY_THREADGROUP_PERMISSION); - } - } finally { - inThreadGroupCheck = false; - } - } - } - - - /** - * Throws a <code>SecurityException</code> if the - * calling thread is not allowed to access the package specified by - * the argument. - * <p> - * This method is used by the <code>loadClass</code> method of class - * loaders. - * <p> - * The <code>checkPackageAccess</code> method for class - * <code>SecurityManager</code> calls - * <code>checkPermission</code> with the - * <code>RuntimePermission("accessClassInPackage."+pkg)</code> - * permission. - * - * @param pkg the package name. - * @exception SecurityException if the caller does not have - * permission to access the specified package. - * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean) - */ - public void checkPackageAccess(final String pkgname) { - - // first see if the VM-wide policy allows access to this package - super.checkPackageAccess(pkgname); - - // now check the list of restricted packages - for (Iterator iter = restrictedPackages.iterator(); iter.hasNext();) - { - String pkg = (String) iter.next(); - - // Prevent matching "sun" and "sunir" even if they - // starts with similar beginning characters - // - if (pkgname.equals(pkg) || pkgname.startsWith(pkg + ".")) - { - checkPermission(new java.lang.RuntimePermission - ("accessClassInPackage." + pkgname)); - } - } - } - - /** - * Tests if a client can get access to the AWT event queue. - * <p> - * This method calls <code>checkPermission</code> with the - * <code>AWTPermission("accessEventQueue")</code> permission. - * - * @since JDK1.1 - * @exception SecurityException if the caller does not have - * permission to accesss the AWT event queue. - */ - public void checkAwtEventQueueAccess() { - AppContext appContext = AppContext.getAppContext(); - AppletClassLoader appletClassLoader = currentAppletClassLoader(); - - if ((appContext == mainAppContext) && (appletClassLoader != null)) { - // If we're about to allow access to the main EventQueue, - // and anything untrusted is on the class context stack, - // disallow access. - super.checkAwtEventQueueAccess(); - } - } // checkAwtEventQueueAccess() - - /** - * Returns the thread group of the applet. We consult the classloader - * if there is one. - */ - public ThreadGroup getThreadGroup() { - /* If any applet code is on the execution stack, we return - that applet's ThreadGroup. Otherwise, we use the default - behavior. */ - AppletClassLoader appletLoader = currentAppletClassLoader(); - ThreadGroup loaderGroup = (appletLoader == null) ? null - : appletLoader.getThreadGroup(); - if (loaderGroup != null) { - return loaderGroup; - } else { - return super.getThreadGroup(); - } - } // getThreadGroup() - - /** - * Get the AppContext corresponding to the current context. - * The default implementation returns null, but this method - * may be overridden by various SecurityManagers - * (e.g. AppletSecurity) to index AppContext objects by the - * calling context. - * - * @return the AppContext corresponding to the current context. - * @see sun.awt.AppContext - * @see java.lang.SecurityManager - * @since JDK1.2.1 - */ - public AppContext getAppContext() { - AppletClassLoader appletLoader = currentAppletClassLoader(); - - if (appletLoader == null) { - return null; - } else { - AppContext context = appletLoader.getAppContext(); - - // context == null when some thread in applet thread group - // has not been destroyed in AppContext.dispose() - if (context == null) { - throw new SecurityException("Applet classloader has invalid AppContext"); - } - - return context; - } - } - -} // class AppletSecurity
--- a/plugin/icedtea/java/src/main/sun/applet/AppletSecurityContext.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -package sun.applet; - -import java.util.HashMap; - -public abstract class AppletSecurityContext { - - public static PluginStreamHandler streamhandler; - - public static void setStreamhandler(PluginStreamHandler sh) { - streamhandler = sh; - } - - public abstract void handleMessage(String src, int reference, String message); - - public abstract void addClassLoader(String id, ClassLoader cl); - - public abstract void dumpStore(); - - public abstract Object getObject(int identifier); - - public abstract int getIdentifier(Object o); - - public abstract void store(Object o); - -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletSecurityContextManager.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -package sun.applet; - -import java.util.HashMap; - -public class AppletSecurityContextManager { - - // Context identifier -> PluginAppletSecurityContext object. - // FIXME: make private - private static HashMap<Integer, AppletSecurityContext> contexts = new HashMap(); - - public static void addContext(int identifier, AppletSecurityContext context) { - contexts.put(identifier, context); - } - - public static AppletSecurityContext getSecurityContext(int identifier) { - return contexts.get(identifier); - } - - public static void dumpStore(int identifier) { - contexts.get(identifier).dumpStore(); - } - - public static void handleMessage(int identifier, String src, int reference, String message) { - System.err.println(identifier + " -- " + src + " -- " + reference + " -- " + message + " CONTEXT= " + contexts.get(identifier)); - contexts.get(identifier).handleMessage(src, reference, message); - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletSecurityException.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright 1995-1998 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -/** - * An applet security exception. - * - * @author Arthur van Hoff - */ -public -class AppletSecurityException extends SecurityException { - private String key = null; - private Object msgobj[] = null; - - public AppletSecurityException(String name) { - super(name); - this.key = name; - } - - public AppletSecurityException(String name, String arg) { - this(name); - msgobj = new Object[1]; - msgobj[0] = (Object)arg; - } - - public AppletSecurityException(String name, String arg1, String arg2) { - this(name); - msgobj = new Object[2]; - msgobj[0] = (Object)arg1; - msgobj[1] = (Object)arg2; - } - - public String getLocalizedMessage() { - if( msgobj != null) - return amh.getMessage(key, msgobj); - else - return amh.getMessage(key); - } - - private static AppletMessageHandler amh = new AppletMessageHandler("appletsecurityexception"); - -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletThreadGroup.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright 1995-1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -/** - * This class defines an applet thread group. - * - * @author Arthur van Hoff - */ -public class AppletThreadGroup extends ThreadGroup { - - /** - * Constructs a new thread group for an applet. - * The parent of this new group is the thread - * group of the currently running thread. - * - * @param name the name of the new thread group. - */ - public AppletThreadGroup(String name) { - this(Thread.currentThread().getThreadGroup(), name); - } - - /** - * Creates a new thread group for an applet. - * The parent of this new group is the specified - * thread group. - * - * @param parent the parent thread group. - * @param name the name of the new thread group. - * @exception NullPointerException if the thread group argument is - * <code>null</code>. - * @exception SecurityException if the current thread cannot create a - * thread in the specified thread group. - * @see java.lang.SecurityException - * @since JDK1.1.1 - */ - public AppletThreadGroup(ThreadGroup parent, String name) { - super(parent, name); - setMaxPriority(Thread.NORM_PRIORITY - 1); - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletViewerFactory.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright 1996 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -/* - * AppletViewerFactory.java - */ - -package sun.applet; - -import java.util.Hashtable; -import java.net.URL; -import java.awt.MenuBar; - -public -interface AppletViewerFactory { - public AppletViewer createAppletViewer(int x, int y, URL doc, Hashtable atts); - public MenuBar getBaseMenuBar(); - public boolean isStandalone(); -}
--- a/plugin/icedtea/java/src/main/sun/applet/AppletViewerPanel.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,254 +0,0 @@ -/* - * Copyright 1995-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.applet.AppletContext; -import java.awt.Dimension; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Hashtable; - - -/** - * Sample applet panel class. The panel manages and manipulates the - * applet as it is being loaded. It forks a seperate thread in a new - * thread group to call the applet's init(), start(), stop(), and - * destroy() methods. - * - * @author Arthur van Hoff - */ -public class AppletViewerPanel extends AppletPanel { - - /* Are we debugging? */ - protected static boolean debug = true; - - /** - * The document url. - */ - protected URL documentURL; - - /** - * The base url. - */ - protected URL baseURL; - - /** - * The attributes of the applet. - */ - protected Hashtable atts; - - /* - * JDK 1.1 serialVersionUID - */ - private static final long serialVersionUID = 8890989370785545619L; - - private Dimension windowSizeFactor = new Dimension(750, 350); - - /** - * Construct an applet viewer and start the applet. - */ - protected AppletViewerPanel(URL documentURL, Hashtable atts) { - this.documentURL = documentURL; - this.atts = atts; - - String att = getParameter("codebase"); - if (att != null) { - if (!att.endsWith("/")) { - att += "/"; - } - try { - baseURL = new URL(documentURL, att); - } catch (MalformedURLException e) { - } - } - if (baseURL == null) { - String file = documentURL.getFile(); - int i = file.lastIndexOf('/'); - if (i >= 0 && i < file.length() - 1) { - try { - baseURL = new URL(documentURL, file.substring(0, i + 1)); - } catch (MalformedURLException e) { - } - } - } - - // when all is said & done, baseURL shouldn't be null - if (baseURL == null) - baseURL = documentURL; - - - } - - - /** - * Get an applet parameter. - */ - public String getParameter(String name) { - return (String)atts.get(name.toLowerCase()); - } - - /** - * Get the document url. - */ - public URL getDocumentBase() { - return documentURL; - - } - - /** - * Get the base url. - */ - public URL getCodeBase() { - return baseURL; - } - - /** - * Set applet size (as proportion of window size) if needed - */ - public synchronized void setAppletSizeIfNeeded(int width, int height) { - - Dimension newD = new Dimension(getWidth(), getHeight()); - - String h = getParameter("height"); - String w = getParameter("width"); - - if (width != -1 && w != null && w.endsWith("%")) { - newD.width = (Integer.valueOf(w.substring(0, w.length() - 1)).intValue()/100)*width; - } - - if (height != -1 && h != null && h.endsWith("%")) { - newD.height = (Integer.valueOf(h.substring(0, h.length() - 1)).intValue()/100)*height; - } - - synchronized(windowSizeFactor) { - windowSizeFactor = newD; - } - } - - /** - * Get the width. - */ - public int getWidth() { - String w = getParameter("width"); - if (w != null) { - try { - return Integer.valueOf(w).intValue(); - } catch (NumberFormatException nfe) { - synchronized(windowSizeFactor) { - System.err.println("getWidth() returning " + windowSizeFactor.width); - return windowSizeFactor.width; - } - } - } - return 0; - } - - - /** - * Get the height. - */ - public int getHeight() { - String h = getParameter("height"); - if (h != null) { - try { - return Integer.valueOf(h).intValue(); - } catch (NumberFormatException nfe) { - synchronized(windowSizeFactor) { - System.err.println("getHeight() returning " + windowSizeFactor.height); - return windowSizeFactor.height; - } - } - } - return 0; - } - - /** - * Get initial_focus - */ - public boolean hasInitialFocus() - { - - // 6234219: Do not set initial focus on an applet - // during startup if applet is targeted for - // JDK 1.1/1.2. [stanley.ho] - if (isJDK11Applet() || isJDK12Applet()) - return false; - - String initialFocus = getParameter("initial_focus"); - - if (initialFocus != null) - { - if (initialFocus.toLowerCase().equals("false")) - return false; - } - - return true; - } - - /** - * Get the code parameter - */ - public String getCode() { - return getParameter("code"); - } - - - /** - * Return the list of jar files if specified. - * Otherwise return null. - */ - public String getJarFiles() { - return getParameter("archive"); - } - - /** - * Return the value of the object param - */ - public String getSerializedObject() { - return getParameter("object");// another name? - } - - - /** - * Get the applet context. For now this is - * also implemented by the AppletPanel class. - */ - public AppletContext getAppletContext() { - return (AppletContext)getParent(); - } - - protected static void debug(String s) { - if(debug) - System.err.println("AppletViewerPanel:::" + s); - } - - protected static void debug(String s, Throwable t) { - if(debug) { - t.printStackTrace(); - debug(s); - } - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/Main.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,533 +0,0 @@ -/* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.applet; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; -import java.net.URL; -import java.net.MalformedURLException; -import java.util.Enumeration; -import java.util.Properties; -import java.util.Vector; -import sun.net.www.ParseUtil; - -/** - * The main entry point into AppletViewer. - */ -public class Main { - /** - * The file which contains all of the AppletViewer specific properties. - */ - static File theUserPropertiesFile; - - /** - * The default key/value pairs for the required user-specific properties. - */ - static final String [][] avDefaultUserProps = { - // There's a bootstrapping problem here. If we don't have a proxyHost, - // then we will not be able to connect to a URL outside the firewall; - // however, there's no way for us to set the proxyHost without starting - // AppletViewer. This problem existed before the re-write. - {"http.proxyHost", ""}, - {"http.proxyPort", "80"}, - {"package.restrict.access.sun", "true"} - }; - - static { - File userHome = new File(System.getProperty("user.home")); - // make sure we can write to this location - userHome.canWrite(); - - theUserPropertiesFile = new File(userHome, ".appletviewer"); - } - - // i18n - private static AppletMessageHandler amh = new AppletMessageHandler("appletviewer"); - - /** - * Member variables set according to options passed in to AppletViewer. - */ - private boolean debugFlag = false; - private boolean helpFlag = false; - private String encoding = null; - private boolean noSecurityFlag = false; - private static boolean cmdLineTestFlag = false; - - /** - * The list of valid URLs passed in to AppletViewer. - */ - private static Vector urlList = new Vector(1); - - // This is used in init(). Getting rid of this is desirable but depends - // on whether the property that uses it is necessary/standard. - public static final String theVersion = System.getProperty("java.version"); - - /** - * The main entry point into AppletViewer. - */ - public static void main(String [] args) { - Main m = new Main(); - int ret = m.run(args); - - // Exit immediately if we got some sort of error along the way. - // For debugging purposes, if we have passed in "-XcmdLineTest" we - // force a premature exit. - if ((ret != 0) || (cmdLineTestFlag)) - System.exit(ret); - } - - private int run(String [] args) { - // DECODE ARGS - try { - if (args.length == 0) { - usage(); - return 0; - } - for (int i = 0; i < args.length; ) { - int j = decodeArg(args, i); - if (j == 0) { - throw new ParseException(lookup("main.err.unrecognizedarg", - args[i])); - } - i += j; - } - } catch (ParseException e) { - System.err.println(e.getMessage()); - return 1; - } - - // CHECK ARGUMENTS - if (helpFlag) { - usage(); - return 0; - } - - if (urlList.size() == 0) { - System.err.println(lookup("main.err.inputfile")); - return 1; - } - - if (debugFlag) { - // START A DEBUG SESSION - // Given the current architecture, we will end up decoding the - // arguments again, but at least we are guaranteed to have - // arguments which are valid. - return invokeDebugger(args); - } - - // INSTALL THE SECURITY MANAGER (if necessary) - if (!noSecurityFlag && (System.getSecurityManager() == null)) - init(); - - // LAUNCH APPLETVIEWER FOR EACH URL - for (int i = 0; i < urlList.size(); i++) { - try { - // XXX 5/17 this parsing method should be changed/fixed so that - // it doesn't do both parsing of the html file and launching of - // the AppletPanel - AppletViewer.parse((URL) urlList.elementAt(i), encoding); - } catch (IOException e) { - System.err.println(lookup("main.err.io", e.getMessage())); - return 1; - } - } - return 0; - } - - private static void usage() { - System.out.println(lookup("usage")); - } - - /** - * Decode a single argument in an array and return the number of elements - * used. - * - * @param args The array of arguments. - * @param i The argument to decode. - * @return The number of array elements used when the argument was - * decoded. - * @exception ParseException - * Thrown when there is a problem with something in the - * argument array. - */ - private int decodeArg(String [] args, int i) throws ParseException { - String arg = args[i]; - int argc = args.length; - - if ("-help".equalsIgnoreCase(arg) || "-?".equals(arg)) { - helpFlag = true; - return 1; - } else if ("-encoding".equals(arg) && (i < argc - 1)) { - if (encoding != null) - throw new ParseException(lookup("main.err.dupoption", arg)); - encoding = args[++i]; - return 2; - } else if ("-debug".equals(arg)) { - debugFlag = true; - return 1; - } else if ("-Xnosecurity".equals(arg)) { - // This is an undocumented (and, in the future, unsupported) - // flag which prevents AppletViewer from installing its own - // SecurityManager. - - System.err.println(); - System.err.println(lookup("main.warn.nosecmgr")); - System.err.println(); - - noSecurityFlag = true; - return 1; - } else if ("-XcmdLineTest".equals(arg)) { - // This is an internal flag which should be used for command-line - // testing. It instructs AppletViewer to force a premature exit - // immediately after the applet has been launched. - cmdLineTestFlag = true; - return 1; - } else if (arg.startsWith("-")) { - throw new ParseException(lookup("main.err.unsupportedopt", arg)); - } else { - // we found what we hope is a url - URL url = parseURL(arg); - if (url != null) { - urlList.addElement(url); - return 1; - } - } - return 0; - } - - /** - * Following the relevant RFC, construct a valid URL based on the passed in - * string. - * - * @param url a string which represents either a relative or absolute URL. - * @return a URL when the passed in string can be interpreted according - * to the RFC, <code>null</code> otherwise. - * @exception ParseException - * Thrown when we are unable to construct a proper URL from the - * passed in string. - */ - private URL parseURL(String url) throws ParseException { - URL u = null; - // prefix of the urls with 'file' scheme - String prefix = "file:"; - - try { - if (url.indexOf(':') <= 1) - { - // appletviewer accepts only unencoded filesystem paths - u = ParseUtil.fileToEncodedURL(new File(url)); - } else if (url.startsWith(prefix) && - url.length() != prefix.length() && - !(new File(url.substring(prefix.length())).isAbsolute())) - { - // relative file URL, like this "file:index.html" - // ensure that this file URL is absolute - // ParseUtil.fileToEncodedURL should be done last (see 6329251) - String path = ParseUtil.fileToEncodedURL(new File(System.getProperty("user.dir"))).getPath() + - url.substring(prefix.length()); - u = new URL("file", "", path); - } else { - // appletviewer accepts only encoded urls - u = new URL(url); - } - } catch (MalformedURLException e) { - throw new ParseException(lookup("main.err.badurl", - url, e.getMessage())); - } - - return u; - } - - /** - * Invoke the debugger with the arguments passed in to appletviewer. - * - * @param args The arguments passed into the debugger. - * @return <code>0</code> if the debugger is invoked successfully, - * <code>1</code> otherwise. - */ - private int invokeDebugger(String [] args) { - // CONSTRUCT THE COMMAND LINE - String [] newArgs = new String[args.length + 1]; - int current = 0; - - // Add a -classpath argument that prevents - // the debugger from launching appletviewer with the default of - // ".". appletviewer's classpath should never contain valid - // classes since they will result in security exceptions. - // Ideally, the classpath should be set to "", but the VM won't - // allow an empty classpath, so a phony directory name is used. - String phonyDir = System.getProperty("java.home") + - File.separator + "phony"; - newArgs[current++] = "-Djava.class.path=" + phonyDir; - - // Appletviewer's main class is the debuggee - newArgs[current++] = "sun.applet.Main"; - - // Append all the of the original appletviewer arguments, - // leaving out the "-debug" option. - for (int i = 0; i < args.length; i++) { - if (!("-debug".equals(args[i]))) { - newArgs[current++] = args[i]; - } - } - - // LAUNCH THE DEBUGGER - // Reflection is used for two reasons: - // 1) The debugger classes are on classpath and thus must be loaded - // by the application class loader. (Currently, appletviewer are - // loaded through the boot class path out of rt.jar.) - // 2) Reflection removes any build dependency between appletviewer - // and jdb. - try { - Class c = Class.forName("com.sun.tools.example.debug.tty.TTY", true, - ClassLoader.getSystemClassLoader()); - Method m = c.getDeclaredMethod("main", - new Class[] { String[].class }); - m.invoke(null, new Object[] { newArgs }); - } catch (ClassNotFoundException cnfe) { - System.err.println(lookup("main.debug.cantfinddebug")); - return 1; - } catch (NoSuchMethodException nsme) { - System.err.println(lookup("main.debug.cantfindmain")); - return 1; - } catch (InvocationTargetException ite) { - System.err.println(lookup("main.debug.exceptionindebug")); - return 1; - } catch (IllegalAccessException iae) { - System.err.println(lookup("main.debug.cantaccess")); - return 1; - } - return 0; - } - - private void init() { - // GET APPLETVIEWER USER-SPECIFIC PROPERTIES - Properties avProps = getAVProps(); - - // ADD OTHER RANDOM PROPERTIES - // XXX 5/18 need to revisit why these are here, is there some - // standard for what is available? - - // Standard browser properties - avProps.put("browser", "sun.applet.AppletViewer"); - avProps.put("browser.version", "1.06"); - avProps.put("browser.vendor", "Sun Microsystems Inc."); - avProps.put("http.agent", "Java(tm) 2 SDK, Standard Edition v" + theVersion); - - // Define which packages can be extended by applets - // XXX 5/19 probably not needed, not checked in AppletSecurity - avProps.put("package.restrict.definition.java", "true"); - avProps.put("package.restrict.definition.sun", "true"); - - // Define which properties can be read by applets. - // A property named by "key" can be read only when its twin - // property "key.applet" is true. The following ten properties - // are open by default. Any other property can be explicitly - // opened up by the browser user by calling appletviewer with - // -J-Dkey.applet=true - avProps.put("java.version.applet", "true"); - avProps.put("java.vendor.applet", "true"); - avProps.put("java.vendor.url.applet", "true"); - avProps.put("java.class.version.applet", "true"); - avProps.put("os.name.applet", "true"); - avProps.put("os.version.applet", "true"); - avProps.put("os.arch.applet", "true"); - avProps.put("file.separator.applet", "true"); - avProps.put("path.separator.applet", "true"); - avProps.put("line.separator.applet", "true"); - - // Read in the System properties. If something is going to be - // over-written, warn about it. - Properties sysProps = System.getProperties(); - for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements(); ) { - String key = (String) e.nextElement(); - String val = (String) sysProps.getProperty(key); - String oldVal; - if ((oldVal = (String) avProps.setProperty(key, val)) != null) - System.err.println(lookup("main.warn.prop.overwrite", key, - oldVal, val)); - } - - // INSTALL THE PROPERTY LIST - System.setProperties(avProps); - - // Create and install the security manager - if (!noSecurityFlag) { - System.setSecurityManager(new AppletSecurity()); - } else { - System.err.println(lookup("main.nosecmgr")); - } - - // REMIND: Create and install a socket factory! - } - - /** - * Read the AppletViewer user-specific properties. Typically, these - * properties should reside in the file $USER/.appletviewer. If this file - * does not exist, one will be created. Information for this file will - * be gleaned from $USER/.hotjava/properties. If that file does not exist, - * then default values will be used. - * - * @return A Properties object containing all of the AppletViewer - * user-specific properties. - */ - private Properties getAVProps() { - Properties avProps = new Properties(); - - File dotAV = theUserPropertiesFile; - if (dotAV.exists()) { - // we must have already done the conversion - if (dotAV.canRead()) { - // just read the file - avProps = getAVProps(dotAV); - } else { - // send out warning and use defaults - System.err.println(lookup("main.warn.cantreadprops", - dotAV.toString())); - avProps = setDefaultAVProps(); - } - } else { - // create the $USER/.appletviewer file - - // see if $USER/.hotjava/properties exists - File userHome = new File(System.getProperty("user.home")); - File dotHJ = new File(userHome, ".hotjava"); - dotHJ = new File(dotHJ, "properties"); - if (dotHJ.exists()) { - // just read the file - avProps = getAVProps(dotHJ); - } else { - // send out warning and use defaults - System.err.println(lookup("main.warn.cantreadprops", - dotHJ.toString())); - avProps = setDefaultAVProps(); - } - - // SAVE THE FILE - try { - FileOutputStream out = new FileOutputStream(dotAV); - avProps.store(out, lookup("main.prop.store")); - out.close(); - } catch (IOException e) { - System.err.println(lookup("main.err.prop.cantsave", - dotAV.toString())); - } - } - return avProps; - } - - /** - * Set the AppletViewer user-specific properties to be the default values. - * - * @return A Properties object containing all of the AppletViewer - * user-specific properties, set to the default values. - */ - private Properties setDefaultAVProps() { - Properties avProps = new Properties(); - for (int i = 0; i < avDefaultUserProps.length; i++) { - avProps.setProperty(avDefaultUserProps[i][0], - avDefaultUserProps[i][1]); - } - return avProps; - } - - /** - * Given a file, find only the properties that are setable by AppletViewer. - * - * @param inFile A Properties file from which we select the properties of - * interest. - * @return A Properties object containing all of the AppletViewer - * user-specific properties. - */ - private Properties getAVProps(File inFile) { - Properties avProps = new Properties(); - - // read the file - Properties tmpProps = new Properties(); - try { - FileInputStream in = new FileInputStream(inFile); - tmpProps.load(new BufferedInputStream(in)); - in.close(); - } catch (IOException e) { - System.err.println(lookup("main.err.prop.cantread", - inFile.toString())); - } - - // pick off the properties we care about - for (int i = 0; i < avDefaultUserProps.length; i++) { - String value = tmpProps.getProperty(avDefaultUserProps[i][0]); - if (value != null) { - // the property exists in the file, so replace the default - avProps.setProperty(avDefaultUserProps[i][0], value); - } else { - // just use the default - avProps.setProperty(avDefaultUserProps[i][0], - avDefaultUserProps[i][1]); - } - } - return avProps; - } - - /** - * Methods for easier i18n handling. - */ - - private static String lookup(String key) { - return amh.getMessage(key); - } - - private static String lookup(String key, String arg0) { - return amh.getMessage(key, arg0); - } - - private static String lookup(String key, String arg0, String arg1) { - return amh.getMessage(key, arg0, arg1); - } - - private static String lookup(String key, String arg0, String arg1, - String arg2) { - return amh.getMessage(key, arg0, arg1, arg2); - } - - class ParseException extends RuntimeException - { - public ParseException(String msg) { - super(msg); - } - - public ParseException(Throwable t) { - super(t.getMessage()); - this.t = t; - } - - Throwable t = null; - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginAppletViewer.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1481 +0,0 @@ - /* - * Copyright 1995-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - - package sun.applet; - - import java.applet.Applet; -import java.applet.AppletContext; -import java.applet.AudioClip; -import java.awt.Dimension; -import java.awt.Frame; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.Insets; -import java.awt.Label; -import java.awt.Toolkit; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; -import java.awt.print.PageFormat; -import java.awt.print.Printable; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.io.Reader; -import java.io.StringReader; -import java.net.SocketPermission; -import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; -import java.util.Vector; - -import net.sourceforge.jnlp.NetxPanel; - -import sun.awt.AppContext; -import sun.awt.SunToolkit; -import sun.awt.X11.XEmbeddedFrame; -import sun.misc.Ref; - - /** - * Lets us construct one using unix-style one shot behaviors - */ - - class PluginAppletViewerFactory - { - public PluginAppletViewer createAppletViewer(int identifier, - long handle, int x, int y, - URL doc, Hashtable atts) { - PluginAppletViewer pluginappletviewer = new PluginAppletViewer(identifier, handle, x, y, doc, atts, System.out, this); - return pluginappletviewer; - } - - public boolean isStandalone() - { - return false; - } - } - - 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"; - - /** - * The panel in which the applet is being displayed. - */ - AppletViewerPanel panel; - - /** - * The status line. - */ - Label label; - - /** - * output status messages to this stream - */ - - PrintStream statusMsgStream; - - /** - * For cloning - */ - PluginAppletViewerFactory factory; - - int identifier; - - private static HashMap<Integer, PluginParseRequest> requests = new HashMap(); - - // Instance identifier -> PluginAppletViewer object. - private static HashMap<Integer, PluginAppletViewer> applets = new HashMap(); - - private static PluginStreamHandler streamhandler; - - private static PluginCallRequestFactory requestFactory; - - /** - * Null constructor to allow instantiation via newInstance() - */ - public PluginAppletViewer() { - } - - /** - * Create the applet viewer - */ - public PluginAppletViewer(int identifier, long handle, int x, int y, final URL doc, - final Hashtable atts, PrintStream statusMsgStream, - PluginAppletViewerFactory factory) { - super(handle, true); - this.factory = factory; - this.statusMsgStream = statusMsgStream; - this.identifier = identifier; - // FIXME: when/where do we remove this? - PluginDebug.debug ("PARSING: PUTTING " + identifier + " " + this); - applets.put(identifier, this); - - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - try { - panel = new NetxPanel(doc, atts); - AppletViewerPanel.debug("Using NetX panel"); - } catch (Exception ex) { - AppletViewerPanel.debug("Unable to start NetX applet - defaulting to Sun applet", ex); - panel = new AppletViewerPanel(doc, atts); - } - return null; - } - }); - - add("Center", panel); - panel.init(); - appletPanels.addElement(panel); - - pack(); - setVisible(true); - - WindowListener windowEventListener = new WindowAdapter() { - - public void windowClosing(WindowEvent evt) { - appletClose(); - } - - public void windowIconified(WindowEvent evt) { - appletStop(); - } - - public void windowDeiconified(WindowEvent evt) { - appletStart(); - } - }; - - class AppletEventListener implements AppletListener - { - final Frame frame; - - public AppletEventListener(Frame frame) - { - this.frame = frame; - } - - public void appletStateChanged(AppletEvent evt) - { - AppletPanel src = (AppletPanel)evt.getSource(); - - switch (evt.getID()) { - case AppletPanel.APPLET_RESIZE: { - if(src != null) { - resize(preferredSize()); - validate(); - } - break; - } - case AppletPanel.APPLET_LOADING_COMPLETED: { - Applet a = src.getApplet(); // sun.applet.AppletPanel - - // Fixed #4754451: Applet can have methods running on main - // thread event queue. - // - // The cause of this bug is that the frame of the applet - // is created in main thread group. Thus, when certain - // AWT/Swing events are generated, the events will be - // dispatched through the wrong event dispatch thread. - // - // To fix this, we rearrange the AppContext with the frame, - // so the proper event queue will be looked up. - // - // Swing also maintains a Frame list for the AppContext, - // so we will have to rearrange it as well. - // - if (a != null) - AppletPanel.changeFrameAppContext(frame, SunToolkit.targetToAppContext(a)); - else - AppletPanel.changeFrameAppContext(frame, AppContext.getAppContext()); - - break; - } - } - } - }; - - addWindowListener(windowEventListener); - panel.addAppletListener(new AppletEventListener(this)); - - // Start the applet - showStatus(amh.getMessage("status.start")); - initEventQueue(); - - try { - write("initialized"); - } catch (IOException ioe) { - ioe.printStackTrace(); - } - - // Wait for a maximum of 10 seconds for the panel to initialize - // (happens in a separate thread) - Applet a; - int maxSleepTime = 10000; - int sleepTime = 0; - while ((a = panel.getApplet()) == null && sleepTime < maxSleepTime) { - try { - Thread.sleep(100); - sleepTime += 100; - PluginDebug.debug("Waiting for applet to initialize... "); - } catch (InterruptedException ie) { - ie.printStackTrace(); - } - } - - PluginDebug.debug("Applet initialized"); - - // Applet initialized. Find out it's classloader and add it to the list - AppletSecurityContextManager.getSecurityContext(0).addClassLoader(Integer.toString(identifier), a.getClass().getClassLoader()); - - } - - public static void setStreamhandler(PluginStreamHandler sh) { - streamhandler = sh; - } - - public static void setPluginCallRequestFactory(PluginCallRequestFactory rf) { - 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("tag")) { - - // tag and handle must both be set before parsing, so we need - // synchronization here, as the setting of these variables - // may happen in independent threads - - synchronized(requests) { - PluginParseRequest request = requests.get(identifier); - if (request == null) { - request = new PluginParseRequest(); - requests.put(identifier, request); - } - int index = message.indexOf(' ', "tag".length() + 1); - request.documentbase = - message.substring("tag".length() + 1, index); - request.tag = message.substring(index + 1); - PluginDebug.debug ("REQUEST TAG: " + request.tag + " " + - Thread.currentThread()); - - if (request.handle != 0) { - PluginDebug.debug ("REQUEST TAG, PARSING " + - Thread.currentThread()); - PluginAppletViewer.parse - (identifier, request.handle, - new StringReader(request.tag), - new URL(request.documentbase)); - requests.remove(identifier); - } else { - PluginDebug.debug ("REQUEST HANDLE NOT SET: " + request.handle + ". BYPASSING"); - } - } - } else if (message.startsWith("handle")) { - synchronized(requests) { - PluginParseRequest request = requests.get(identifier); - if (request == null) { - request = new PluginParseRequest(); - requests.put(identifier, request); - } - request.handle = Long.parseLong - (message.substring("handle".length() + 1)); - PluginDebug.debug ("REQUEST HANDLE: " + request.handle); - if (request.tag != null) { - PluginDebug.debug ("REQUEST HANDLE, PARSING " + - Thread.currentThread()); - PluginAppletViewer.parse - (identifier, request.handle, - new StringReader(request.tag), - new URL(request.documentbase)); - requests.remove(identifier); - PluginDebug.debug ("REQUEST HANDLE, DONE PARSING " + - Thread.currentThread()); - } else { - PluginDebug.debug ("REQUEST TAG NOT SET: " + request.tag + ". BYPASSING"); - } - } - } else { - PluginDebug.debug ("HANDLING MESSAGE " + message + " instance " + identifier + " " + Thread.currentThread()); - applets.get(identifier).handleMessage(reference, message); - } - } catch (Exception e) { - throw new RuntimeException("Failed to handle message: " + message + " " + - Thread.currentThread(), e); - } - } - - public void handleMessage(int reference, String message) - { - if (message.startsWith("width")) { - int width = - Integer.parseInt(message.substring("width".length() + 1)); - //panel.setAppletSizeIfNeeded(width, -1); - setSize(width, getHeight()); - } else if (message.startsWith("height")) { - int height = - Integer.parseInt(message.substring("height".length() + 1)); - //panel.setAppletSizeIfNeeded(-1, height); - setSize(getWidth(), height); - } else if (message.startsWith("destroy")) { - dispose(); - } else if (message.startsWith("GetJavaObject")) { - // FIXME: how do we determine what security context this - // object should belong to? - Object o; - - // Wait for a maximum of 10 seconds for the panel to initialize - // (happens in a separate thread) - int maxSleepTime = 10000; - int sleepTime = 0; - while ((o = panel.getApplet()) == null && sleepTime < maxSleepTime) { - try { - Thread.sleep(100); - sleepTime += 100; - PluginDebug.debug("Waiting for applet to initialize..."); - } catch (InterruptedException ie) { - ie.printStackTrace(); - } - } - - System.err.println ("Looking for object " + o + " panel is " + panel.getClass()); - AppletSecurityContextManager.getSecurityContext(0).store(o); - System.err.println ("WRITING 1: " + "context 0 reference " + reference + " GetJavaObject " - + AppletSecurityContextManager.getSecurityContext(0).getIdentifier(o)); - streamhandler.write("context 0 reference " + reference + " GetJavaObject " - + AppletSecurityContextManager.getSecurityContext(0).getIdentifier(o)); - System.err.println ("WRITING 1 DONE"); - } - } - - /** - * Send the initial set of events to the appletviewer event queue. - * On start-up the current behaviour is to load the applet and call - * Applet.init() and Applet.start(). - */ - private void initEventQueue() { - // appletviewer.send.event is an undocumented and unsupported system - // property which is used exclusively for testing purposes. - PrivilegedAction pa = new PrivilegedAction() { - public Object run() { - return System.getProperty("appletviewer.send.event"); - } - }; - String eventList = (String) 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++) { - System.out.println("Adding event to queue: " + events[i]); - if (events[i].equals("dispose")) - panel.sendEvent(AppletPanel.APPLET_DISPOSE); - else if (events[i].equals("load")) - panel.sendEvent(AppletPanel.APPLET_LOAD); - else if (events[i].equals("init")) - panel.sendEvent(AppletPanel.APPLET_INIT); - else if (events[i].equals("start")) - panel.sendEvent(AppletPanel.APPLET_START); - else if (events[i].equals("stop")) - panel.sendEvent(AppletPanel.APPLET_STOP); - else if (events[i].equals("destroy")) - panel.sendEvent(AppletPanel.APPLET_DESTROY); - else if (events[i].equals("quit")) - panel.sendEvent(AppletPanel.APPLET_QUIT); - else if (events[i].equals("error")) - panel.sendEvent(AppletPanel.APPLET_ERROR); - else - // non-fatal error if we get an unrecognized event - System.out.println("Unrecognized event name: " + events[i]); - } - - while (!panel.emptyEventQueue()) ; - appletSystemExit(); - } - } - - /** - * Split a string based on the presence of a specified separator. Returns - * an array of arbitrary length. The end of each element in the array is - * indicated by the separator of the end of the string. If there is a - * separator immediately before the end of the string, the final element - * will be empty. None of the strings will contain the separator. Useful - * when separating strings such as "foo/bar/bas" using separator "/". - * - * @param sep The separator. - * @param s The string to split. - * @return An array of strings. Each string in the array is determined - * by the location of the provided sep in the original string, - * s. Whitespace not stripped. - */ - private String [] splitSeparator(String sep, String s) { - Vector v = new Vector(); - int tokenStart = 0; - int tokenEnd = 0; - - while ((tokenEnd = s.indexOf(sep, tokenStart)) != -1) { - v.addElement(s.substring(tokenStart, tokenEnd)); - tokenStart = tokenEnd+1; - } - // Add the final element. - v.addElement(s.substring(tokenStart)); - - String [] retVal = new String[v.size()]; - v.copyInto(retVal); - return retVal; - } - - /* - * Methods for java.applet.AppletContext - */ - - private static Map audioClips = new HashMap(); - - /** - * Get an audio clip. - */ - public AudioClip getAudioClip(URL url) { - checkConnect(url); - synchronized (audioClips) { - AudioClip clip = (AudioClip)audioClips.get(url); - if (clip == null) { - audioClips.put(url, clip = new AppletAudioClip(url)); - } - return clip; - } - } - - private static Map imageRefs = new HashMap(); - - /** - * Get an image. - */ - public Image getImage(URL url) { - return getCachedImage(url); - } - - static Image getCachedImage(URL url) { - // System.getSecurityManager().checkConnection(url.getHost(), url.getPort()); - return (Image)getCachedImageRef(url).get(); - } - - /** - * Get an image ref. - */ - static Ref getCachedImageRef(URL url) { - synchronized (imageRefs) { - AppletImageRef ref = (AppletImageRef)imageRefs.get(url); - if (ref == null) { - ref = new AppletImageRef(url); - imageRefs.put(url, ref); - } - return ref; - } - } - - /** - * Flush the image cache. - */ - static void flushImageCache() { - imageRefs.clear(); - } - - static Vector appletPanels = new Vector(); - - /** - * Get an applet by name. - */ - public Applet getApplet(String name) { - AppletSecurity security = (AppletSecurity)System.getSecurityManager(); - name = name.toLowerCase(); - SocketPermission panelSp = - new SocketPermission(panel.getCodeBase().getHost(), "connect"); - for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) { - AppletPanel p = (AppletPanel)e.nextElement(); - String param = p.getParameter("name"); - if (param != null) { - param = param.toLowerCase(); - } - if (name.equals(param) && - p.getDocumentBase().equals(panel.getDocumentBase())) { - - SocketPermission sp = - new SocketPermission(p.getCodeBase().getHost(), "connect"); - - if (panelSp.implies(sp)) { - return p.applet; - } - } - } - return null; - } - - /** - * Return an enumeration of all the accessible - * applets on this page. - */ - public Enumeration getApplets() { - AppletSecurity security = (AppletSecurity)System.getSecurityManager(); - Vector v = new Vector(); - SocketPermission panelSp = - new SocketPermission(panel.getCodeBase().getHost(), "connect"); - - for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) { - AppletPanel p = (AppletPanel)e.nextElement(); - if (p.getDocumentBase().equals(panel.getDocumentBase())) { - - SocketPermission sp = - new SocketPermission(p.getCodeBase().getHost(), "connect"); - if (panelSp.implies(sp)) { - v.addElement(p.applet); - } - } - } - return v.elements(); - } - - /** - * Ignore. - */ - 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 " + url + " " + 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 - 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. - } - } - - public int getWindow() { - System.out.println ("STARTING getWindow"); - PluginCallRequest request = requestFactory.getPluginCallRequest("window", - "instance " + identifier + " " + "GetWindow", - "JavaScriptGetWindow"); - System.out.println ("STARTING postCallRequest"); - streamhandler.postCallRequest(request); - System.out.println ("STARTING postCallRequest done"); - streamhandler.write(request.getMessage()); - try { - System.out.println ("wait request 1"); - synchronized(request) { - System.out.println ("wait request 2"); - while ((Integer) request.getObject() == 0) - request.wait(); - System.out.println ("wait request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", - e); - } - - System.out.println ("STARTING getWindow DONE"); - return (Integer) request.getObject(); - } - - // FIXME: make private, access via reflection. - public static Object getMember(int internal, String name) - { - AppletSecurityContextManager.getSecurityContext(0).store(name); - int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("member", - "instance " + 0 + " GetMember " + internal + " " + nameID, - "JavaScriptGetMember"); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - System.err.println ("wait getMEM request 1"); - synchronized(request) { - System.err.println ("wait getMEM request 2"); - while (request.isDone() == false) - request.wait(); - System.err.println ("wait getMEM request 3 GOT: " + request.getObject().getClass()); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", - e); - } - System.err.println (" getMember DONE"); - return request.getObject(); - } - - public static void setMember(int internal, String name, Object value) { - AppletSecurityContextManager.getSecurityContext(0).store(name); - int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); - AppletSecurityContextManager.getSecurityContext(0).store(value); - int valueID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value); - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("void", - "instance " + 0 + " SetMember " + internal + " " + nameID + " " + valueID, - "JavaScriptSetMember"); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - System.out.println ("wait setMem request: " + request.getMessage()); - System.out.println ("wait setMem request 1"); - synchronized(request) { - System.out.println ("wait setMem request 2"); - while (request.isDone() == false) - request.wait(); - System.out.println ("wait setMem request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", - e); - } - System.out.println (" setMember DONE"); - } - - // FIXME: handle long index as well. - public static void setSlot(int internal, int index, Object value) { - AppletSecurityContextManager.getSecurityContext(0).store(value); - int valueID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value); - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("void", - "instance " + 0 + " SetSlot " + internal + " " + index + " " + valueID, - "JavaScriptSetSlot"); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - System.out.println ("wait setSlot request 1"); - synchronized(request) { - System.out.println ("wait setSlot request 2"); - while (request.isDone() == false) - request.wait(); - System.out.println ("wait setSlot request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", - e); - } - System.out.println (" setSlot DONE"); - } - - public static Object getSlot(int internal, int index) - { - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("member", - "instance " + 0 + " GetSlot " + internal + " " + index, - "JavaScriptGetSlot"); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - System.out.println ("wait getSlot request 1"); - synchronized(request) { - System.out.println ("wait getSlot request 2"); - while (request.isDone() == false) - request.wait(); - System.out.println ("wait getSlot request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", - e); - } - System.out.println (" getSlot DONE"); - return request.getObject(); - } - - public static Object eval(int internal, String s) - { - AppletSecurityContextManager.getSecurityContext(0).store(s); - int stringID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(s); - // Prefix with dummy instance for convenience. - // FIXME: rename GetMemberPluginCallRequest ObjectPluginCallRequest. - PluginCallRequest request = requestFactory.getPluginCallRequest("member", - "instance " + 0 + " Eval " + internal + " " + stringID, - "JavaScriptEval"); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - System.out.println ("wait eval request 1"); - synchronized(request) { - System.out.println ("wait eval request 2"); - while (request.isDone() == false) - request.wait(); - System.out.println ("wait eval request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", - e); - } - System.out.println (" getSlot DONE"); - return request.getObject(); - } - - public static void removeMember (int internal, String name) { - AppletSecurityContextManager.getSecurityContext(0).store(name); - int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("void", - "instance " + 0 + " RemoveMember " + internal + " " + nameID, - "JavaScriptRemoveMember"); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - System.out.println ("wait removeMember request 1"); - synchronized(request) { - System.out.println ("wait removeMember request 2"); - while (request.isDone() == false) - request.wait(); - System.out.println ("wait removeMember request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", - e); - } - System.out.println (" RemoveMember DONE"); - } - - public static Object call(int 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); - AppletSecurityContextManager.getSecurityContext(0).store(args); - int argsID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(args); - - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("member", - "instance " + 0 + " Call " + internal + " " + nameID + " " + argsID, - "JavaScriptCall"); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - System.out.println ("wait call request 1"); - synchronized(request) { - System.out.println ("wait call request 2"); - while (request.isDone() == false) - request.wait(); - System.out.println ("wait call request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", - e); - } - System.out.println (" Call DONE"); - return request.getObject(); - } - - public static void JavaScriptFinalize(int internal) - { - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("void", - "instance " + 0 + " Finalize " + internal, - "JavaScriptFinalize"); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - System.out.println ("wait finalize request 1"); - synchronized(request) { - System.out.println ("wait finalize request 2"); - while (request.isDone() == false) - request.wait(); - System.out.println ("wait finalize request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", - e); - } - System.out.println (" finalize DONE"); - } - - public static String javascriptToString(int internal) - { - // Prefix with dummy instance for convenience. - PluginCallRequest request = requestFactory.getPluginCallRequest("member", - "instance " + 0 + " ToString " + internal, - "JavaScriptToString"); - streamhandler.postCallRequest(request); - streamhandler.write(request.getMessage()); - try { - System.out.println ("wait ToString request 1"); - synchronized(request) { - System.out.println ("wait ToString request 2"); - while (request.isDone() == false) - request.wait(); - System.out.println ("wait ToString request 3"); - } - } catch (InterruptedException e) { - throw new RuntimeException("Interrupted waiting for call request.", - e); - } - System.out.println (" ToString DONE"); - return (String) request.getObject(); - } - - // FIXME: make this private and access it from JSObject using - // reflection. - private void write(String message) throws IOException { - System.err.println ("WRITING 2: " + "instance " + identifier + " " + message); - streamhandler.write("instance " + identifier + " " + message); - System.err.println ("WRITING 2 DONE"); - } - - public void setStream(String key, InputStream stream)throws IOException{ - // We do nothing. - } - - public InputStream getStream(String key){ - // We do nothing. - return null; - } - - public Iterator getStreamKeys(){ - // We do nothing. - return null; - } - - /** - * System parameters. - */ - static Hashtable systemParam = new Hashtable(); - - static { - systemParam.put("codebase", "codebase"); - systemParam.put("code", "code"); - systemParam.put("alt", "alt"); - systemParam.put("width", "width"); - systemParam.put("height", "height"); - systemParam.put("align", "align"); - systemParam.put("vspace", "vspace"); - systemParam.put("hspace", "hspace"); - } - - /** - * Print the HTML tag. - */ - public static void printTag(PrintStream out, Hashtable atts) { - out.print("<applet"); - - String v = (String)atts.get("codebase"); - if (v != null) { - out.print(" codebase=\"" + v + "\""); - } - - v = (String)atts.get("code"); - if (v == null) { - v = "applet.class"; - } - out.print(" code=\"" + v + "\""); - v = (String)atts.get("width"); - if (v == null) { - v = "150"; - } - out.print(" width=" + v); - - v = (String)atts.get("height"); - if (v == null) { - v = "100"; - } - out.print(" height=" + v); - - v = (String)atts.get("name"); - if (v != null) { - out.print(" name=\"" + v + "\""); - } - out.println(">"); - - // A very slow sorting algorithm - int len = atts.size(); - String params[] = new String[len]; - len = 0; - for (Enumeration e = atts.keys() ; e.hasMoreElements() ;) { - String param = (String)e.nextElement(); - int i = 0; - for (; i < len ; i++) { - if (params[i].compareTo(param) >= 0) { - break; - } - } - System.arraycopy(params, i, params, i + 1, len - i); - params[i] = param; - len++; - } - - for (int i = 0 ; i < len ; i++) { - String param = params[i]; - if (systemParam.get(param) == null) { - out.println("<param name=" + param + - " value=\"" + atts.get(param) + "\">"); - } - } - out.println("</applet>"); - } - - /** - * Make sure the atrributes are uptodate. - */ - public void updateAtts() { - Dimension d = panel.size(); - Insets in = panel.insets(); - panel.atts.put("width", - new Integer(d.width - (in.left + in.right)).toString()); - panel.atts.put("height", - new Integer(d.height - (in.top + in.bottom)).toString()); - } - - /** - * Restart the applet. - */ - 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() { - public Object 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() - { - appletShutdown(p); - appletPanels.removeElement(p); - dispose(); - - if (countApplets() == 0) { - appletSystemExit(); - } - } - }).start(); - } - - /** - * Exit the program. - * Exit from the program (if not stand alone) - do no clean-up - */ - private void appletSystemExit() { - if (factory.isStandalone()) - System.exit(0); - } - - /** - * How many applets are running? - */ - - public static int countApplets() { - return appletPanels.size(); - } - - - /** - * The current character. - */ - static int c; - - /** - * Scan spaces. - */ - public static void skipSpace(Reader in) throws IOException { - while ((c >= 0) && - ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'))) { - c = in.read(); - } - } - - /** - * Scan identifier - */ - public static String scanIdentifier(Reader in) throws IOException { - StringBuffer buf = new StringBuffer(); - while (true) { - if (((c >= 'a') && (c <= 'z')) || - ((c >= 'A') && (c <= 'Z')) || - ((c >= '0') && (c <= '9')) || (c == '_')) { - buf.append((char)c); - c = in.read(); - } else { - return buf.toString(); - } - } - } - - /** - * Scan tag - */ - public static Hashtable scanTag(Reader in) throws IOException { - Hashtable atts = new Hashtable(); - skipSpace(in); - while (c >= 0 && c != '>') { - String att = scanIdentifier(in); - String val = ""; - skipSpace(in); - if (c == '=') { - int quote = -1; - c = in.read(); - skipSpace(in); - if ((c == '\'') || (c == '\"')) { - quote = c; - c = in.read(); - } - StringBuffer buf = new StringBuffer(); - while ((c > 0) && - (((quote < 0) && (c != ' ') && (c != '\t') && - (c != '\n') && (c != '\r') && (c != '>')) - || ((quote >= 0) && (c != quote)))) { - buf.append((char)c); - c = in.read(); - } - if (c == quote) { - c = in.read(); - } - skipSpace(in); - val = buf.toString(); - } - System.err.println("PUT " + att + " = '" + val + "'"); - if (! val.equals("")) { - atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val); - } - while (true) { - if ((c == '>') || (c < 0) || - ((c >= 'a') && (c <= 'z')) || - ((c >= 'A') && (c <= 'Z')) || - ((c >= '0') && (c <= '9')) || (c == '_')) - break; - c = in.read(); - } - //skipSpace(in); - } - return atts; - } - - /* values used for placement of AppletViewer's frames */ - private static int x = 0; - private static int y = 0; - private static final int XDELTA = 30; - private static final int YDELTA = XDELTA; - - static String encoding = null; - - static private Reader makeReader(InputStream is) { - if (encoding != null) { - try { - return new BufferedReader(new InputStreamReader(is, encoding)); - } catch (IOException x) { } - } - InputStreamReader r = new InputStreamReader(is); - encoding = r.getEncoding(); - return new BufferedReader(r); - } - - /** - * Scan an html file for <applet> tags - */ - public static void parse(int identifier, long handle, Reader in, URL url, String enc) - throws IOException { - encoding = enc; - parse(identifier, handle, in, url, System.out, new PluginAppletViewerFactory()); - } - - public static void parse(int identifier, long handle, Reader in, URL url) - throws IOException { - final int fIdentifier = identifier; - final long fHandle = handle; - final Reader fIn = in; - final URL fUrl = url; - PrivilegedAction pa = new PrivilegedAction() { - public Object run() { - try { - parse(fIdentifier, fHandle, fIn, fUrl, System.out, new PluginAppletViewerFactory()); - } catch (IOException ioe) { - return ioe; - } - - return null; - } - }; - - Object ret = AccessController.doPrivileged(pa); - if (ret instanceof IOException) { - throw (IOException) ret; - } - } - - public static void parse(int identifier, long handle, Reader in, URL url, - PrintStream statusMsgStream, - PluginAppletViewerFactory factory) - throws IOException - { - // <OBJECT> <EMBED> tag flags - boolean isAppletTag = false; - boolean isObjectTag = false; - boolean isEmbedTag = false; - - // warning messages - String requiresNameWarning = amh.getMessage("parse.warning.requiresname"); - String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside"); - String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode"); - String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight"); - String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth"); - String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode"); - String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight"); - String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth"); - String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode"); - String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight"); - String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth"); - String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported"); - - java.net.URLConnection conn = url.openConnection(); - /* The original URL may have been redirected - this - * sets it to whatever URL/codebase we ended up getting - */ - url = conn.getURL(); - - int ydisp = 1; - Hashtable atts = null; - - while(true) { - c = in.read(); - if (c == -1) - break; - - if (c == '<') { - c = in.read(); - if (c == '/') { - c = in.read(); - String nm = scanIdentifier(in); - if (nm.equalsIgnoreCase("applet") || - nm.equalsIgnoreCase("object") || - nm.equalsIgnoreCase("embed")) { - - // We can't test for a code tag until </OBJECT> - // because it is a parameter, not an attribute. - if(isObjectTag) { - if (atts.get("code") == null && atts.get("object") == null) { - statusMsgStream.println(objectRequiresCodeWarning); - atts = null; - } - } - - if (atts != null) { - // XXX 5/18 In general this code just simply - // shouldn't be part of parsing. It's presence - // causes things to be a little too much of a - // hack. - factory.createAppletViewer(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(in); - if (nm.equalsIgnoreCase("param")) { - Hashtable t = scanTag(in); - String att = (String)t.get("name"); - if (att == null) { - statusMsgStream.println(requiresNameWarning); - } else { - String val = (String)t.get("value"); - if (val == null) { - statusMsgStream.println(requiresNameWarning); - } else if (atts != null) { - atts.put(att.toLowerCase(), val); - } else { - statusMsgStream.println(paramOutsideWarning); - } - } - } - else if (nm.equalsIgnoreCase("applet")) { - isAppletTag = true; - atts = scanTag(in); - - // If there is a classid present, transform it to code tag - if (atts.get("code") == null && atts.get("classid") != null && - ((String) atts.get("classid")).startsWith("java:")) { - //skip "java:" - atts.put("code", ((String) atts.get("classid")).substring(5)); - } - - if (atts.get("code") == null && atts.get("object") == null) { - statusMsgStream.println(appletRequiresCodeWarning); - atts = null; - } - - if (atts.get("width") == null) { - atts.put("width", "100%"); - } - - if (atts.get("height") == null) { - atts.put("height", "100%"); - } - } - else if (nm.equalsIgnoreCase("object")) { - isObjectTag = true; - atts = scanTag(in); - - // If there is a classid present, transform it to code tag - if (atts.get("code") == null && atts.get("classid") != null && - ((String) atts.get("classid")).startsWith("java:")) { - //skip "java:" - atts.put("code", ((String) atts.get("classid")).substring(5)); - } - - // The <OBJECT> attribute codebase isn't what - // we want when not dealing with jars. If its - // defined, remove it in that case. - if(atts.get("archive") == null && atts.get("codebase") != null) { - atts.remove("codebase"); - } - - if (atts.get("width") == null) { - atts.put("width", "100%"); - } - - if (atts.get("height") == null) { - atts.put("height", "100%"); - } - } - else if (nm.equalsIgnoreCase("embed")) { - isEmbedTag = true; - atts = scanTag(in); - - // If there is a classid present, transform it to code tag - if (atts.get("code") == null && atts.get("classid") != null && - ((String) atts.get("classid")).startsWith("java:")) { - //skip "java:" - atts.put("code", ((String) atts.get("classid")).substring(5)); - } - - if (atts.get("code") == null && atts.get("object") == null) { - statusMsgStream.println(embedRequiresCodeWarning); - atts = null; - } - - if (atts.get("width") == null) { - atts.put("width", "100%"); - } - - if (atts.get("height") == null) { - atts.put("height", "100%"); - } - } - else if (nm.equalsIgnoreCase("app")) { - statusMsgStream.println(appNotLongerSupportedWarning); - Hashtable atts2 = scanTag(in); - nm = (String)atts2.get("class"); - if (nm != null) { - atts2.remove("class"); - atts2.put("code", nm + ".class"); - } - nm = (String)atts2.get("src"); - if (nm != null) { - atts2.remove("src"); - atts2.put("codebase", nm); - } - if (atts2.get("width") == null) { - atts2.put("width", "100%"); - } - if (atts2.get("height") == null) { - atts2.put("height", "100%"); - } - printTag(statusMsgStream, atts2); - statusMsgStream.println(); - } - } - } - } - in.close(); - } - - - 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()); - } - } - } - }
--- a/plugin/icedtea/java/src/main/sun/applet/PluginCallRequest.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* PluginCallRequest -- represent Java-to-JavaScript requests - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package sun.applet; - -import java.security.AccessControlContext; -import java.security.ProtectionDomain; - -// FIXME: for each type of request extend a new (anonymous?) -// PluginCallRequest. -public abstract class PluginCallRequest { - String message; - String returnString; - PluginCallRequest next; - boolean done = false; - - public PluginCallRequest(String message, String returnString) { - this.message = message; - this.returnString = returnString; - } - - public String getMessage() { - return this.message; - } - - public String getReturnString() { - return this.returnString; - } - - public boolean isDone() { - return this.done; - } - - public boolean setDone(boolean done) { - return this.done = done; - } - - public void setNext(PluginCallRequest next) { - this.next = next; - } - - public PluginCallRequest getNext() { - return this.next; - } - - public abstract void parseReturn(String message); - - public abstract boolean serviceable(String message); - - public abstract Object getObject(); -}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginCallRequestFactory.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -package sun.applet; - -public interface PluginCallRequestFactory { - - public PluginCallRequest getPluginCallRequest(String id, String message, String returnString); - -}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginClassLoader.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -package sun.applet; - -public class PluginClassLoader extends ClassLoader { - - public PluginClassLoader() { - super(); - } - - public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { - return super.loadClass(name, resolve); - } - -}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginDebug.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -package sun.applet; - -import java.io.*; - -public class PluginDebug { - - static final boolean DEBUG = true; - - public static void debug(String message) { - if (DEBUG) - System.err.println(message); - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginException.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -package sun.applet; - - -public class PluginException extends Exception { - - public PluginException (PluginStreamHandler sh, int instance, int reference, Throwable t) { - t.printStackTrace(); - this.setStackTrace(t.getStackTrace()); - - AppletSecurityContextManager.dumpStore(0); - - String message = "instance " + instance + " reference " + reference + " Error " + t.getMessage(); - sh.write(message); - } -}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginStreamHandler.java Tue Sep 23 16:33:17 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -package sun.applet; - - -public interface PluginStreamHandler { - - public void postMessage(String s); - - public void handleMessage(String message) throws PluginException; - - public void postCallRequest(PluginCallRequest request); - - public void write(String message); - - public boolean messageAvailable(); - - public String getMessage(); - - public void startProcessing(); - -} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/netscape/javascript/JSException.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,140 @@ +/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +package netscape.javascript; + +/** + * JSException is an exception which is thrown when JavaScript code + * returns an error. + */ + +public +class JSException extends RuntimeException { + public static final int EXCEPTION_TYPE_EMPTY = -1; + public static final int EXCEPTION_TYPE_VOID = 0; + public static final int EXCEPTION_TYPE_OBJECT = 1; + public static final int EXCEPTION_TYPE_FUNCTION = 2; + public static final int EXCEPTION_TYPE_STRING = 3; + public static final int EXCEPTION_TYPE_NUMBER = 4; + public static final int EXCEPTION_TYPE_BOOLEAN = 5; + public static final int EXCEPTION_TYPE_ERROR = 6; + + public String filename; + public int lineno; + public String source; + public int tokenIndex; + public int wrappedExceptionType; + public Object wrappedException; + + /** + * Constructs a JSException without a detail message. + * A detail message is a String that describes this particular exception. + * + * @deprecated Not for public use in future versions. + */ + public JSException() { + super(); + filename = "unknown"; + lineno = 0; + source = ""; + tokenIndex = 0; + wrappedExceptionType = EXCEPTION_TYPE_EMPTY; + } + + /** + * Constructs a JSException with a detail message. + * A detail message is a String that describes this particular exception. + * @param s the detail message + * + * @deprecated Not for public use in future versions. + */ + public JSException(String s) { + super(s); + filename = "unknown"; + lineno = 0; + source = ""; + tokenIndex = 0; + wrappedExceptionType = EXCEPTION_TYPE_EMPTY; + } + + /** + * Constructs a JSException with a wrapped JavaScript exception object. + * This constructor needs to be public so that Java users can throw + * exceptions to JS cleanly. + */ + public JSException(int wrappedExceptionType, Object wrappedException) { + super(); + this.wrappedExceptionType = wrappedExceptionType; + this.wrappedException = wrappedException; + } + + /** + * Constructs a JSException with a detail message and all the + * other info that usually comes with a JavaScript error. + * @param s the detail message + * + * @deprecated Not for public use in future versions. + */ + public JSException(String s, String filename, int lineno, + String source, int tokenIndex) { + super(s); + this.filename = filename; + this.lineno = lineno; + this.source = source; + this.tokenIndex = tokenIndex; + wrappedExceptionType = EXCEPTION_TYPE_EMPTY; + } + + /** + * Instance method getWrappedExceptionType returns the int mapping of the + * type of the wrappedException Object. + */ + public int getWrappedExceptionType() { + return wrappedExceptionType; + } + + /** + * Instance method getWrappedException. + */ + public Object getWrappedException() { + return wrappedException; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/netscape/javascript/JSObject.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,258 @@ +/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* more doc todo: + * threads + * gc + * + * + */ + +package netscape.javascript; + +import java.applet.Applet; +import java.io.IOException; +import sun.applet.PluginAppletViewer; + +/** + * JSObject allows Java to manipulate objects that are + * defined in JavaScript. + * Values passed from Java to JavaScript are converted as + * follows:<ul> + * <li>JSObject is converted to the original JavaScript object + * <li>Any other Java object is converted to a JavaScript wrapper, + * which can be used to access methods and fields of the java object. + * Converting this wrapper to a string will call the toString method + * on the original object, converting to a number will call the + * doubleValue method if possible and fail otherwise. Converting + * to a boolean will try to call the booleanValue method in the + * same way. + * <li>Java arrays are wrapped with a JavaScript object that understands + * array.length and array[index] + * <li>A Java boolean is converted to a JavaScript boolean + * <li>Java byte, char, short, int, long, float, and double are converted + * to JavaScript numbers + * </ul> + * Values passed from JavaScript to Java are converted as follows:<ul> + * <li>objects which are wrappers around java objects are unwrapped + * <li>other objects are wrapped with a JSObject + * <li>strings, numbers and booleans are converted to String, Double, + * and Boolean objects respectively + * </ul> + * This means that all JavaScript values show up as some kind + * of java.lang.Object in Java. In order to make much use of them, + * you will have to cast them to the appropriate subclass of Object, + * e.g. <code>(String) window.getMember("name");</code> or + * <code>(JSObject) window.getMember("document");</code>. + */ +public final class JSObject { + /* the internal object data */ + private int internal; + private long long_internal; + + /** + * initialize + */ + private static void initClass() { + System.err.println ("JSObject.initClass"); + } + + static { + System.err.println ("JSObject INITIALIZER"); + } + + /** + * it is illegal to construct a JSObject manually + */ + // FIXME: make private! + public JSObject(int jsobj_addr) { + System.err.println ("JSObject int CONSTRUCTOR"); + internal = jsobj_addr; + } + + private JSObject(long jsobj_addr) { + System.err.println ("JSObject long CONSTRUCTOR"); + long_internal = jsobj_addr; + } + + /** + * Retrieves a named member of a JavaScript object. + * Equivalent to "this.<i>name</i>" in JavaScript. + */ + public Object getMember(String name) + { + System.err.println ("JSObject.getMember " + name); + + Object o = PluginAppletViewer.getMember(internal, name); + System.out.println ("JSObject.getMember GOT " + o); + return o; + } + + + /** + * Retrieves an indexed member of a JavaScript object. + * Equivalent to "this[<i>index</i>]" in JavaScript. + */ + // public Object getMember(int index) { return getSlot(index); } + public Object getSlot(int index) + { + System.err.println ("JSObject.getSlot " + index); + + return PluginAppletViewer.getSlot(internal, index); + } + + + /** + * Sets a named member of a JavaScript object. + * Equivalent to "this.<i>name</i> = <i>value</i>" in JavaScript. + */ + public void setMember(String name, Object value) + { + System.err.println ("JSObject.setMember " + name + " " + value); + + PluginAppletViewer.setMember(internal, name, value); + } + + /** + * Sets an indexed member of a JavaScript object. + * Equivalent to "this[<i>index</i>] = <i>value</i>" in JavaScript. + */ + // public void setMember(int index, Object value) { + // setSlot(index, value); + // } + public void setSlot(int index, Object value) + { + System.err.println ("JSObject.setSlot " + index + " " + value); + + PluginAppletViewer.setSlot(internal, index, value); + } + + + // TODO: toString, finalize. + + /** + * Removes a named member of a JavaScript object. + */ + public void removeMember(String name) + { + System.err.println ("JSObject.removeMember " + name); + + PluginAppletViewer.removeMember(internal, name); + } + + + /** + * Calls a JavaScript method. + * Equivalent to "this.<i>methodName</i>(<i>args</i>[0], <i>args</i>[1], ...)" in JavaScript. + */ + public Object call(String methodName, Object args[]) + { + System.err.print ("JSObject.call " + methodName); + for (int i = 0; i < args.length; i++) + System.err.print (" " + args[i]); + System.err.println(""); + return PluginAppletViewer.call(internal, methodName, args); + } + + + /** + * Evaluates a JavaScript expression. The expression is a string + * of JavaScript source code which will be evaluated in the context + * given by "this". + */ + public Object eval(String s) + { + System.err.println("JSObject.eval " + s); + return PluginAppletViewer.eval(internal, s); + } + + + /** + * Converts a JSObject to a String. + */ + public String toString() + { + System.err.println("JSObject.toString"); + return PluginAppletViewer.javascriptToString(internal); + } + + + // should use some sort of identifier rather than String + // is "property" the right word? + // native String[] listProperties(); + + + /** + * get a JSObject for the window containing the given applet + */ + public static JSObject getWindow(Applet applet) + { + System.err.println("JSObject.getWindow"); + // FIXME: handle long case as well. + int internal = 0; + internal = ((PluginAppletViewer) + applet.getAppletContext()).getWindow(); + System.out.println ("GOT IT: " + internal); + return new JSObject(internal); + } + + + /** + * Finalization decrements the reference count on the corresponding + * JavaScript object. + */ + protected void finalize() + { + System.err.println("JSObject.finalize "); + PluginAppletViewer.JavaScriptFinalize(internal); + } + + + /** + * Override java.lang.Object.equals() because identity is not preserved + * with instances of JSObject. + */ + public boolean equals(Object obj) + { + System.err.println("JSObject.equals " + obj); + + return false; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/netscape/javascript/JSProxy.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,58 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * The JSProxy interface allows applets and plugins to + * share javascript contexts. + */ + +package netscape.javascript; +import java.applet.Applet; + +public interface JSProxy { + Object getMember(JSObject jso, String name); + Object getSlot(JSObject jso, int index); + void setMember(JSObject jso, String name, Object value); + void setSlot(JSObject jso, int index, Object value); + void removeMember(JSObject jso, String name); + Object call(JSObject jso, String methodName, Object args[]); + Object eval(JSObject jso, String s); + String toString(JSObject jso); + JSObject getWindow(Applet applet); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/netscape/javascript/JSRunnable.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,70 @@ +/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +package netscape.javascript; + +/** + * Runs a JavaScript object with a run() method in a separate thread. + */ +public class JSRunnable implements Runnable { + private JSObject runnable; + + public JSRunnable(JSObject runnable) { + this.runnable = runnable; + synchronized(this) { + new Thread(this).start(); + try { + this.wait(); + } catch (InterruptedException ie) { + } + } + } + + public void run() { + try { + runnable.call("run", null); + synchronized(this) { + notifyAll(); + } + } catch (Throwable t) { + System.err.println(t); + t.printStackTrace(System.err); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/netscape/javascript/JSUtil.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,59 @@ +/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +/* ** */ + +package netscape.javascript; +import java.io.*; + +public class JSUtil { + + /* Return the stack trace of an exception or error as a String */ + public static String getStackTrace(Throwable t) { + ByteArrayOutputStream captureStream; + PrintWriter p; + + captureStream = new ByteArrayOutputStream(); + p = new PrintWriter(captureStream); + + t.printStackTrace(p); + p.flush(); + + return captureStream.toString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,78 @@ +/* GetMemberPluginCallRequest -- represent Java-to-JavaScript requests + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package org.classpath.icedtea.plugin; + +import sun.applet.AppletSecurityContextManager; +import sun.applet.PluginCallRequest; + +public class GetMemberPluginCallRequest extends PluginCallRequest { + Object object = null; + + public GetMemberPluginCallRequest(String message, String returnString) { + super(message, returnString); + System.out.println ("GetMEMBerPLUGINCAlL " + message + " " + returnString); + } + + public void parseReturn(String message) { + System.out.println ("GetMEMBerparseReturn GOT: " + message); + String[] args = message.split(" "); + // FIXME: add thread ID to messages to support multiple + // threads using the netscape.javascript package. + object = AppletSecurityContextManager.getSecurityContext(0).getObject(Integer.parseInt(args[1])); + setDone(true); + } + + /** + * Returns whether the given message is serviceable by this object + * + * @param message The message to service + * @return boolean indicating if message is serviceable + */ + public boolean serviceable(String message) { + return message.contains("JavaScriptCall") || + message.contains("JavaScriptEval") || + message.contains("JavaScriptGetMember") || + message.contains("JavaScriptGetSlot") || + message.contains("JavaScriptToString"); + } + + public Object getObject() { + return this.object; + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,76 @@ +/* GetWindowPluginCallRequest -- represent Java-to-JavaScript requests + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package org.classpath.icedtea.plugin; + +import java.security.AccessControlContext; +import java.security.ProtectionDomain; + +import sun.applet.PluginCallRequest; + + +public class GetWindowPluginCallRequest extends PluginCallRequest { + // FIXME: look into int vs long JavaScript internal values. + int internal; + + public GetWindowPluginCallRequest(String message, String returnString) { + super(message, returnString); + } + + public void parseReturn(String message) { + System.out.println ("GetWINDOWparseReturn GOT: " + message); + String[] args = message.split(" "); + // FIXME: add thread ID to messages to support multiple + // threads using the netscape.javascript package. + internal = Integer.parseInt(args[1]); + setDone(true); + } + + /** + * Returns whether the given message is serviceable by this object + * + * @param message The message to service + * @return boolean indicating if message is serviceable + */ + public boolean serviceable(String message) { + return message.contains("JavaScriptGetWindow"); + } + + public Integer getObject() { + return this.internal; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,855 @@ +/* PluginAppletSecurityContext -- execute plugin JNI messages + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package org.classpath.icedtea.plugin; + +import java.io.FilePermission; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.StringTokenizer; + +import sun.applet.AppletSecurityContext; +import sun.applet.PluginDebug; +import sun.applet.PluginException; + + +class Signature { + private String signature; + private int currentIndex; + private List<Class> typeList; + private static final char ARRAY = '['; + private static final char OBJECT = 'L'; + private static final char SIGNATURE_ENDCLASS = ';'; + private static final char SIGNATURE_FUNC = '('; + private static final char SIGNATURE_ENDFUNC = ')'; + private static final char VOID = 'V'; + private static final char BOOLEAN = 'Z'; + private static final char BYTE = 'B'; + private static final char CHARACTER = 'C'; + private static final char SHORT = 'S'; + private static final char INTEGER = 'I'; + private static final char LONG = 'J'; + private static final char FLOAT = 'F'; + private static final char DOUBLE = 'D'; + + private String nextTypeName() { + char key = signature.charAt(currentIndex++); + + switch (key) { + case ARRAY: + return nextTypeName() + "[]"; + + case OBJECT: + int endClass = signature.indexOf(SIGNATURE_ENDCLASS, currentIndex); + String retVal = signature.substring(currentIndex, endClass); + retVal = retVal.replace('/', '.'); + currentIndex = endClass + 1; + return retVal; + + // FIXME: generated bytecode with classes named after + // primitives will not work in this scheme -- those + // classes will be incorrectly treated as primitive + // types. + case VOID: + return "void"; + case BOOLEAN: + return "boolean"; + case BYTE: + return "byte"; + case CHARACTER: + return "char"; + case SHORT: + return "short"; + case INTEGER: + return "int"; + case LONG: + return "long"; + case FLOAT: + return "float"; + case DOUBLE: + return "double"; + + case SIGNATURE_ENDFUNC: + case SIGNATURE_FUNC: + return nextTypeName(); + + default: + throw new IllegalArgumentException( + "Invalid JNI signature character '" + key + "'"); + } + } + + public Signature(String signature, String src) { + this.signature = signature; + currentIndex = 0; + typeList = new ArrayList<Class>(10); + + String elem; + while (currentIndex < signature.length()) { + elem = nextTypeName(); + // System.out.println ("NEXT TYPE: " + elem); + Class primitive = primitiveNameToType(elem); + if (primitive != null) + typeList.add(primitive); + else { + // System.out.println ("HERE1"); + int dimsize = 0; + int n = elem.indexOf('['); + if (n != -1) { + // System.out.println ("HERE2"); + String arrayType = elem.substring(0, n); + dimsize++; + n = elem.indexOf('[', n + 1); + // System.out.println ("HERE2.5"); + while (n != -1) { + dimsize++; + n = elem.indexOf('[', n + 1); + // System.out.println ("HERE2.8"); + } + int[] dims = new int[dimsize]; + primitive = primitiveNameToType(arrayType); + // System.out.println ("HERE3"); + if (primitive != null) { + typeList.add(Array.newInstance(primitive, dims) + .getClass()); + // System.out.println ("HERE4"); + } else + typeList.add(Array.newInstance( + getClass(arrayType, src), dims).getClass()); + } else { + typeList.add(getClass(elem, src)); + } + } + } + if (typeList.size() == 0) { + throw new IllegalArgumentException("Invalid JNI signature '" + + signature + "'"); + } + } + + public static Class getClass(String name, String src) { + + Class c = null; + + try { + c = Class.forName(name); + } catch (ClassNotFoundException cnfe) { + + StringTokenizer st = new StringTokenizer(src, ","); + + while (st.hasMoreTokens()) { + + String tok = st.nextToken(); + System.err.println("Searching for " + name + " at key " + tok); + + try { + c = PluginAppletSecurityContext.classLoaders.get(tok).loadClass(name); + } catch (ClassNotFoundException e) { + // do nothing .. thrown below + } + + if (c != null) + break; + } + } + + if (c == null) { + throw (new RuntimeException(new ClassNotFoundException("Unable to find class " + name))); + } + + return c; + } + + public static Class primitiveNameToType(String name) { + if (name.equals("void")) + return Void.TYPE; + else if (name.equals("boolean")) + return Boolean.TYPE; + else if (name.equals("byte")) + return Byte.TYPE; + else if (name.equals("char")) + return Character.TYPE; + else if (name.equals("short")) + return Short.TYPE; + else if (name.equals("int")) + return Integer.TYPE; + else if (name.equals("long")) + return Long.TYPE; + else if (name.equals("float")) + return Float.TYPE; + else if (name.equals("double")) + return Double.TYPE; + else + return null; + } + + public Class[] getClassArray() { + return typeList.subList(0, typeList.size() - 1).toArray(new Class[] {}); + } +} + +public class PluginAppletSecurityContext extends AppletSecurityContext { + + public static HashMap<String, ClassLoader> classLoaders = new HashMap<String, ClassLoader>(); + + // FIXME: make private + public PluginObjectStore store = new PluginObjectStore(); + private Throwable throwable = null; + private ClassLoader liveconnectLoader = ClassLoader.getSystemClassLoader(); + int identifier = 0; + + public PluginAppletSecurityContext(int identifier) { + this.identifier = identifier; + } + + private static <V> V parseCall(String s, String src, Class<V> c) { + if (c == Integer.class) + return (V) new Integer(s); + else if (c == String.class) + return (V) new String(s); + else if (c == Signature.class) + return (V) new Signature(s, src); + else + throw new RuntimeException("Unexpected call value."); + } + + private Object parseArgs(String s, Class c) { + if (c == Boolean.TYPE || c == Boolean.class) + return new Boolean(s); + else if (c == Byte.TYPE || c == Byte.class) + return new Byte(s); + else if (c == Character.TYPE || c == Character.class) { + String[] bytes = s.split("_"); + int low = Integer.parseInt(bytes[0]); + int high = Integer.parseInt(bytes[1]); + int full = ((high << 8) & 0x0ff00) | (low & 0x0ff); + return new Character((char) full); + } else if (c == Short.TYPE || c == Short.class) + return new Short(s); + else if (c == Integer.TYPE || c == Integer.class) + return new Integer(s); + else if (c == Long.TYPE || c == Long.class) + return new Long(s); + else if (c == Float.TYPE || c == Float.class) + return new Float(s); + else if (c == Double.TYPE || c == Double.class) + return new Double(s); + else + return store.getObject(new Integer(s)); + } + + public void addClassLoader(String id, ClassLoader cl) { + this.classLoaders.put(id, cl); + } + + public void handleMessage(String src, int reference, String message) { + + try { + if (message.startsWith("FindClass")) { + ClassLoader cl = null; + Class c = null; + cl = liveconnectLoader; + String className = message.substring("FindClass".length() + 1) + .replace('/', '.'); + + try { + c = cl.loadClass(className); + store.reference(c); + write(reference, "FindClass " + store.getIdentifier(c)); + } catch (ClassNotFoundException cnfe) { + write(reference, "FindClass 0"); + } + + } else if (message.startsWith("GetStaticMethodID") + || message.startsWith("GetMethodID")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + String methodName = parseCall(args[2], src, String.class); + Signature signature = parseCall(args[3], src, Signature.class); + Object[] a = signature.getClassArray(); + + Class c = (Class) store.getObject(classID); + Method m = null; + Constructor cs = null; + Object o = null; + if (methodName.equals("<init>") + || methodName.equals("<clinit>")) { + o = cs = c.getConstructor(signature.getClassArray()); + store.reference(cs); + } else { + o = m = c.getMethod(methodName, signature.getClassArray()); + store.reference(m); + } + PluginDebug.debug(o + " has id " + store.getIdentifier(o)); + write(reference, args[0] + " " + store.getIdentifier(o)); + } else if (message.startsWith("GetStaticFieldID") + || message.startsWith("GetFieldID")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + String fieldName = parseCall(args[2], src, String.class); + Signature signature = parseCall(args[3], src, Signature.class); + + Class c = (Class) store.getObject(classID); + Field f = null; + f = c.getField(fieldName); + + store.reference(f); + + write(reference, "GetStaticFieldID " + store.getIdentifier(f)); + } else if (message.startsWith("GetStaticField")) { + String[] args = message.split(" "); + String type = parseCall(args[1], src, String.class); + Integer classID = parseCall(args[1], src, Integer.class); + Integer fieldID = parseCall(args[2], src, Integer.class); + + Class c = (Class) store.getObject(classID); + Field f = (Field) store.getObject(fieldID); + + Object ret = null; + ret = f.get(c); + + // System.out.println ("FIELD VALUE: " + ret); + if (ret == null) { + write(reference, "GetStaticField 0"); + } else if (f.getType() == Boolean.TYPE + || f.getType() == Byte.TYPE + || f.getType() == Character.TYPE + || f.getType() == Short.TYPE + || f.getType() == Integer.TYPE + || f.getType() == Long.TYPE + || f.getType() == Float.TYPE + || f.getType() == Double.TYPE) { + write(reference, "GetStaticField " + ret); + } else { + // Track returned object. + store.reference(ret); + write(reference, "GetStaticField " + + store.getIdentifier(ret)); + } + } else if (message.startsWith("SetStaticField")) { + String[] args = message.split(" "); + String type = parseCall(args[1], src, String.class); + Integer classID = parseCall(args[2], src, Integer.class); + Integer fieldID = parseCall(args[3], src, Integer.class); + + Object value = null; + if (Signature.primitiveNameToType(type) != null) { + value = parseArgs(args[4], Signature + .primitiveNameToType(type)); + // System.out.println ("HERE1: " + value); + } else { + value = parseArgs(args[3], Object.class); + // System.out.println ("HERE2: " + value); + } + + Class c = (Class) store.getObject(classID); + Field f = (Field) store.getObject(fieldID); + + f.set(c, value); + + write(reference, "SetStaticField"); + } else if (message.startsWith("SetField")) { + String[] args = message.split(" "); + String type = parseCall(args[1], src, String.class); + Integer objectID = parseCall(args[2], src, Integer.class); + Integer fieldID = parseCall(args[3], src, Integer.class); + + Object value = null; + if (Signature.primitiveNameToType(type) != null) { + value = parseArgs(args[4], Signature + .primitiveNameToType(type)); + // System.out.println ("HERE1: " + value); + } else { + value = parseArgs(args[3], Object.class); + // System.out.println ("HERE2: " + value); + } + + Object o = (Object) store.getObject(objectID); + Field f = (Field) store.getObject(fieldID); + + f.set(o, value); + + write(reference, "SetField"); + } else if (message.startsWith("GetObjectArrayElement")) { + String[] args = message.split(" "); + Integer arrayID = parseCall(args[1], src, Integer.class); + Integer index = parseCall(args[2], src, Integer.class); + + Object[] o = (Object[]) store.getObject(arrayID); + Object ret = null; + + ret = o[index]; + + // Track returned object. + store.reference(ret); + // System.out.println ("array element: " + index + " " + ret); + write(reference, "GetObjectArrayElement " + + store.getIdentifier(ret)); + } else if (message.startsWith("SetObjectArrayElement")) { + String[] args = message.split(" "); + Integer arrayID = parseCall(args[1], src, Integer.class); + Integer index = parseCall(args[2], src, Integer.class); + Integer objectID = parseCall(args[3], src, Integer.class); + + Object[] o = (Object[]) store.getObject(arrayID); + Object toSet = (Object) store.getObject(objectID); + + o[index] = toSet; + + write(reference, "SetObjectArrayElement"); + } else if (message.startsWith("GetArrayLength")) { + String[] args = message.split(" "); + Integer arrayID = parseCall(args[1], src, Integer.class); + + System.out.println("ARRAYID: " + arrayID); + Object o = (Object) store.getObject(arrayID); + int len = 0; + len = Array.getLength(o); + // System.out.println ("Returning array length: " + len); + + // System.out.println ("array length: " + o + " " + len); + write(reference, "GetArrayLength " + Array.getLength(o)); + } else if (message.startsWith("GetField")) { + String[] args = message.split(" "); + String type = parseCall(args[1], src, String.class); + Integer objectID = parseCall(args[1], src, Integer.class); + Integer fieldID = parseCall(args[2], src, Integer.class); + + Object o = (Object) store.getObject(objectID); + Field f = (Field) store.getObject(fieldID); + + Object ret = null; + ret = f.get(o); + + // System.out.println ("FIELD VALUE: " + ret); + if (ret == null) { + write(reference, "GetField 0"); + } else if (f.getType() == Boolean.TYPE + || f.getType() == Byte.TYPE + || f.getType() == Character.TYPE + || f.getType() == Short.TYPE + || f.getType() == Integer.TYPE + || f.getType() == Long.TYPE + || f.getType() == Float.TYPE + || f.getType() == Double.TYPE) { + write(reference, "GetField " + ret); + } else { + // Track returned object. + store.reference(ret); + write(reference, "GetField " + store.getIdentifier(ret)); + } + } else if (message.startsWith("GetObjectClass")) { + int oid = Integer.parseInt(message.substring("GetObjectClass" + .length() + 1)); + // System.out.println ("GETTING CLASS FOR: " + oid); + Class c = store.getObject(oid).getClass(); + // System.out.println (" OBJ: " + store.getObject(oid)); + // System.out.println (" CLS: " + c); + store.reference(c); + + write(reference, "GetObjectClass " + store.getIdentifier(c)); + } else if (message.startsWith("CallStaticMethod")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + Integer methodID = parseCall(args[2], src, Integer.class); + + System.out.println("GETTING: " + methodID); + Method m = (Method) store.getObject(methodID); + System.out.println("GOT: " + m); + Class[] argTypes = m.getParameterTypes(); + + Object[] arguments = new Object[argTypes.length]; + for (int i = 0; i < argTypes.length; i++) { + arguments[i] = parseArgs(args[3 + i], argTypes[i]); + // System.out.println ("GOT ARG: " + argTypes[i] + " " + + // arguments[i]); + } + + // System.out.println ("Calling " + m); + Object ret = null; + ret = m.invoke(null, arguments); + + // if (ret != null) + // System.out.println ("RETURN VALUE: " + ret + " " + + // ret.getClass()); + // else + // System.out.println ("RETURN VALUE: " + ret); + if (ret == null) { + write(reference, "CallStaticMethod void"); + } else if (m.getReturnType() == Boolean.TYPE + || m.getReturnType() == Byte.TYPE + || m.getReturnType() == Short.TYPE + || m.getReturnType() == Integer.TYPE + || m.getReturnType() == Long.TYPE + || m.getReturnType() == Float.TYPE + || m.getReturnType() == Double.TYPE) { + write(reference, "CallStaticMethod " + ret); + } else if (m.getReturnType() == Character.TYPE) { + char ch = (Character) ret; + int high = (((int) ch) >> 8) & 0x0ff; + int low = ((int) ch) & 0x0ff; + write(reference, "CallStaticMethod " + low + "_" + high); + } else { + // Track returned object. + store.reference(ret); + write(reference, "CallStaticMethod " + + store.getIdentifier(ret)); + } + } else if (message.startsWith("CallMethod")) { + String[] args = message.split(" "); + Integer objectID = parseCall(args[1], src, Integer.class); + Integer methodID = parseCall(args[2], src, Integer.class); + + Object o = (Object) store.getObject(objectID); + Method m = (Method) store.getObject(methodID); + Class[] argTypes = m.getParameterTypes(); + + Object[] arguments = new Object[argTypes.length]; + for (int i = 0; i < argTypes.length; i++) { + arguments[i] = parseArgs(args[3 + i], argTypes[i]); + PluginDebug.debug("GOT ARG: " + argTypes[i] + " " + + arguments[i]); + } + + String collapsedArgs = ""; + for (String s : args) { + collapsedArgs += " " + s; + } + + PluginDebug.debug("Calling method " + m + " on object " + o + + " with " + arguments); + Object ret = null; + ret = m.invoke(o, arguments); + + String retO; + if (ret == null) { + retO = "null"; + } else { + retO = ret.getClass().toString(); + } + + PluginDebug.debug("Calling " + m + " on " + o + " with " + + collapsedArgs + " and that returned: " + ret + + " of type " + retO); + + if (ret == null) { + write(reference, "CallMethod void"); + } else if (m.getReturnType() == Boolean.TYPE + || m.getReturnType() == Byte.TYPE + || m.getReturnType() == Short.TYPE + || m.getReturnType() == Integer.TYPE + || m.getReturnType() == Long.TYPE + || m.getReturnType() == Float.TYPE + || m.getReturnType() == Double.TYPE) { + write(reference, "CallMethod " + ret); + } else if (m.getReturnType() == Character.TYPE) { + char ch = (Character) ret; + int high = (((int) ch) >> 8) & 0x0ff; + int low = ((int) ch) & 0x0ff; + write(reference, "CallMethod " + low + "_" + high); + } else { + // Track returned object. + store.reference(ret); + write(reference, "CallMethod " + store.getIdentifier(ret)); + } + } else if (message.startsWith("GetSuperclass")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + Class c = null; + Class ret = null; + + c = (Class) store.getObject(classID); + ret = c.getSuperclass(); + store.reference(ret); + + write(reference, "GetSuperclass " + store.getIdentifier(ret)); + } else if (message.startsWith("IsAssignableFrom")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + Integer superclassID = parseCall(args[2], src, Integer.class); + + boolean result = false; + Class clz = (Class) store.getObject(classID); + Class sup = (Class) store.getObject(superclassID); + + result = sup.isAssignableFrom(clz); + + write(reference, "IsAssignableFrom " + (result ? "1" : "0")); + } else if (message.startsWith("IsInstanceOf")) { + String[] args = message.split(" "); + Integer objectID = parseCall(args[1], src, Integer.class); + Integer classID = parseCall(args[2], src, Integer.class); + + boolean result = false; + Object o = (Object) store.getObject(objectID); + Class c = (Class) store.getObject(classID); + + result = c.isInstance(o); + + write(reference, "IsInstanceOf " + (result ? "1" : "0")); + } else if (message.startsWith("GetStringUTFLength")) { + String[] args = message.split(" "); + Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; + o = (String) store.getObject(stringID); + b = o.getBytes("UTF-8"); + // System.out.println ("STRING UTF-8 LENGTH: " + o + " " + + // b.length); + + write(reference, "GetStringUTFLength " + o.length()); + } else if (message.startsWith("GetStringLength")) { + String[] args = message.split(" "); + Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; + o = (String) store.getObject(stringID); + b = o.getBytes("UTF-16LE"); + // System.out.println ("STRING UTF-16 LENGTH: " + o + " " + + // b.length); + + // System.out.println ("Java: GetStringLength " + b.length); + write(reference, "GetStringLength " + o.length()); + } else if (message.startsWith("GetStringUTFChars")) { + String[] args = message.split(" "); + Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; + StringBuffer buf = null; + o = (String) store.getObject(stringID); + b = o.getBytes("UTF-8"); + buf = new StringBuffer(b.length * 2); + buf.append(b.length); + for (int i = 0; i < b.length; i++) + buf + .append(" " + + Integer + .toString(((int) b[i]) & 0x0ff, 16)); + + // System.out.println ("Java: GetStringUTFChars: " + o); + // //System.out.println ("String UTF BYTES: " + buf); + write(reference, "GetStringUTFChars " + buf); + } else if (message.startsWith("GetStringChars")) { + String[] args = message.split(" "); + Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; + StringBuffer buf = null; + o = (String) store.getObject(stringID); + // FIXME: LiveConnect uses UCS-2. + b = o.getBytes("UTF-16LE"); + buf = new StringBuffer(b.length * 2); + buf.append(b.length); + for (int i = 0; i < b.length; i++) + buf + .append(" " + + Integer + .toString(((int) b[i]) & 0x0ff, 16)); + + System.out.println("Java: GetStringChars: " + o); + System.out.println(" String BYTES: " + buf); + write(reference, "GetStringChars " + buf); + } else if (message.startsWith("NewArray")) { + String[] args = message.split(" "); + String type = parseCall(args[1], src, String.class); + Integer length = parseCall(args[2], src, Integer.class); + + // System.out.println ("CALLING: NewArray: " + type + " " + + // length + " " + // + Signature.primitiveNameToType(type)); + + Object newArray = null; + newArray = Array.newInstance(Signature + .primitiveNameToType(type), length); + + store.reference(newArray); + write(reference, "NewArray " + store.getIdentifier(newArray)); + } else if (message.startsWith("NewObjectArray")) { + String[] args = message.split(" "); + Integer length = parseCall(args[1], src, Integer.class); + Integer classID = parseCall(args[2], src, Integer.class); + Integer objectID = parseCall(args[3], src, Integer.class); + + // System.out.println ("CALLING: NewObjectArray: " + + // classID + " " + length + " " + // + objectID); + + Object newArray = null; + newArray = Array.newInstance((Class) store.getObject(classID), + length); + + Object[] array = (Object[]) newArray; + for (int i = 0; i < array.length; i++) + array[i] = store.getObject(objectID); + store.reference(newArray); + write(reference, "NewObjectArray " + + store.getIdentifier(newArray)); + } else if (message.startsWith("NewObject")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + Integer methodID = parseCall(args[2], src, Integer.class); + + final Constructor m = (Constructor) store.getObject(methodID); + Class[] argTypes = m.getParameterTypes(); + + // System.out.println ("NEWOBJ: HERE1"); + final Object[] arguments = new Object[argTypes.length]; + // System.out.println ("NEWOBJ: HERE2"); + for (int i = 0; i < argTypes.length; i++) { + arguments[i] = parseArgs(args[3 + i], argTypes[i]); + // System.out.println ("NEWOBJ: GOT ARG: " + arguments[i]); + } + + Object ret = m.newInstance(arguments); + store.reference(ret); + + write(reference, "NewObject " + store.getIdentifier(ret)); + + } else if (message.startsWith("NewString")) { + System.out.println("MESSAGE: " + message); + String[] args = message.split(" "); + Integer strlength = parseCall(args[1], src, Integer.class); + int bytelength = 2 * strlength; + byte[] byteArray = new byte[bytelength]; + String ret = null; + for (int i = 0; i < strlength; i++) { + int c = parseCall(args[2 + i], src, Integer.class); + System.out.println("char " + i + " " + c); + // Low. + byteArray[2 * i] = (byte) (c & 0x0ff); + // High. + byteArray[2 * i + 1] = (byte) ((c >> 8) & 0x0ff); + } + ret = new String(byteArray, 0, bytelength, "UTF-16LE"); + System.out.println("NEWSTRING: " + ret); + + // System.out.println ("NEWOBJ: CALLED: " + ret); + // System.out.println ("NEWOBJ: CALLED: " + + // store.getObject(ret)); + store.reference(ret); + write(reference, "NewString " + store.getIdentifier(ret)); + } else if (message.startsWith("NewStringUTF")) { + System.out.println("MESSAGE: " + message); + String[] args = message.split(" "); + byte[] byteArray = new byte[60]; + String ret = null; + int i = 0; + int c = 0; + while (((byte) c) != 0) { + c = parseCall(args[1 + i], src, Integer.class); + byteArray[i] = (byte) c; + i++; + if (i == byteArray.length) { + byte[] newByteArray = new byte[2 * byteArray.length]; + System.arraycopy(byteArray, 0, newByteArray, 0, + byteArray.length); + byteArray = newByteArray; + } + } + byteArray[i] = (byte) 0; + ret = new String(byteArray, "UTF-8"); + System.out.println("NEWSTRINGUTF: " + ret); + + store.reference(ret); + write(reference, "NewStringUTF " + store.getIdentifier(ret)); + } else if (message.startsWith("ExceptionOccurred")) { + System.out.println("EXCEPTION: " + throwable); + if (throwable != null) + store.reference(throwable); + write(reference, "ExceptionOccurred " + + store.getIdentifier(throwable)); + } else if (message.startsWith("ExceptionClear")) { + if (throwable != null) + store.unreference(store.getIdentifier(throwable)); + throwable = null; + write(reference, "ExceptionClear"); + } else if (message.startsWith("DeleteGlobalRef")) { + String[] args = message.split(" "); + Integer id = parseCall(args[1], src, Integer.class); + store.unreference(id); + write(reference, "DeleteGlobalRef"); + } else if (message.startsWith("DeleteLocalRef")) { + String[] args = message.split(" "); + Integer id = parseCall(args[1], src, Integer.class); + store.unreference(id); + write(reference, "DeleteLocalRef"); + } else if (message.startsWith("NewGlobalRef")) { + String[] args = message.split(" "); + Integer id = parseCall(args[1], src, Integer.class); + store.reference(store.getObject(id)); + write(reference, "NewGlobalRef " + id); + } + } catch (Throwable t) { + t.printStackTrace(); + throwable = t; + PluginException p = new PluginException(this.streamhandler, identifier, reference, t); + } + } + + private void write(int reference, String message) { + PluginDebug.debug("appletviewer writing " + message); + streamhandler.write("context " + identifier + " reference " + reference + + " " + message); + } + + public void dumpStore() { + store.dump(); + } + + public Object getObject(int identifier) { + return store.getObject(identifier); + } + + public int getIdentifier(Object o) { + return store.getIdentifier(o); + } + + public void store(Object o) { + store.reference(o); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,22 @@ +package org.classpath.icedtea.plugin; + +import sun.applet.PluginCallRequest; +import sun.applet.PluginCallRequestFactory; + +public class PluginCallRequestFactoryImpl implements PluginCallRequestFactory { + + public PluginCallRequest getPluginCallRequest(String id, String message, String returnString) { + + if (id == "member") { + return new GetMemberPluginCallRequest(message, returnString); + } else if (id == "void") { + return new VoidPluginCallRequest(message, returnString); + } else if (id == "window") { + return new GetWindowPluginCallRequest(message, returnString); + } else { + throw new RuntimeException ("Unknown plugin call request type requested from factory"); + } + + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/PluginMain.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,193 @@ +/* + * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.classpath.icedtea.plugin; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.net.Socket; +import java.util.Enumeration; +import java.util.Properties; + +import sun.applet.AppletSecurityContext; +import sun.applet.AppletSecurityContextManager; +import sun.applet.PluginAppletViewer; +import sun.applet.PluginStreamHandler; + +/** + * The main entry point into PluginAppletViewer. + */ +public class PluginMain +{ + final boolean redirectStreams = true; + static PluginStreamHandler streamHandler; + + // This is used in init(). Getting rid of this is desirable but depends + // on whether the property that uses it is necessary/standard. + public static final String theVersion = System.getProperty("java.version"); + + private AppletSecurityContext securityContext; + + /** + * The main entry point into AppletViewer. + */ + public static void main(String args[]) + throws IOException + { + + if (args.length != 1) { + // Indicate to plugin that appletviewer is installed correctly. + System.exit(0); + } + + int port = 0; + try { + port = Integer.parseInt(args[0]); + } catch (NumberFormatException e) { + System.err.println("Failed to parse port number: " + e); + System.exit(1); + } + + PluginMain pm = new PluginMain(); + + } + + public PluginMain() { + + if (redirectStreams) { + try { + File errFile = new File("/tmp/java.stderr"); + File outFile = new File("/tmp/java.stdout"); + + System.setErr(new PrintStream(new FileOutputStream(errFile))); + System.setOut(new PrintStream(new FileOutputStream(outFile))); + + } catch (Exception e) { + System.err.println("Unable to redirect streams"); + e.printStackTrace(); + } + } + + // INSTALL THE SECURITY MANAGER + init(); + + connect(50007); + + securityContext = new PluginAppletSecurityContext(0); + securityContext.setStreamhandler(streamHandler); + AppletSecurityContextManager.addContext(0, securityContext); + + PluginAppletViewer.setStreamhandler(streamHandler); + PluginAppletViewer.setPluginCallRequestFactory(new PluginCallRequestFactoryImpl()); + + // Streams set. Start processing. + streamHandler.startProcessing(); + } + + public void connect(int port) { + /* + * Code for TCP/IP communication + */ + Socket socket = null; + + try { + socket = new Socket("localhost", port); + } catch (Exception e) { + e.printStackTrace(); + } + + System.err.println("Socket initialized. Proceeding with start()"); + + try { + streamHandler = new PluginStreamHandlerImpl(socket.getInputStream(), socket.getOutputStream()); + System.err.println("Streams initialized"); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + private static void init() { + Properties avProps = new Properties(); + + // ADD OTHER RANDOM PROPERTIES + // XXX 5/18 need to revisit why these are here, is there some + // standard for what is available? + + // Standard browser properties + avProps.put("browser", "sun.applet.AppletViewer"); + avProps.put("browser.version", "1.06"); + avProps.put("browser.vendor", "Sun Microsystems Inc."); + avProps.put("http.agent", "Java(tm) 2 SDK, Standard Edition v" + theVersion); + + // Define which packages can be extended by applets + // XXX 5/19 probably not needed, not checked in AppletSecurity + avProps.put("package.restrict.definition.java", "true"); + avProps.put("package.restrict.definition.sun", "true"); + + // Define which properties can be read by applets. + // A property named by "key" can be read only when its twin + // property "key.applet" is true. The following ten properties + // are open by default. Any other property can be explicitly + // opened up by the browser user by calling appletviewer with + // -J-Dkey.applet=true + avProps.put("java.version.applet", "true"); + avProps.put("java.vendor.applet", "true"); + avProps.put("java.vendor.url.applet", "true"); + avProps.put("java.class.version.applet", "true"); + avProps.put("os.name.applet", "true"); + avProps.put("os.version.applet", "true"); + avProps.put("os.arch.applet", "true"); + avProps.put("file.separator.applet", "true"); + avProps.put("path.separator.applet", "true"); + avProps.put("line.separator.applet", "true"); + + // Read in the System properties. If something is going to be + // over-written, warn about it. + Properties sysProps = System.getProperties(); + for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements(); ) { + String key = (String) e.nextElement(); + String val = (String) sysProps.getProperty(key); + avProps.setProperty(key, val); + } + + // INSTALL THE PROPERTY LIST + System.setProperties(avProps); + + // Create and install the security manager + //System.setSecurityManager(new AppletSecurity()); + + // REMIND: Create and install a socket factory! + } + + static boolean messageAvailable() { + return streamHandler.messageAvailable(); + } + + static String getMessage() { + return streamHandler.getMessage(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageConsumer.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,76 @@ +package org.classpath.icedtea.plugin; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.LinkedList; + +import sun.applet.PluginDebug; +import sun.applet.PluginStreamHandler; + + + +class PluginMessageConsumer { + + int MAX_WORKERS = 3; + LinkedList<String> readQueue = new LinkedList<String>(); + ArrayList<PluginMessageHandlerWorker> workers = new ArrayList<PluginMessageHandlerWorker>(); + PluginStreamHandler streamHandler = null; + + public PluginMessageConsumer(PluginStreamHandler streamHandler) { + + this.streamHandler = streamHandler; + + for (int i=0; i < MAX_WORKERS; i++) { + System.err.println("Creating worker " + i); + PluginMessageHandlerWorker worker = new PluginMessageHandlerWorker(streamHandler, i); + worker.start(); + workers.add(worker); + } + } + + public void consume(String message) { + + PluginDebug.debug("Consumer received message " + message); + + synchronized(readQueue) { + readQueue.add(message); + } + + PluginDebug.debug("Message " + message + " added to queue. Looking for free worker..."); + final PluginMessageHandlerWorker worker = getFreeWorker(); + + synchronized(readQueue) { + if (readQueue.size() > 0) { + worker.setmessage(readQueue.poll()); + } + } + + AccessController.doPrivileged(new PrivilegedAction() { + public Object run () { + worker.interrupt(); + return null; + } + }); + } + + private PluginMessageHandlerWorker getFreeWorker() { + + // FIXME: Can be made more efficient by having an idle worker pool + + while (true) { + for (PluginMessageHandlerWorker worker: workers) { + if (worker.isFree()) { + PluginDebug.debug("Found free worker with id " + worker.getWorkerId()); + // mark it busy before returning + worker.busy(); + return worker; + } + } + Thread.yield(); + } + + //throw new RuntimeException("Out of message handler workers"); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,79 @@ +package org.classpath.icedtea.plugin; + +import sun.applet.PluginException; +import sun.applet.PluginStreamHandler; + +class PluginMessageHandlerWorker extends Thread { + + private boolean free = true; + private int id; + private String message = null; + PluginStreamHandler streamHandler = null; + + public PluginMessageHandlerWorker(PluginStreamHandler streamHandler, int id) { + this.id = id; + this.streamHandler = streamHandler; + } + + public void setmessage(String message) { + this.message = message; + } + + public void run() { + while (true) { + + if (message != null) { + + // ideally, whoever returns things object should mark it + // busy first, but just in case.. + busy(); + System.err.println("Thread " + id + " picking up " + message + " from queue..."); + + try { + streamHandler.handleMessage(message); + } catch (PluginException pe) { + /* + catch the exception and DO NOTHING. The plugin should take over after + this error and let the user know. We don't quit because otherwise the + exception will spread to the rest of the applets which is a no-no + */ + } + + this.message = null; + } else { + + // Sleep when there is nothing to do + try { + Thread.sleep(Integer.MAX_VALUE); + System.err.println("Consumer thread " + id + " sleeping..."); + } catch (InterruptedException ie) { + System.err.println("Consumer thread " + id + " woken..."); + // nothing.. someone woke us up, see if there + // is work to do + } + } + + // mark ourselves free again + free(); + } + } + + + + public int getWorkerId() { + return id; + } + + public void busy() { + this.free = false; + } + + + public void free() { + this.free = true; + } + + public boolean isFree() { + return free; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/PluginObjectStore.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,119 @@ +/* PluginObjectStore -- manage identifier-to-object mapping + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package org.classpath.icedtea.plugin; + +import java.util.*; +import java.lang.reflect.*; +import java.io.*; + +public class PluginObjectStore +{ + private static HashMap<Integer, Object> objects = new HashMap(); + private static HashMap<Integer, Integer> counts = new HashMap(); + private static HashMap<Object, Integer> identifiers = new HashMap(); + // FIXME: + // + // IF uniqueID == MAX_LONG, uniqueID = + // 0 && wrapped = true + // + // if (wrapped), check if + // objects.get(uniqueID) returns null + // + // if yes, use uniqueID, if no, + // uniqueID++ and keep checking + // or: + // stack of available ids: + // derefed id -> derefed id -> nextUniqueIdentifier + private static int nextUniqueIdentifier = 1; + + public Object getObject(Integer identifier) { + return objects.get(identifier); + } + + public Integer getIdentifier(Object object) { + if (object == null) + return 0; + return identifiers.get(object); + } + + public void reference(Object object) { + Integer identifier = identifiers.get(object); + if (identifier == null) { + objects.put(nextUniqueIdentifier, object); + counts.put(nextUniqueIdentifier, 1); + identifiers.put(object, nextUniqueIdentifier); + System.out.println("JAVA ADDED: " + nextUniqueIdentifier); + System.out.println("JAVA REFERENCED: " + nextUniqueIdentifier + + " to: 1"); + nextUniqueIdentifier++; + } else { + counts.put(identifier, counts.get(identifier) + 1); + System.out.println("JAVA REFERENCED: " + identifier + + " to: " + counts.get(identifier)); + } + } + + public void unreference(int identifier) { + Integer currentCount = counts.get(identifier); + if (currentCount == null) + System.out.println("ERROR UNREFERENCING: " + identifier); + if (currentCount == 1) { + System.out.println("JAVA DEREFERENCED: " + identifier + + " to: 0"); + Object object = objects.get(identifier); + objects.remove(identifier); + counts.remove(identifier); + identifiers.remove(object); + System.out.println("JAVA REMOVED: " + identifier); + } else { + counts.put(identifier, currentCount - 1); + System.out.println("JAVA DEREFERENCED: " + + identifier + " to: " + + counts.get(identifier)); + } + } + + public void dump() { + Iterator i = objects.keySet().iterator(); + while (i.hasNext()) { + Object key = i.next(); + System.err.println(key + "::" + objects.get(key)); + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,362 @@ +package org.classpath.icedtea.plugin; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.StreamTokenizer; +import java.net.MalformedURLException; +import java.nio.charset.Charset; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.LinkedList; +import java.util.StringTokenizer; + +import sun.applet.AppletSecurityContextManager; +import sun.applet.PluginAppletViewer; +import sun.applet.PluginCallRequest; +import sun.applet.PluginDebug; +import sun.applet.PluginException; +import sun.applet.PluginStreamHandler; + +public class PluginStreamHandlerImpl implements PluginStreamHandler { + + private BufferedReader pluginInputReader; + private StreamTokenizer pluginInputTokenizer; + private BufferedWriter pluginOutputWriter; + + private RequestQueue queue = new RequestQueue(); + + LinkedList<String> writeQueue = new LinkedList<String>(); + + PluginMessageConsumer consumer; + Boolean shuttingDown = false; + + PluginAppletViewer pav; + + public PluginStreamHandlerImpl(InputStream inputstream, OutputStream outputstream) + throws MalformedURLException, IOException + { + + System.err.println("Current context CL=" + Thread.currentThread().getContextClassLoader()); + try { + pav = (PluginAppletViewer) ClassLoader.getSystemClassLoader().loadClass("sun.applet.PluginAppletViewer").newInstance(); + System.err.println("Loaded: " + pav + " CL=" + pav.getClass().getClassLoader()); + } catch (InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + System.err.println("Creating consumer..."); + consumer = new PluginMessageConsumer(this); + + // Set up input and output pipes. Use UTF-8 encoding. + pluginInputReader = + new BufferedReader(new InputStreamReader(inputstream, + Charset.forName("UTF-8"))); + pluginInputTokenizer = new StreamTokenizer(pluginInputReader); + pluginInputTokenizer.resetSyntax(); + pluginInputTokenizer.whitespaceChars('\u0000', '\u0000'); + pluginInputTokenizer.wordChars('\u0001', '\u00FF'); + pluginOutputWriter = + new BufferedWriter(new OutputStreamWriter + (outputstream, Charset.forName("UTF-8"))); + + /* + while(true) { + String message = read(); + PluginDebug.debug(message); + handleMessage(message); + // TODO: + // write(queue.peek()); + } + */ + } + + public void startProcessing() { + + Thread listenerThread = new Thread() { + + public void run() { + while (true) { + + System.err.println("Waiting for data..."); + + int readChar = -1; + // blocking read, discard first character + try { + readChar = pluginInputReader.read(); + } catch (IOException ioe) { + // plugin may have detached + } + + // if not disconnected + if (readChar != -1) { + String s = read(); + System.err.println("Got data, consuming " + s); + consumer.consume(s); + } else { + try { + // Close input/output channels to plugin. + pluginInputReader.close(); + pluginOutputWriter.close(); + } catch (IOException exception) { + // Deliberately ignore IOException caused by broken + // pipe since plugin may have already detached. + } + AppletSecurityContextManager.dumpStore(0); + System.err.println("APPLETVIEWER: exiting appletviewer"); + System.exit(0); + } + } + } + }; + + listenerThread.start(); + } + + public void postMessage(String s) { + + if (s == null || s.equals("shutdown")) { + try { + // Close input/output channels to plugin. + pluginInputReader.close(); + pluginOutputWriter.close(); + } catch (IOException exception) { + // Deliberately ignore IOException caused by broken + // pipe since plugin may have already detached. + } + AppletSecurityContextManager.dumpStore(0); + System.err.println("APPLETVIEWER: exiting appletviewer"); + System.exit(0); + } + + //PluginAppletSecurityContext.contexts.get(0).store.dump(); + PluginDebug.debug("Plugin posted: " + s); + + System.err.println("Consuming " + s); + consumer.consume(s); + + PluginDebug.debug("Added to queue"); + } + + public void handleMessage(String message) throws PluginException { + + StringTokenizer st = new StringTokenizer(message, " "); + + String type = st.nextToken(); + final int identifier = Integer.parseInt(st.nextToken()); + + String rest = ""; + int reference = -1; + String src = null; + + String potentialReference = st.hasMoreTokens() ? st.nextToken() : ""; + + // if the next token is reference, read it, else reset "rest" + if (potentialReference.equals("reference")) { + reference = Integer.parseInt(st.nextToken()); + } else { + rest += potentialReference + " "; + } + + String potentialSrc = st.hasMoreTokens() ? st.nextToken() : ""; + + if (potentialSrc.equals("src")) { + src = st.nextToken(); + } else { + rest += potentialSrc + " "; + } + + while (st.hasMoreElements()) { + rest += st.nextToken(); + rest += " "; + } + + rest = rest.trim(); + + try { + + System.err.println("Breakdown -- type: " + type + " identifier: " + identifier + " reference: " + reference + " src: " + src + " rest: " + rest); + + if (rest.contains("JavaScriptGetWindow") + || rest.contains("JavaScriptGetMember") + || rest.contains("JavaScriptSetMember") + || rest.contains("JavaScriptGetSlot") + || rest.contains("JavaScriptSetSlot") + || rest.contains("JavaScriptEval") + || rest.contains("JavaScriptRemoveMember") + || rest.contains("JavaScriptCall") + || rest.contains("JavaScriptFinalize") + || rest.contains("JavaScriptToString")) { + + finishCallRequest(rest); + return; + } + + final int freference = reference; + final String frest = rest; + + if (type.equals("instance")) { + PluginAppletViewer.handleMessage(identifier, freference,frest); + } else if (type.equals("context")) { + PluginDebug.debug("Sending to PASC: " + identifier + "/" + reference + " and " + rest); + AppletSecurityContextManager.handleMessage(identifier, src, reference, rest); + } + } catch (Exception e) { + throw new PluginException(this, identifier, reference, e); + } + } + + public void postCallRequest(PluginCallRequest request) { + synchronized(queue) { + queue.post(request); + } + } + + private void finishCallRequest(String message) { + PluginDebug.debug ("DISPATCHCALLREQUESTS 1"); + synchronized(queue) { + PluginDebug.debug ("DISPATCHCALLREQUESTS 2"); + PluginCallRequest request = queue.pop(); + + // make sure we give the message to the right request + // in the queue.. for the love of God, MAKE SURE! + + // first let's be efficient.. if there was only one + // request in queue, we're already set + if (queue.size() != 0) { + + int size = queue.size(); + int count = 0; + + while (!request.serviceable(message)) { + + // something is very wrong.. we have a message to + // process, but no one to service it + if (count >= size) { + throw new RuntimeException("Unable to find processor for message " + message); + } + + // post request at the end of the queue + queue.post(request); + + // Look at the next request + request = queue.pop(); + + count++; + } + + } + + PluginDebug.debug ("DISPATCHCALLREQUESTS 3"); + if (request != null) { + PluginDebug.debug ("DISPATCHCALLREQUESTS 5"); + synchronized(request) { + request.parseReturn(message); + request.notifyAll(); + } + PluginDebug.debug ("DISPATCHCALLREQUESTS 6"); + PluginDebug.debug ("DISPATCHCALLREQUESTS 7"); + } + } + PluginDebug.debug ("DISPATCHCALLREQUESTS 8"); + } + + /** + * Read string from plugin. + * + * @return the read string + * + * @exception IOException if an error occurs + */ + private String read() + { + try { + pluginInputTokenizer.nextToken(); + } catch (IOException e) { + throw new RuntimeException(e); + } + String message = pluginInputTokenizer.sval; + PluginDebug.debug(" PIPE: appletviewer read: " + message); + if (message == null || message.equals("shutdown")) { + synchronized(shuttingDown) { + shuttingDown = true; + } + try { + // Close input/output channels to plugin. + pluginInputReader.close(); + pluginOutputWriter.close(); + } catch (IOException exception) { + // Deliberately ignore IOException caused by broken + // pipe since plugin may have already detached. + } + AppletSecurityContextManager.dumpStore(0); + System.err.println("APPLETVIEWER: exiting appletviewer"); + System.exit(0); + } + return message; + } + + /** + * Write string to plugin. + * + * @param message the message to write + * + * @exception IOException if an error occurs + */ + public void write(String message) + { + + System.err.println(" PIPE: appletviewer wrote: " + message); + synchronized(pluginOutputWriter) { + try { + pluginOutputWriter.write(message, 0, message.length()); + pluginOutputWriter.write(0); + pluginOutputWriter.flush(); + } catch (IOException e) { + // if we are shutting down, ignore write failures as + // pipe may have closed + synchronized(shuttingDown) { + if (!shuttingDown) { + e.printStackTrace(); + } + } + + // either ways, if the pipe is broken, there is nothing + // we can do anymore. Don't hang around. + System.err.println("Unable to write to PIPE. APPLETVIEWER exiting"); + System.exit(1); + } + } + + return; + /* + synchronized(writeQueue) { + writeQueue.add(message); + System.err.println(" PIPE: appletviewer wrote: " + message); + } + */ + + } + + public boolean messageAvailable() { + return writeQueue.size() != 0; + } + + public String getMessage() { + synchronized(writeQueue) { + String ret = writeQueue.size() > 0 ? writeQueue.poll() : ""; + return ret; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/RequestQueue.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,40 @@ +package org.classpath.icedtea.plugin; + +import sun.applet.PluginCallRequest; + +public class RequestQueue { + PluginCallRequest head = null; + PluginCallRequest tail = null; + private int size = 0; + + public void post(PluginCallRequest request) { + System.err.println("Securitymanager=" + System.getSecurityManager()); + if (head == null) { + head = tail = request; + tail.setNext(null); + } else { + tail.setNext(request); + tail = request; + tail.setNext(null); + } + + size++; + } + + public PluginCallRequest pop() { + if (head == null) + return null; + + PluginCallRequest ret = head; + head = head.getNext(); + ret.setNext(null); + + size--; + + return ret; + } + + public int size() { + return size; + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/TestEnv.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,172 @@ +/* TestEnv -- test JavaScript-to-Java calls + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package org.classpath.icedtea.plugin; + +public class TestEnv +{ + public static int intField = 103; + public int intInstanceField = 7822; + public String stringField = "hello"; + // z <musical G clef> <chinese water> + public String complexStringField = "z\uD834\uDD1E\u6C34"; + + public static void TestIt() { + System.out.println("TestIt"); + } + + public static void TestItBool(boolean arg) { + System.out.println("TestItBool: " + arg); + } + + public static void TestItByte(byte arg) { + System.out.println("TestItByte: " + arg); + } + + public static void TestItChar(char arg) { + System.out.println("TestItChar: " + arg); + } + + public static void TestItShort(short arg) { + System.out.println("TestItShort: " + arg); + } + + public static void TestItInt(int arg) { + System.out.println("TestItInt: " + arg); + } + + public static void TestItLong(long arg) { + System.out.println("TestItLong: " + arg); + } + + public static void TestItFloat(float arg) { + System.out.println("TestItFloat: " + arg); + } + + public static void TestItDouble(double arg) { + System.out.println("TestItDouble: " + arg); + } + + public static void TestItObject(TestEnv arg) { + System.out.println("TestItObject: " + arg); + } + + public static void TestItObjectString(String arg) { + System.out.println("TestItObjectString: " + arg); + } + + public static void TestItIntArray(int[] arg) { + System.out.println("TestItIntArray: " + arg); + for (int i = 0; i < arg.length; i++) + System.out.println ("ELEMENT: " + i + " " + arg[i]); + } + + public static void TestItObjectArray(String[] arg) { + System.out.println("TestItObjectArray: " + arg); + for (int i = 0; i < arg.length; i++) + System.out.println ("ELEMENT: " + i + " " + arg[i]); + } + + public static void TestItObjectArrayMulti(String[][] arg) { + System.out.println("TestItObjectArrayMulti: " + arg); + for (int i = 0; i < arg.length; i++) + for (int j = 0; j < arg[i].length; j++) + System.out.println ("ELEMENT: " + i + " " + j + " " + arg[i][j]); + } + + public static boolean TestItBoolReturnTrue() { + return true; + } + + public static boolean TestItBoolReturnFalse() { + return false; + } + + public static byte TestItByteReturn() { + return (byte) 0xfe; + } + + public static char TestItCharReturn() { + return 'K'; + } + + public static char TestItCharUnicodeReturn() { + return '\u6C34'; + } + + public static short TestItShortReturn() { + return 23; + } + + public static int TestItIntReturn() { + return 3445; + } + + public static long TestItLongReturn() { + return 3242883; + } + + public static float TestItFloatReturn() { + return 9.21E4f; + } + + public static double TestItDoubleReturn() { + return 8.33E88; + } + + public static Object TestItObjectReturn() { + return new String("Thomas"); + } + + public static int[] TestItIntArrayReturn() { + return new int[] { 6, 7, 8 }; + } + + public static String[] TestItObjectArrayReturn() { + return new String[] { "Thomas", "Brigitte" }; + } + + public static String[][] TestItObjectArrayMultiReturn() { + return new String[][] { {"Thomas", "Brigitte"}, + {"Lindsay", "Michael"} }; + } + + public int TestItIntInstance(int arg) { + System.out.println("TestItIntInstance: " + this + " " + arg); + return 899; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/org/classpath/icedtea/plugin/VoidPluginCallRequest.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,69 @@ +/* VoidPluginCallRequest -- represent Java-to-JavaScript requests + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package org.classpath.icedtea.plugin; + +import sun.applet.PluginCallRequest; + +public class VoidPluginCallRequest extends PluginCallRequest { + public VoidPluginCallRequest(String message, String returnString) { + super(message, returnString); + System.out.println ("VoidPLUGINCAlL " + message + " " + returnString); + } + + public void parseReturn(String message) { + setDone(true); + } + + + /** + * Returns whether the given message is serviceable by this object + * + * @param message The message to service + * @return boolean indicating if message is serviceable + */ + public boolean serviceable(String message) { + return message.contains("JavaScriptFinalize") || + message.contains("JavaScriptRemoveMember") || + message.contains("JavaScriptSetMember") || + message.contains("JavaScriptSetSlot"); + } + + public Object getObject() { + return null; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/AppletSecurityContext.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,25 @@ +package sun.applet; + +import java.util.HashMap; + +public abstract class AppletSecurityContext { + + public static PluginStreamHandler streamhandler; + + public static void setStreamhandler(PluginStreamHandler sh) { + streamhandler = sh; + } + + public abstract void handleMessage(String src, int reference, String message); + + public abstract void addClassLoader(String id, ClassLoader cl); + + public abstract void dumpStore(); + + public abstract Object getObject(int identifier); + + public abstract int getIdentifier(Object o); + + public abstract void store(Object o); + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/AppletSecurityContextManager.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,27 @@ +package sun.applet; + +import java.util.HashMap; + +public class AppletSecurityContextManager { + + // Context identifier -> PluginAppletSecurityContext object. + // FIXME: make private + private static HashMap<Integer, AppletSecurityContext> contexts = new HashMap(); + + public static void addContext(int identifier, AppletSecurityContext context) { + contexts.put(identifier, context); + } + + public static AppletSecurityContext getSecurityContext(int identifier) { + return contexts.get(identifier); + } + + public static void dumpStore(int identifier) { + contexts.get(identifier).dumpStore(); + } + + public static void handleMessage(int identifier, String src, int reference, String message) { + System.err.println(identifier + " -- " + src + " -- " + reference + " -- " + message + " CONTEXT= " + contexts.get(identifier)); + contexts.get(identifier).handleMessage(src, reference, message); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginAppletViewer.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,1481 @@ + /* + * Copyright 1995-2004 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + package sun.applet; + + import java.applet.Applet; +import java.applet.AppletContext; +import java.applet.AudioClip; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Insets; +import java.awt.Label; +import java.awt.Toolkit; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.io.Reader; +import java.io.StringReader; +import java.net.SocketPermission; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Vector; + +import net.sourceforge.jnlp.NetxPanel; + +import sun.awt.AppContext; +import sun.awt.SunToolkit; +import sun.awt.X11.XEmbeddedFrame; +import sun.misc.Ref; + + /** + * Lets us construct one using unix-style one shot behaviors + */ + + class PluginAppletViewerFactory + { + public PluginAppletViewer createAppletViewer(int identifier, + long handle, int x, int y, + URL doc, Hashtable atts) { + PluginAppletViewer pluginappletviewer = new PluginAppletViewer(identifier, handle, x, y, doc, atts, System.out, this); + return pluginappletviewer; + } + + public boolean isStandalone() + { + return false; + } + } + + 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"; + + /** + * The panel in which the applet is being displayed. + */ + AppletViewerPanel panel; + + /** + * The status line. + */ + Label label; + + /** + * output status messages to this stream + */ + + PrintStream statusMsgStream; + + /** + * For cloning + */ + PluginAppletViewerFactory factory; + + int identifier; + + private static HashMap<Integer, PluginParseRequest> requests = new HashMap(); + + // Instance identifier -> PluginAppletViewer object. + private static HashMap<Integer, PluginAppletViewer> applets = new HashMap(); + + private static PluginStreamHandler streamhandler; + + private static PluginCallRequestFactory requestFactory; + + /** + * Null constructor to allow instantiation via newInstance() + */ + public PluginAppletViewer() { + } + + /** + * Create the applet viewer + */ + public PluginAppletViewer(int identifier, long handle, int x, int y, final URL doc, + final Hashtable atts, PrintStream statusMsgStream, + PluginAppletViewerFactory factory) { + super(handle, true); + this.factory = factory; + this.statusMsgStream = statusMsgStream; + this.identifier = identifier; + // FIXME: when/where do we remove this? + PluginDebug.debug ("PARSING: PUTTING " + identifier + " " + this); + applets.put(identifier, this); + + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + panel = new NetxPanel(doc, atts); + AppletViewerPanel.debug("Using NetX panel"); + } catch (Exception ex) { + AppletViewerPanel.debug("Unable to start NetX applet - defaulting to Sun applet", ex); + panel = new AppletViewerPanel(doc, atts); + } + return null; + } + }); + + add("Center", panel); + panel.init(); + appletPanels.addElement(panel); + + pack(); + setVisible(true); + + WindowListener windowEventListener = new WindowAdapter() { + + public void windowClosing(WindowEvent evt) { + appletClose(); + } + + public void windowIconified(WindowEvent evt) { + appletStop(); + } + + public void windowDeiconified(WindowEvent evt) { + appletStart(); + } + }; + + class AppletEventListener implements AppletListener + { + final Frame frame; + + public AppletEventListener(Frame frame) + { + this.frame = frame; + } + + public void appletStateChanged(AppletEvent evt) + { + AppletPanel src = (AppletPanel)evt.getSource(); + + switch (evt.getID()) { + case AppletPanel.APPLET_RESIZE: { + if(src != null) { + resize(preferredSize()); + validate(); + } + break; + } + case AppletPanel.APPLET_LOADING_COMPLETED: { + Applet a = src.getApplet(); // sun.applet.AppletPanel + + // Fixed #4754451: Applet can have methods running on main + // thread event queue. + // + // The cause of this bug is that the frame of the applet + // is created in main thread group. Thus, when certain + // AWT/Swing events are generated, the events will be + // dispatched through the wrong event dispatch thread. + // + // To fix this, we rearrange the AppContext with the frame, + // so the proper event queue will be looked up. + // + // Swing also maintains a Frame list for the AppContext, + // so we will have to rearrange it as well. + // + if (a != null) + AppletPanel.changeFrameAppContext(frame, SunToolkit.targetToAppContext(a)); + else + AppletPanel.changeFrameAppContext(frame, AppContext.getAppContext()); + + break; + } + } + } + }; + + addWindowListener(windowEventListener); + panel.addAppletListener(new AppletEventListener(this)); + + // Start the applet + showStatus(amh.getMessage("status.start")); + initEventQueue(); + + try { + write("initialized"); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + + // Wait for a maximum of 10 seconds for the panel to initialize + // (happens in a separate thread) + Applet a; + int maxSleepTime = 10000; + int sleepTime = 0; + while ((a = panel.getApplet()) == null && sleepTime < maxSleepTime) { + try { + Thread.sleep(100); + sleepTime += 100; + PluginDebug.debug("Waiting for applet to initialize... "); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + + PluginDebug.debug("Applet initialized"); + + // Applet initialized. Find out it's classloader and add it to the list + AppletSecurityContextManager.getSecurityContext(0).addClassLoader(Integer.toString(identifier), a.getClass().getClassLoader()); + + } + + public static void setStreamhandler(PluginStreamHandler sh) { + streamhandler = sh; + } + + public static void setPluginCallRequestFactory(PluginCallRequestFactory rf) { + 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("tag")) { + + // tag and handle must both be set before parsing, so we need + // synchronization here, as the setting of these variables + // may happen in independent threads + + synchronized(requests) { + PluginParseRequest request = requests.get(identifier); + if (request == null) { + request = new PluginParseRequest(); + requests.put(identifier, request); + } + int index = message.indexOf(' ', "tag".length() + 1); + request.documentbase = + message.substring("tag".length() + 1, index); + request.tag = message.substring(index + 1); + PluginDebug.debug ("REQUEST TAG: " + request.tag + " " + + Thread.currentThread()); + + if (request.handle != 0) { + PluginDebug.debug ("REQUEST TAG, PARSING " + + Thread.currentThread()); + PluginAppletViewer.parse + (identifier, request.handle, + new StringReader(request.tag), + new URL(request.documentbase)); + requests.remove(identifier); + } else { + PluginDebug.debug ("REQUEST HANDLE NOT SET: " + request.handle + ". BYPASSING"); + } + } + } else if (message.startsWith("handle")) { + synchronized(requests) { + PluginParseRequest request = requests.get(identifier); + if (request == null) { + request = new PluginParseRequest(); + requests.put(identifier, request); + } + request.handle = Long.parseLong + (message.substring("handle".length() + 1)); + PluginDebug.debug ("REQUEST HANDLE: " + request.handle); + if (request.tag != null) { + PluginDebug.debug ("REQUEST HANDLE, PARSING " + + Thread.currentThread()); + PluginAppletViewer.parse + (identifier, request.handle, + new StringReader(request.tag), + new URL(request.documentbase)); + requests.remove(identifier); + PluginDebug.debug ("REQUEST HANDLE, DONE PARSING " + + Thread.currentThread()); + } else { + PluginDebug.debug ("REQUEST TAG NOT SET: " + request.tag + ". BYPASSING"); + } + } + } else { + PluginDebug.debug ("HANDLING MESSAGE " + message + " instance " + identifier + " " + Thread.currentThread()); + applets.get(identifier).handleMessage(reference, message); + } + } catch (Exception e) { + throw new RuntimeException("Failed to handle message: " + message + " " + + Thread.currentThread(), e); + } + } + + public void handleMessage(int reference, String message) + { + if (message.startsWith("width")) { + int width = + Integer.parseInt(message.substring("width".length() + 1)); + //panel.setAppletSizeIfNeeded(width, -1); + setSize(width, getHeight()); + } else if (message.startsWith("height")) { + int height = + Integer.parseInt(message.substring("height".length() + 1)); + //panel.setAppletSizeIfNeeded(-1, height); + setSize(getWidth(), height); + } else if (message.startsWith("destroy")) { + dispose(); + } else if (message.startsWith("GetJavaObject")) { + // FIXME: how do we determine what security context this + // object should belong to? + Object o; + + // Wait for a maximum of 10 seconds for the panel to initialize + // (happens in a separate thread) + int maxSleepTime = 10000; + int sleepTime = 0; + while ((o = panel.getApplet()) == null && sleepTime < maxSleepTime) { + try { + Thread.sleep(100); + sleepTime += 100; + PluginDebug.debug("Waiting for applet to initialize..."); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + + System.err.println ("Looking for object " + o + " panel is " + panel.getClass()); + AppletSecurityContextManager.getSecurityContext(0).store(o); + System.err.println ("WRITING 1: " + "context 0 reference " + reference + " GetJavaObject " + + AppletSecurityContextManager.getSecurityContext(0).getIdentifier(o)); + streamhandler.write("context 0 reference " + reference + " GetJavaObject " + + AppletSecurityContextManager.getSecurityContext(0).getIdentifier(o)); + System.err.println ("WRITING 1 DONE"); + } + } + + /** + * Send the initial set of events to the appletviewer event queue. + * On start-up the current behaviour is to load the applet and call + * Applet.init() and Applet.start(). + */ + private void initEventQueue() { + // appletviewer.send.event is an undocumented and unsupported system + // property which is used exclusively for testing purposes. + PrivilegedAction pa = new PrivilegedAction() { + public Object run() { + return System.getProperty("appletviewer.send.event"); + } + }; + String eventList = (String) 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++) { + System.out.println("Adding event to queue: " + events[i]); + if (events[i].equals("dispose")) + panel.sendEvent(AppletPanel.APPLET_DISPOSE); + else if (events[i].equals("load")) + panel.sendEvent(AppletPanel.APPLET_LOAD); + else if (events[i].equals("init")) + panel.sendEvent(AppletPanel.APPLET_INIT); + else if (events[i].equals("start")) + panel.sendEvent(AppletPanel.APPLET_START); + else if (events[i].equals("stop")) + panel.sendEvent(AppletPanel.APPLET_STOP); + else if (events[i].equals("destroy")) + panel.sendEvent(AppletPanel.APPLET_DESTROY); + else if (events[i].equals("quit")) + panel.sendEvent(AppletPanel.APPLET_QUIT); + else if (events[i].equals("error")) + panel.sendEvent(AppletPanel.APPLET_ERROR); + else + // non-fatal error if we get an unrecognized event + System.out.println("Unrecognized event name: " + events[i]); + } + + while (!panel.emptyEventQueue()) ; + appletSystemExit(); + } + } + + /** + * Split a string based on the presence of a specified separator. Returns + * an array of arbitrary length. The end of each element in the array is + * indicated by the separator of the end of the string. If there is a + * separator immediately before the end of the string, the final element + * will be empty. None of the strings will contain the separator. Useful + * when separating strings such as "foo/bar/bas" using separator "/". + * + * @param sep The separator. + * @param s The string to split. + * @return An array of strings. Each string in the array is determined + * by the location of the provided sep in the original string, + * s. Whitespace not stripped. + */ + private String [] splitSeparator(String sep, String s) { + Vector v = new Vector(); + int tokenStart = 0; + int tokenEnd = 0; + + while ((tokenEnd = s.indexOf(sep, tokenStart)) != -1) { + v.addElement(s.substring(tokenStart, tokenEnd)); + tokenStart = tokenEnd+1; + } + // Add the final element. + v.addElement(s.substring(tokenStart)); + + String [] retVal = new String[v.size()]; + v.copyInto(retVal); + return retVal; + } + + /* + * Methods for java.applet.AppletContext + */ + + private static Map audioClips = new HashMap(); + + /** + * Get an audio clip. + */ + public AudioClip getAudioClip(URL url) { + checkConnect(url); + synchronized (audioClips) { + AudioClip clip = (AudioClip)audioClips.get(url); + if (clip == null) { + audioClips.put(url, clip = new AppletAudioClip(url)); + } + return clip; + } + } + + private static Map imageRefs = new HashMap(); + + /** + * Get an image. + */ + public Image getImage(URL url) { + return getCachedImage(url); + } + + static Image getCachedImage(URL url) { + // System.getSecurityManager().checkConnection(url.getHost(), url.getPort()); + return (Image)getCachedImageRef(url).get(); + } + + /** + * Get an image ref. + */ + static Ref getCachedImageRef(URL url) { + synchronized (imageRefs) { + AppletImageRef ref = (AppletImageRef)imageRefs.get(url); + if (ref == null) { + ref = new AppletImageRef(url); + imageRefs.put(url, ref); + } + return ref; + } + } + + /** + * Flush the image cache. + */ + static void flushImageCache() { + imageRefs.clear(); + } + + static Vector appletPanels = new Vector(); + + /** + * Get an applet by name. + */ + public Applet getApplet(String name) { + AppletSecurity security = (AppletSecurity)System.getSecurityManager(); + name = name.toLowerCase(); + SocketPermission panelSp = + new SocketPermission(panel.getCodeBase().getHost(), "connect"); + for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) { + AppletPanel p = (AppletPanel)e.nextElement(); + String param = p.getParameter("name"); + if (param != null) { + param = param.toLowerCase(); + } + if (name.equals(param) && + p.getDocumentBase().equals(panel.getDocumentBase())) { + + SocketPermission sp = + new SocketPermission(p.getCodeBase().getHost(), "connect"); + + if (panelSp.implies(sp)) { + return p.applet; + } + } + } + return null; + } + + /** + * Return an enumeration of all the accessible + * applets on this page. + */ + public Enumeration getApplets() { + AppletSecurity security = (AppletSecurity)System.getSecurityManager(); + Vector v = new Vector(); + SocketPermission panelSp = + new SocketPermission(panel.getCodeBase().getHost(), "connect"); + + for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) { + AppletPanel p = (AppletPanel)e.nextElement(); + if (p.getDocumentBase().equals(panel.getDocumentBase())) { + + SocketPermission sp = + new SocketPermission(p.getCodeBase().getHost(), "connect"); + if (panelSp.implies(sp)) { + v.addElement(p.applet); + } + } + } + return v.elements(); + } + + /** + * Ignore. + */ + 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 " + url + " " + 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 + 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. + } + } + + public int getWindow() { + System.out.println ("STARTING getWindow"); + PluginCallRequest request = requestFactory.getPluginCallRequest("window", + "instance " + identifier + " " + "GetWindow", + "JavaScriptGetWindow"); + System.out.println ("STARTING postCallRequest"); + streamhandler.postCallRequest(request); + System.out.println ("STARTING postCallRequest done"); + streamhandler.write(request.getMessage()); + try { + System.out.println ("wait request 1"); + synchronized(request) { + System.out.println ("wait request 2"); + while ((Integer) request.getObject() == 0) + request.wait(); + System.out.println ("wait request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", + e); + } + + System.out.println ("STARTING getWindow DONE"); + return (Integer) request.getObject(); + } + + // FIXME: make private, access via reflection. + public static Object getMember(int internal, String name) + { + AppletSecurityContextManager.getSecurityContext(0).store(name); + int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("member", + "instance " + 0 + " GetMember " + internal + " " + nameID, + "JavaScriptGetMember"); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + System.err.println ("wait getMEM request 1"); + synchronized(request) { + System.err.println ("wait getMEM request 2"); + while (request.isDone() == false) + request.wait(); + System.err.println ("wait getMEM request 3 GOT: " + request.getObject().getClass()); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", + e); + } + System.err.println (" getMember DONE"); + return request.getObject(); + } + + public static void setMember(int internal, String name, Object value) { + AppletSecurityContextManager.getSecurityContext(0).store(name); + int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); + AppletSecurityContextManager.getSecurityContext(0).store(value); + int valueID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value); + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("void", + "instance " + 0 + " SetMember " + internal + " " + nameID + " " + valueID, + "JavaScriptSetMember"); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + System.out.println ("wait setMem request: " + request.getMessage()); + System.out.println ("wait setMem request 1"); + synchronized(request) { + System.out.println ("wait setMem request 2"); + while (request.isDone() == false) + request.wait(); + System.out.println ("wait setMem request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", + e); + } + System.out.println (" setMember DONE"); + } + + // FIXME: handle long index as well. + public static void setSlot(int internal, int index, Object value) { + AppletSecurityContextManager.getSecurityContext(0).store(value); + int valueID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value); + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("void", + "instance " + 0 + " SetSlot " + internal + " " + index + " " + valueID, + "JavaScriptSetSlot"); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + System.out.println ("wait setSlot request 1"); + synchronized(request) { + System.out.println ("wait setSlot request 2"); + while (request.isDone() == false) + request.wait(); + System.out.println ("wait setSlot request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", + e); + } + System.out.println (" setSlot DONE"); + } + + public static Object getSlot(int internal, int index) + { + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("member", + "instance " + 0 + " GetSlot " + internal + " " + index, + "JavaScriptGetSlot"); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + System.out.println ("wait getSlot request 1"); + synchronized(request) { + System.out.println ("wait getSlot request 2"); + while (request.isDone() == false) + request.wait(); + System.out.println ("wait getSlot request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", + e); + } + System.out.println (" getSlot DONE"); + return request.getObject(); + } + + public static Object eval(int internal, String s) + { + AppletSecurityContextManager.getSecurityContext(0).store(s); + int stringID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(s); + // Prefix with dummy instance for convenience. + // FIXME: rename GetMemberPluginCallRequest ObjectPluginCallRequest. + PluginCallRequest request = requestFactory.getPluginCallRequest("member", + "instance " + 0 + " Eval " + internal + " " + stringID, + "JavaScriptEval"); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + System.out.println ("wait eval request 1"); + synchronized(request) { + System.out.println ("wait eval request 2"); + while (request.isDone() == false) + request.wait(); + System.out.println ("wait eval request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", + e); + } + System.out.println (" getSlot DONE"); + return request.getObject(); + } + + public static void removeMember (int internal, String name) { + AppletSecurityContextManager.getSecurityContext(0).store(name); + int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("void", + "instance " + 0 + " RemoveMember " + internal + " " + nameID, + "JavaScriptRemoveMember"); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + System.out.println ("wait removeMember request 1"); + synchronized(request) { + System.out.println ("wait removeMember request 2"); + while (request.isDone() == false) + request.wait(); + System.out.println ("wait removeMember request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", + e); + } + System.out.println (" RemoveMember DONE"); + } + + public static Object call(int 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); + AppletSecurityContextManager.getSecurityContext(0).store(args); + int argsID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(args); + + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("member", + "instance " + 0 + " Call " + internal + " " + nameID + " " + argsID, + "JavaScriptCall"); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + System.out.println ("wait call request 1"); + synchronized(request) { + System.out.println ("wait call request 2"); + while (request.isDone() == false) + request.wait(); + System.out.println ("wait call request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", + e); + } + System.out.println (" Call DONE"); + return request.getObject(); + } + + public static void JavaScriptFinalize(int internal) + { + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("void", + "instance " + 0 + " Finalize " + internal, + "JavaScriptFinalize"); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + System.out.println ("wait finalize request 1"); + synchronized(request) { + System.out.println ("wait finalize request 2"); + while (request.isDone() == false) + request.wait(); + System.out.println ("wait finalize request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", + e); + } + System.out.println (" finalize DONE"); + } + + public static String javascriptToString(int internal) + { + // Prefix with dummy instance for convenience. + PluginCallRequest request = requestFactory.getPluginCallRequest("member", + "instance " + 0 + " ToString " + internal, + "JavaScriptToString"); + streamhandler.postCallRequest(request); + streamhandler.write(request.getMessage()); + try { + System.out.println ("wait ToString request 1"); + synchronized(request) { + System.out.println ("wait ToString request 2"); + while (request.isDone() == false) + request.wait(); + System.out.println ("wait ToString request 3"); + } + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted waiting for call request.", + e); + } + System.out.println (" ToString DONE"); + return (String) request.getObject(); + } + + // FIXME: make this private and access it from JSObject using + // reflection. + private void write(String message) throws IOException { + System.err.println ("WRITING 2: " + "instance " + identifier + " " + message); + streamhandler.write("instance " + identifier + " " + message); + System.err.println ("WRITING 2 DONE"); + } + + public void setStream(String key, InputStream stream)throws IOException{ + // We do nothing. + } + + public InputStream getStream(String key){ + // We do nothing. + return null; + } + + public Iterator getStreamKeys(){ + // We do nothing. + return null; + } + + /** + * System parameters. + */ + static Hashtable systemParam = new Hashtable(); + + static { + systemParam.put("codebase", "codebase"); + systemParam.put("code", "code"); + systemParam.put("alt", "alt"); + systemParam.put("width", "width"); + systemParam.put("height", "height"); + systemParam.put("align", "align"); + systemParam.put("vspace", "vspace"); + systemParam.put("hspace", "hspace"); + } + + /** + * Print the HTML tag. + */ + public static void printTag(PrintStream out, Hashtable atts) { + out.print("<applet"); + + String v = (String)atts.get("codebase"); + if (v != null) { + out.print(" codebase=\"" + v + "\""); + } + + v = (String)atts.get("code"); + if (v == null) { + v = "applet.class"; + } + out.print(" code=\"" + v + "\""); + v = (String)atts.get("width"); + if (v == null) { + v = "150"; + } + out.print(" width=" + v); + + v = (String)atts.get("height"); + if (v == null) { + v = "100"; + } + out.print(" height=" + v); + + v = (String)atts.get("name"); + if (v != null) { + out.print(" name=\"" + v + "\""); + } + out.println(">"); + + // A very slow sorting algorithm + int len = atts.size(); + String params[] = new String[len]; + len = 0; + for (Enumeration e = atts.keys() ; e.hasMoreElements() ;) { + String param = (String)e.nextElement(); + int i = 0; + for (; i < len ; i++) { + if (params[i].compareTo(param) >= 0) { + break; + } + } + System.arraycopy(params, i, params, i + 1, len - i); + params[i] = param; + len++; + } + + for (int i = 0 ; i < len ; i++) { + String param = params[i]; + if (systemParam.get(param) == null) { + out.println("<param name=" + param + + " value=\"" + atts.get(param) + "\">"); + } + } + out.println("</applet>"); + } + + /** + * Make sure the atrributes are uptodate. + */ + public void updateAtts() { + Dimension d = panel.size(); + Insets in = panel.insets(); + panel.atts.put("width", + new Integer(d.width - (in.left + in.right)).toString()); + panel.atts.put("height", + new Integer(d.height - (in.top + in.bottom)).toString()); + } + + /** + * Restart the applet. + */ + 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() { + public Object 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() + { + appletShutdown(p); + appletPanels.removeElement(p); + dispose(); + + if (countApplets() == 0) { + appletSystemExit(); + } + } + }).start(); + } + + /** + * Exit the program. + * Exit from the program (if not stand alone) - do no clean-up + */ + private void appletSystemExit() { + if (factory.isStandalone()) + System.exit(0); + } + + /** + * How many applets are running? + */ + + public static int countApplets() { + return appletPanels.size(); + } + + + /** + * The current character. + */ + static int c; + + /** + * Scan spaces. + */ + public static void skipSpace(Reader in) throws IOException { + while ((c >= 0) && + ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'))) { + c = in.read(); + } + } + + /** + * Scan identifier + */ + public static String scanIdentifier(Reader in) throws IOException { + StringBuffer buf = new StringBuffer(); + while (true) { + if (((c >= 'a') && (c <= 'z')) || + ((c >= 'A') && (c <= 'Z')) || + ((c >= '0') && (c <= '9')) || (c == '_')) { + buf.append((char)c); + c = in.read(); + } else { + return buf.toString(); + } + } + } + + /** + * Scan tag + */ + public static Hashtable scanTag(Reader in) throws IOException { + Hashtable atts = new Hashtable(); + skipSpace(in); + while (c >= 0 && c != '>') { + String att = scanIdentifier(in); + String val = ""; + skipSpace(in); + if (c == '=') { + int quote = -1; + c = in.read(); + skipSpace(in); + if ((c == '\'') || (c == '\"')) { + quote = c; + c = in.read(); + } + StringBuffer buf = new StringBuffer(); + while ((c > 0) && + (((quote < 0) && (c != ' ') && (c != '\t') && + (c != '\n') && (c != '\r') && (c != '>')) + || ((quote >= 0) && (c != quote)))) { + buf.append((char)c); + c = in.read(); + } + if (c == quote) { + c = in.read(); + } + skipSpace(in); + val = buf.toString(); + } + System.err.println("PUT " + att + " = '" + val + "'"); + if (! val.equals("")) { + atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val); + } + while (true) { + if ((c == '>') || (c < 0) || + ((c >= 'a') && (c <= 'z')) || + ((c >= 'A') && (c <= 'Z')) || + ((c >= '0') && (c <= '9')) || (c == '_')) + break; + c = in.read(); + } + //skipSpace(in); + } + return atts; + } + + /* values used for placement of AppletViewer's frames */ + private static int x = 0; + private static int y = 0; + private static final int XDELTA = 30; + private static final int YDELTA = XDELTA; + + static String encoding = null; + + static private Reader makeReader(InputStream is) { + if (encoding != null) { + try { + return new BufferedReader(new InputStreamReader(is, encoding)); + } catch (IOException x) { } + } + InputStreamReader r = new InputStreamReader(is); + encoding = r.getEncoding(); + return new BufferedReader(r); + } + + /** + * Scan an html file for <applet> tags + */ + public static void parse(int identifier, long handle, Reader in, URL url, String enc) + throws IOException { + encoding = enc; + parse(identifier, handle, in, url, System.out, new PluginAppletViewerFactory()); + } + + public static void parse(int identifier, long handle, Reader in, URL url) + throws IOException { + final int fIdentifier = identifier; + final long fHandle = handle; + final Reader fIn = in; + final URL fUrl = url; + PrivilegedAction pa = new PrivilegedAction() { + public Object run() { + try { + parse(fIdentifier, fHandle, fIn, fUrl, System.out, new PluginAppletViewerFactory()); + } catch (IOException ioe) { + return ioe; + } + + return null; + } + }; + + Object ret = AccessController.doPrivileged(pa); + if (ret instanceof IOException) { + throw (IOException) ret; + } + } + + public static void parse(int identifier, long handle, Reader in, URL url, + PrintStream statusMsgStream, + PluginAppletViewerFactory factory) + throws IOException + { + // <OBJECT> <EMBED> tag flags + boolean isAppletTag = false; + boolean isObjectTag = false; + boolean isEmbedTag = false; + + // warning messages + String requiresNameWarning = amh.getMessage("parse.warning.requiresname"); + String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside"); + String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode"); + String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight"); + String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth"); + String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode"); + String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight"); + String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth"); + String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode"); + String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight"); + String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth"); + String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported"); + + java.net.URLConnection conn = url.openConnection(); + /* The original URL may have been redirected - this + * sets it to whatever URL/codebase we ended up getting + */ + url = conn.getURL(); + + int ydisp = 1; + Hashtable atts = null; + + while(true) { + c = in.read(); + if (c == -1) + break; + + if (c == '<') { + c = in.read(); + if (c == '/') { + c = in.read(); + String nm = scanIdentifier(in); + if (nm.equalsIgnoreCase("applet") || + nm.equalsIgnoreCase("object") || + nm.equalsIgnoreCase("embed")) { + + // We can't test for a code tag until </OBJECT> + // because it is a parameter, not an attribute. + if(isObjectTag) { + if (atts.get("code") == null && atts.get("object") == null) { + statusMsgStream.println(objectRequiresCodeWarning); + atts = null; + } + } + + if (atts != null) { + // XXX 5/18 In general this code just simply + // shouldn't be part of parsing. It's presence + // causes things to be a little too much of a + // hack. + factory.createAppletViewer(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(in); + if (nm.equalsIgnoreCase("param")) { + Hashtable t = scanTag(in); + String att = (String)t.get("name"); + if (att == null) { + statusMsgStream.println(requiresNameWarning); + } else { + String val = (String)t.get("value"); + if (val == null) { + statusMsgStream.println(requiresNameWarning); + } else if (atts != null) { + atts.put(att.toLowerCase(), val); + } else { + statusMsgStream.println(paramOutsideWarning); + } + } + } + else if (nm.equalsIgnoreCase("applet")) { + isAppletTag = true; + atts = scanTag(in); + + // If there is a classid present, transform it to code tag + if (atts.get("code") == null && atts.get("classid") != null && + ((String) atts.get("classid")).startsWith("java:")) { + //skip "java:" + atts.put("code", ((String) atts.get("classid")).substring(5)); + } + + if (atts.get("code") == null && atts.get("object") == null) { + statusMsgStream.println(appletRequiresCodeWarning); + atts = null; + } + + if (atts.get("width") == null) { + atts.put("width", "100%"); + } + + if (atts.get("height") == null) { + atts.put("height", "100%"); + } + } + else if (nm.equalsIgnoreCase("object")) { + isObjectTag = true; + atts = scanTag(in); + + // If there is a classid present, transform it to code tag + if (atts.get("code") == null && atts.get("classid") != null && + ((String) atts.get("classid")).startsWith("java:")) { + //skip "java:" + atts.put("code", ((String) atts.get("classid")).substring(5)); + } + + // The <OBJECT> attribute codebase isn't what + // we want when not dealing with jars. If its + // defined, remove it in that case. + if(atts.get("archive") == null && atts.get("codebase") != null) { + atts.remove("codebase"); + } + + if (atts.get("width") == null) { + atts.put("width", "100%"); + } + + if (atts.get("height") == null) { + atts.put("height", "100%"); + } + } + else if (nm.equalsIgnoreCase("embed")) { + isEmbedTag = true; + atts = scanTag(in); + + // If there is a classid present, transform it to code tag + if (atts.get("code") == null && atts.get("classid") != null && + ((String) atts.get("classid")).startsWith("java:")) { + //skip "java:" + atts.put("code", ((String) atts.get("classid")).substring(5)); + } + + if (atts.get("code") == null && atts.get("object") == null) { + statusMsgStream.println(embedRequiresCodeWarning); + atts = null; + } + + if (atts.get("width") == null) { + atts.put("width", "100%"); + } + + if (atts.get("height") == null) { + atts.put("height", "100%"); + } + } + else if (nm.equalsIgnoreCase("app")) { + statusMsgStream.println(appNotLongerSupportedWarning); + Hashtable atts2 = scanTag(in); + nm = (String)atts2.get("class"); + if (nm != null) { + atts2.remove("class"); + atts2.put("code", nm + ".class"); + } + nm = (String)atts2.get("src"); + if (nm != null) { + atts2.remove("src"); + atts2.put("codebase", nm); + } + if (atts2.get("width") == null) { + atts2.put("width", "100%"); + } + if (atts2.get("height") == null) { + atts2.put("height", "100%"); + } + printTag(statusMsgStream, atts2); + statusMsgStream.println(); + } + } + } + } + in.close(); + } + + + 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()); + } + } + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginCallRequest.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,85 @@ +/* PluginCallRequest -- represent Java-to-JavaScript requests + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package sun.applet; + +import java.security.AccessControlContext; +import java.security.ProtectionDomain; + +// FIXME: for each type of request extend a new (anonymous?) +// PluginCallRequest. +public abstract class PluginCallRequest { + String message; + String returnString; + PluginCallRequest next; + boolean done = false; + + public PluginCallRequest(String message, String returnString) { + this.message = message; + this.returnString = returnString; + } + + public String getMessage() { + return this.message; + } + + public String getReturnString() { + return this.returnString; + } + + public boolean isDone() { + return this.done; + } + + public boolean setDone(boolean done) { + return this.done = done; + } + + public void setNext(PluginCallRequest next) { + this.next = next; + } + + public PluginCallRequest getNext() { + return this.next; + } + + public abstract void parseReturn(String message); + + public abstract boolean serviceable(String message); + + public abstract Object getObject(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginCallRequestFactory.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,7 @@ +package sun.applet; + +public interface PluginCallRequestFactory { + + public PluginCallRequest getPluginCallRequest(String id, String message, String returnString); + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginClassLoader.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,13 @@ +package sun.applet; + +public class PluginClassLoader extends ClassLoader { + + public PluginClassLoader() { + super(); + } + + public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { + return super.loadClass(name, resolve); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginDebug.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,13 @@ +package sun.applet; + +import java.io.*; + +public class PluginDebug { + + static final boolean DEBUG = true; + + public static void debug(String message) { + if (DEBUG) + System.err.println(message); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginException.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,15 @@ +package sun.applet; + + +public class PluginException extends Exception { + + public PluginException (PluginStreamHandler sh, int instance, int reference, Throwable t) { + t.printStackTrace(); + this.setStackTrace(t.getStackTrace()); + + AppletSecurityContextManager.dumpStore(0); + + String message = "instance " + instance + " reference " + reference + " Error " + t.getMessage(); + sh.write(message); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginStreamHandler.java Tue Sep 23 16:52:24 2008 -0400 @@ -0,0 +1,20 @@ +package sun.applet; + + +public interface PluginStreamHandler { + + public void postMessage(String s); + + public void handleMessage(String message) throws PluginException; + + public void postCallRequest(PluginCallRequest request); + + public void write(String message); + + public boolean messageAvailable(); + + public String getMessage(); + + public void startProcessing(); + +} \ No newline at end of file