aboutsummaryrefslogtreecommitdiffstats
path: root/plugin/icedteanp
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/icedteanp')
-rw-r--r--plugin/icedteanp/java-awt/sun/applet/PluginAppletPanelFactory.java (renamed from plugin/icedteanp/java/sun/applet/PluginAppletPanelFactory.java)0
-rw-r--r--plugin/icedteanp/java-awt/sun/applet/PluginAppletViewer.java (renamed from plugin/icedteanp/java/sun/applet/PluginAppletViewer.java)0
-rw-r--r--plugin/icedteanp/java/jogamp/plugin/applet/PluginApplet3PanelFactory.java229
-rw-r--r--plugin/icedteanp/java/jogamp/plugin/applet/PluginApplet3Viewer.java1423
-rw-r--r--plugin/icedteanp/java/netscape/javascript/JSObject.java23
-rw-r--r--plugin/icedteanp/java/sun/applet/Applet3MessageHandler.java21
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginCookieManager.java5
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginMain.java15
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginMessageConsumer.java2
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java2
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginParameterParser.java2
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginProxySelector.java4
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginStreamHandler.java6
13 files changed, 1707 insertions, 25 deletions
diff --git a/plugin/icedteanp/java/sun/applet/PluginAppletPanelFactory.java b/plugin/icedteanp/java-awt/sun/applet/PluginAppletPanelFactory.java
index 429cb62..429cb62 100644
--- a/plugin/icedteanp/java/sun/applet/PluginAppletPanelFactory.java
+++ b/plugin/icedteanp/java-awt/sun/applet/PluginAppletPanelFactory.java
diff --git a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java b/plugin/icedteanp/java-awt/sun/applet/PluginAppletViewer.java
index 8d1630d..8d1630d 100644
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
+++ b/plugin/icedteanp/java-awt/sun/applet/PluginAppletViewer.java
diff --git a/plugin/icedteanp/java/jogamp/plugin/applet/PluginApplet3PanelFactory.java b/plugin/icedteanp/java/jogamp/plugin/applet/PluginApplet3PanelFactory.java
new file mode 100644
index 0000000..2c9040c
--- /dev/null
+++ b/plugin/icedteanp/java/jogamp/plugin/applet/PluginApplet3PanelFactory.java
@@ -0,0 +1,229 @@
+/* Copyright (C) 2012 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. */
+
+/*
+ * 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 jogamp.plugin.applet;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import jogamp.applet.Applet3Panel;
+import jogamp.plugin.jnlp.NetxApplet3Panel;
+import net.sourceforge.jnlp.PluginParameters;
+import net.sourceforge.jnlp.util.logging.OutputController;
+import sun.applet.AppletPanel;
+import sun.applet.AppletSecurityContextManager;
+import sun.applet.PluginDebug;
+import sun.applet.PluginStreamHandler;
+
+import com.jogamp.plugin.applet.Applet3;
+
+/**
+ * Lets us construct one using unix-style one shot behaviors
+ */
+
+public class PluginApplet3PanelFactory {
+
+ public Applet3Panel createPanel(PluginStreamHandler streamhandler,
+ final int identifier,
+ final long nativeWindowHandle,
+ final URL doc,
+ final PluginParameters params) {
+ final int width = params.getWidth();
+ final int height = params.getHeight();
+ PluginDebug.debug("NativeWindow (Browser) Handle: 0x" + Long.toHexString(nativeWindowHandle));
+ PluginDebug.debug("NativeWindow (Browser) Size: " + width + " x " + height);
+ final NetxApplet3Panel panel = AccessController.doPrivileged(new PrivilegedAction<NetxApplet3Panel>() {
+ @Override
+ public NetxApplet3Panel run() {
+ NetxApplet3Panel panel = new NetxApplet3Panel(nativeWindowHandle, width, height, doc, params);
+ NetxApplet3Panel.debug("Using NetX panel");
+ PluginDebug.debug(params.toString());
+ return panel;
+ }
+ });
+
+ // Framing the panel needs to happen in a thread whose thread group
+ // is the same as the threadgroup of the applet thread. If this
+ // isn't the case, the awt eventqueue thread's context classloader
+ // won't be set to a JNLPClassLoader, and when an applet class needs
+ // to be loaded from the awt eventqueue, it won't be found.
+ Thread panelInit = new Thread(panel.getThreadGroup(), new Runnable() {
+ @Override public void run() {
+ panel.createNewAppContext();
+ // create the frame.
+ final PluginApplet3Viewer pav = PluginApplet3Viewer.framePanel(identifier, panel);
+ panel.setAppletViewerFrame(pav);
+ panel.setAppletContext(pav);
+
+ panel.init();
+ // Start the applet
+ initEventQueue(panel);
+ }
+ }, "NetXPanel initializer");
+
+ panelInit.start();
+ try {
+ panelInit.join();
+ } catch (InterruptedException e) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e);
+ }
+
+ setAppletViewerSize(panel, params.getWidth(), params.getHeight());
+
+ // Wait for the panel to initialize
+ PluginApplet3Viewer.waitForAppletInit(panel);
+
+ Applet3 a = panel.getApplet();
+
+ // Still null?
+ if (a == null) {
+ streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError: " + "Initialization timed out");
+ return null;
+ }
+
+ PluginDebug.debug("Applet ", a.getClass(), " initialized");
+ streamhandler.write("instance " + identifier + " reference 0 initialized");
+
+ panel.removeSplash();
+
+ AppletSecurityContextManager.getSecurityContext(0).associateSrc(panel.getAppletClassLoader(), doc);
+ AppletSecurityContextManager.getSecurityContext(0).associateInstance(identifier, panel.getAppletClassLoader());
+
+ return panel;
+ }
+
+ /* AppletViewerPanel sometimes doesn't set size right initially. This
+ * causes the parent frame to be the default (10x10) size.
+ *
+ * Normally it goes unnoticed since browsers like Firefox make a resize
+ * call after init. However some browsers (e.g. Midori) don't.
+ *
+ * We therefore manually set the parent to the right size.
+ */
+ static private void setAppletViewerSize(final Applet3Panel panel,
+ final int width, final int height) {
+ try {
+ panel.resize(width, height);
+ } catch (Exception e) {
+ // Not being able to resize is non-fatal
+ PluginDebug.debug("Unable to resize panel: ");
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e);
+ }
+ }
+ /**
+ * 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(Applet3Panel panel) {
+ // appletviewer.send.event is an undocumented and unsupported system
+ // property which is used exclusively for testing purposes.
+ PrivilegedAction<String> pa = new PrivilegedAction<String>() {
+ @Override
+ public String run() {
+ return System.getProperty("appletviewer.send.event");
+ }
+ };
+ String eventList = AccessController.doPrivileged(pa);
+
+ if (eventList == null) {
+ // Add the standard events onto the event queue.
+ panel.sendEvent(AppletPanel.APPLET_LOAD);
+ panel.sendEvent(AppletPanel.APPLET_INIT);
+ panel.sendEvent(AppletPanel.APPLET_START);
+ } else {
+ // We're testing AppletViewer. Force the specified set of events
+ // onto the event queue, wait for the events to be processed, and
+ // exit.
+
+ // The list of events that will be executed is provided as a
+ // ","-separated list. No error-checking will be done on the list.
+ String[] events = eventList.split(",");
+
+ for (String event : events) {
+ PluginDebug.debug("Adding event to queue: ", event);
+ if ("dispose".equals(event))
+ panel.sendEvent(AppletPanel.APPLET_DISPOSE);
+ else if ("load".equals(event))
+ panel.sendEvent(AppletPanel.APPLET_LOAD);
+ else if ("init".equals(event))
+ panel.sendEvent(AppletPanel.APPLET_INIT);
+ else if ("start".equals(event))
+ panel.sendEvent(AppletPanel.APPLET_START);
+ else if ("stop".equals(event))
+ panel.sendEvent(AppletPanel.APPLET_STOP);
+ else if ("destroy".equals(event))
+ panel.sendEvent(AppletPanel.APPLET_DESTROY);
+ else if ("quit".equals(event))
+ panel.sendEvent(AppletPanel.APPLET_QUIT);
+ else if ("error".equals(event))
+ panel.sendEvent(AppletPanel.APPLET_ERROR);
+ else
+ // non-fatal error if we get an unrecognized event
+ PluginDebug.debug("Unrecognized event name: ", event);
+ }
+
+ while (!panel.emptyEventQueue())
+ ;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugin/icedteanp/java/jogamp/plugin/applet/PluginApplet3Viewer.java b/plugin/icedteanp/java/jogamp/plugin/applet/PluginApplet3Viewer.java
new file mode 100644
index 0000000..338ce42
--- /dev/null
+++ b/plugin/icedteanp/java/jogamp/plugin/applet/PluginApplet3Viewer.java
@@ -0,0 +1,1423 @@
+/* PluginAppletViewer -- Handles embedding of the applet panel
+ 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. */
+
+/*
+ * 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 jogamp.plugin.applet;
+
+import static net.sourceforge.jnlp.runtime.Translator.R;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.SocketPermission;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.AccessController;
+import java.security.AllPermission;
+import java.security.PrivilegedAction;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+import jogamp.applet.App3Context;
+import jogamp.applet.Applet3Panel;
+import jogamp.plugin.jnlp.NetxApplet3Panel;
+import net.sourceforge.jnlp.LaunchException;
+import net.sourceforge.jnlp.PluginParameters;
+import net.sourceforge.jnlp.runtime.JNLPClassLoader;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityLevel;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletStartupSecuritySettings;
+import net.sourceforge.jnlp.splashscreen.SplashController;
+import net.sourceforge.jnlp.splashscreen.SplashPanel;
+import net.sourceforge.jnlp.splashscreen.SplashUtils;
+import net.sourceforge.jnlp.util.logging.OutputController;
+import sun.applet.Applet3MessageHandler;
+import sun.applet.AppletEvent;
+import sun.applet.AppletListener;
+import sun.applet.AppletPanel;
+import sun.applet.AppletSecurityContextManager;
+import sun.applet.PluginAppletSecurityContext;
+import sun.applet.PluginCallRequest;
+import sun.applet.PluginCallRequestFactory;
+import sun.applet.PluginDebug;
+import sun.applet.PluginMessageConsumer;
+import sun.applet.PluginParameterParser;
+import sun.applet.PluginStreamHandler;
+
+import com.jogamp.plugin.applet.Applet3;
+import com.jogamp.plugin.applet.Applet3Context;
+import com.sun.jndi.toolkit.url.UrlUtil;
+
+/*
+ */
+// FIXME: declare JSProxy implementation
+public class PluginApplet3Viewer implements Applet3Context, SplashController {
+
+ /**
+ * Enumerates the current status of an applet
+ *
+ * PRE_INIT -> Parsing and initialization phase
+ * INIT_COMPLETE -> Initialization complete, reframe pending
+ * REFRAME_COMPLETE -> Reframe complete, applet is initialized and usable by the user
+ * INACTIVE -> Browser has directed that the applet be destroyed (this state is non-overridable except by DESTROYED)
+ * DESTROYED -> Applet has been destroyed
+ */
+ private static enum PAV_INIT_STATUS {
+ PRE_INIT, INIT_COMPLETE, REFRAME_COMPLETE, INACTIVE, DESTROYED
+ };
+
+ /**
+ * The panel in which the applet is being displayed.
+ */
+ private final NetxApplet3Panel panel;
+ static final ReentrantLock panelLock = new ReentrantLock();
+ // CONDITION PREDICATE: panel.isAlive()
+ static final Condition panelLive = panelLock.newCondition();
+ private int identifier;
+
+ // Instance identifier -> PluginAppletViewer object.
+ private static ConcurrentMap<Integer, PluginApplet3Viewer> applets =
+ new ConcurrentHashMap<Integer, PluginApplet3Viewer>();
+ private static final ReentrantLock appletsLock = new ReentrantLock();
+ // CONDITION PREDICATE: !applets.containsKey(identifier)
+ private static final Condition appletAdded = appletsLock.newCondition();
+
+ private static PluginStreamHandler streamhandler;
+
+ private static PluginCallRequestFactory requestFactory;
+
+ private static ConcurrentMap<Integer, PAV_INIT_STATUS> status =
+ new ConcurrentHashMap<Integer, PAV_INIT_STATUS>();
+ private static final ReentrantLock statusLock = new ReentrantLock();
+ // CONDITION PREDICATE: !status.get(identifier).equals(PAV_INIT_STATUS.INIT_COMPLETE)
+ private static final Condition initComplete = statusLock.newCondition();
+
+ private AppletEventListener appletEventListener = null;
+
+ public static final long APPLET_TIMEOUT = 180000000000L; // 180s in ns
+
+ private static final Object requestMutex = new Object();
+ private static long requestIdentityCounter = 0L;
+
+ private SplashPanel splashPanel;
+
+ private static long REQUEST_TIMEOUT=60000;//60s
+
+ private static void waitForRequestCompletion(PluginCallRequest request) {
+ try {
+ if (!request.isDone()) {
+ request.wait(REQUEST_TIMEOUT);
+ }
+ if (!request.isDone()) {
+ // Do not wait indefinitely to avoid the potential of deadlock
+ throw new RuntimeException("Possible deadlock, releasing");
+ }
+ } catch (InterruptedException ex) {
+ throw new RuntimeException("Interrupted waiting for call request.", ex);
+ }
+ }
+
+ /**
+ * Null constructor to allow instantiation via newInstance()
+ */
+ public PluginApplet3Viewer() {
+ panel = null;
+ }
+
+ public static PluginApplet3Viewer framePanel(int identifier, NetxApplet3Panel panel) {
+
+ PluginDebug.debug("Framing ", panel);
+
+ // SecurityManager MUST be set, and only privileged code may call framePanel()
+ System.getSecurityManager().checkPermission(new AllPermission());
+
+ PluginApplet3Viewer appletFrame = new PluginApplet3Viewer(identifier, panel);
+
+ appletFrame.appletEventListener = new AppletEventListener(appletFrame);
+ panel.addAppletListener(appletFrame.appletEventListener);
+ // Clear references, if any
+ if (applets.containsKey(identifier)) {
+ PluginApplet3Viewer oldFrame = applets.get(identifier);
+ // FIXME oldFrame.remove(panel);
+ panel.removeAppletListener(oldFrame.appletEventListener);
+ }
+
+ appletsLock.lock();
+ applets.put(identifier, appletFrame);
+ appletAdded.signalAll();
+ appletsLock.unlock();
+
+ PluginDebug.debug(panel, " framed");
+ return appletFrame;
+ }
+
+ /**
+ * Create new plugin appletviewer frame
+ */
+ private PluginApplet3Viewer(final int identifier, NetxApplet3Panel appletPanel) {
+ this.identifier = identifier;
+ this.panel = appletPanel;
+
+ synchronized(appletPanels) {
+ if (!appletPanels.contains(panel))
+ appletPanels.addElement(panel);
+ }
+
+ /** FIXME
+ windowEventListener = new WindowAdapter() {
+
+ @Override
+ public void windowClosing(WindowEvent evt) {
+ destroyApplet(identifier);
+ }
+
+ @Override
+ public void windowIconified(WindowEvent evt) {
+ appletStop();
+ }
+
+ @Override
+ public void windowDeiconified(WindowEvent evt) {
+ appletStart();
+ }
+ };
+ addWindowListener(windowEventListener);
+ */
+ new SplashCreator(panel);
+ }
+
+ /** Called by {@link SplashCreator#run()} */
+ private void initializeViewAndSlash(final Applet3Panel fPanel) {
+ }
+
+ @Override
+ public void replaceSplash(final SplashPanel newSplash) {
+ }
+
+ @Override
+ public void removeSplash() {
+ }
+
+ @Override
+ public int getSplashWidth() {
+ if (splashPanel != null) {
+ return splashPanel.getSplashWidth();
+ } else {
+ return -1;
+ }
+ }
+
+ @Override
+ public int getSplashHeigth() {
+ if (splashPanel != null) {
+ return splashPanel.getSplashHeight();
+ } else {
+ return -1;
+ }
+ }
+
+ private static class AppletEventListener implements AppletListener {
+ final PluginApplet3Viewer appletViewer;
+
+ public AppletEventListener(PluginApplet3Viewer appletViewer) {
+ this.appletViewer = appletViewer;
+ }
+
+ @Override
+ public void appletStateChanged(AppletEvent evt) {
+ Applet3Panel src = (Applet3Panel) evt.getSource();
+
+ panelLock.lock();
+ panelLive.signalAll();
+ panelLock.unlock();
+ switch (evt.getID()) {
+ case AppletPanel.APPLET_RESIZE: {
+ if (src != null) {
+ // FIXME ? appletViewer.setSize(appletViewer.getPreferredSize());
+ // We already resized ..
+ }
+ break;
+ }
+ case AppletPanel.APPLET_LOADING_COMPLETED: {
+ /**
+ Applet3 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) {
+ Applet3Panel.changeFrameAppContext(src.appletWindow, SunToolkit.targetToAppContext(a));
+ }
+ else */ {
+ Applet3Panel.changeFrameAppContext(src.getAppletWindow(), App3Context.getAppContext());
+ }
+
+ updateStatus(appletViewer.identifier, PAV_INIT_STATUS.INIT_COMPLETE);
+
+ break;
+ }
+ case AppletPanel.APPLET_START: {
+ final int src_status = src.getStatus();
+ if (src_status != AppletPanel.APPLET_INIT && src_status != AppletPanel.APPLET_STOP) {
+ String s="Applet started, but but reached invalid state";
+ PluginDebug.debug(s);
+ SplashPanel sp=SplashUtils.getErrorSplashScreen(appletViewer.panel.getWidth(), appletViewer.panel.getHeight(), new Exception(s));
+ appletViewer.replaceSplash(sp);
+ }
+
+ break;
+ }
+ case AppletPanel.APPLET_ERROR: {
+ String s="Undefined error causing applet not to staart appeared";
+ PluginDebug.debug(s);
+ SplashPanel sp=SplashUtils.getErrorSplashScreen(appletViewer.panel.getWidth(), appletViewer.panel.getHeight(), new Exception(s));
+ appletViewer.replaceSplash(sp);
+ break;
+ }
+ }
+ }
+ }
+
+ public static void setStreamhandler(PluginStreamHandler sh) {
+ streamhandler = sh;
+ }
+
+ public static void setPluginCallRequestFactory(PluginCallRequestFactory rf) {
+ requestFactory = rf;
+ }
+
+ private static void handleInitializationMessage(int identifier, String message) throws IOException, LaunchException {
+
+ /* The user has specified via a global setting that applets should not be run.*/
+ if (AppletStartupSecuritySettings.getInstance().getSecurityLevel() == AppletSecurityLevel.DENY_ALL) {
+ throw new LaunchException(null, null, R("LSFatal"), R("LCClient"), R("LUnsignedApplet"), R("LUnsignedAppletPolicyDenied"));
+ }
+
+ // If there is a key for this status, it means it
+ // was either initialized before, or destroy has been
+ // processed. Stop moving further.
+ if (updateStatus(identifier, PAV_INIT_STATUS.PRE_INIT) != null) {
+ return;
+ }
+
+ // Extract the information from the message
+ String[] msgParts = new String[4];
+ for (int i = 0; i < 3; i++) {
+ int spaceLocation = message.indexOf(' ');
+ int nextSpaceLocation = message.indexOf(' ', spaceLocation + 1);
+ msgParts[i] = message.substring(spaceLocation + 1, nextSpaceLocation);
+ message = message.substring(nextSpaceLocation + 1);
+ }
+
+ final long nativeWindowHandle = Long.parseLong(msgParts[0]);
+ String width = msgParts[1];
+ String height = msgParts[2];
+
+ int spaceLocation = message.indexOf(' ', "tag".length() + 1);
+ String documentBase = message.substring("tag".length() + 1, spaceLocation);
+ String paramString = message.substring(spaceLocation + 1);
+
+ PluginDebug.debug("Handle = 0x", Long.toHexString(nativeWindowHandle), "\n",
+ "Width = ", width, "\n",
+ "Height = ", height, "\n",
+ "DocumentBase = ", documentBase, "\n",
+ "Params = ", paramString);
+
+ PluginApplet3PanelFactory factory = new PluginApplet3PanelFactory();
+ Applet3MessageHandler amh = new Applet3MessageHandler("appletviewer");
+ URL url = new URL(documentBase);
+ 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();
+
+ PluginParameters params = new PluginParameterParser().parse(width, height, paramString);
+
+ // Let user know we are starting up
+ streamhandler.write("instance " + identifier + " status " + amh.getMessage("status.start"));
+ factory.createPanel(streamhandler, identifier, nativeWindowHandle, url, params);
+
+ long maxTimeToSleep = APPLET_TIMEOUT;
+ appletsLock.lock();
+ try {
+ while (!applets.containsKey(identifier) &&
+ maxTimeToSleep > 0) { // Map is populated only by reFrame
+ maxTimeToSleep -= waitTillTimeout(appletsLock, appletAdded,
+ maxTimeToSleep);
+ }
+ }
+ finally {
+ appletsLock.unlock();
+ }
+
+ // If wait exceeded maxWait, we timed out. Throw an exception
+ if (maxTimeToSleep <= 0) {
+ // Caught in handleMessage
+ throw new RuntimeException("Applet initialization timeout");
+ }
+
+ // We should not try to destroy an applet during
+ // initialization. It may cause an inconsistent state,
+ // which would bad if it's a trusted applet that
+ // read/writes to files
+ waitForAppletInit(applets.get(identifier).panel);
+
+ // Should we proceed with reframing?
+ PluginDebug.debug("Init complete");
+
+ if (updateStatus(identifier, PAV_INIT_STATUS.REFRAME_COMPLETE).equals(PAV_INIT_STATUS.INACTIVE)) {
+ destroyApplet(identifier);
+ return;
+ }
+ }
+
+ /**
+ * Handle an incoming message from the plugin.
+ */
+ public static void handleMessage(int identifier, int reference, String message) {
+
+ PluginDebug.debug("PAV handling: ", message);
+
+ try {
+ if (message.startsWith("handle")) {
+ handleInitializationMessage(identifier, message);
+ } else if (message.startsWith("destroy")) {
+
+ // Set it inactive, and try to do cleanup is applicable
+ PAV_INIT_STATUS previousStatus = updateStatus(identifier, PAV_INIT_STATUS.INACTIVE);
+ PluginDebug.debug("Destroy status set for ", identifier);
+
+ if (previousStatus != null &&
+ previousStatus.equals(PAV_INIT_STATUS.REFRAME_COMPLETE)) {
+ destroyApplet(identifier);
+ }
+
+ } else {
+ PluginDebug.debug("Handling message: ", message, " instance ", identifier, " ", Thread.currentThread());
+
+ // Wait till initialization finishes
+ while (!applets.containsKey(identifier) &&
+ (
+ !status.containsKey(identifier) ||
+ status.get(identifier).equals(PAV_INIT_STATUS.PRE_INIT)
+ ))
+ ;
+
+ // don't bother processing further for inactive applets
+ if (status.get(identifier).equals(PAV_INIT_STATUS.INACTIVE)) {
+ return;
+ }
+
+ applets.get(identifier).handleMessage(reference, message);
+ }
+ } catch (Exception e) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e);
+
+ // If an exception happened during pre-init, we need to update status
+ updateStatus(identifier, PAV_INIT_STATUS.INACTIVE);
+
+ e.printStackTrace(); // FIXME
+
+ throw new RuntimeException("Failed to handle message: " + message + " for instance " + identifier, e);
+ }
+ }
+
+ /**
+ * Sets the status unless an overriding status is set (e.g. if
+ * status is DESTROYED, it may not be overridden).
+ *
+ * @param identifier The identifier for which the status is to be set
+ * @param status The status to switch to
+ * @return The previous status
+ */
+ private static synchronized PAV_INIT_STATUS updateStatus(int identifier, PAV_INIT_STATUS newStatus) {
+
+ PAV_INIT_STATUS prev = status.get(identifier);
+
+ // If the status is set
+ if (status.containsKey(identifier)) {
+
+ // Nothing may override destroyed status
+ if (status.get(identifier).equals(PAV_INIT_STATUS.DESTROYED)) {
+ return prev;
+ }
+
+ // If status is inactive, only DESTROYED may override it
+ if (status.get(identifier).equals(PAV_INIT_STATUS.INACTIVE)) {
+ if (!newStatus.equals(PAV_INIT_STATUS.DESTROYED)) {
+ return prev;
+ }
+ }
+ }
+
+ // Else set to given status
+
+ statusLock.lock();
+ status.put(identifier, newStatus);
+ initComplete.signalAll();
+ statusLock.unlock();
+
+ return prev;
+ }
+
+ /**
+ * Destroys the given applet instance.
+ *
+ * This function may be called multiple times without problems.
+ * It does a synchronized check on the status and will only
+ * attempt to destroy the applet if not previously destroyed.
+ *
+ * @param identifier The instance which is to be destroyed
+ */
+
+ private static synchronized void destroyApplet(int identifier) {
+ final PluginApplet3Viewer pav = applets.get(identifier);
+
+ if( null != pav ) {
+ // We should not try to destroy an applet during
+ // initialization. It may cause an inconsistent state.
+ waitForAppletInit( pav.panel );
+ }
+
+ PluginDebug.debug("DestroyApplet called for ", identifier);
+
+ PAV_INIT_STATUS prev = updateStatus(identifier, PAV_INIT_STATUS.DESTROYED);
+
+ // If already destroyed, return
+ if (prev.equals(PAV_INIT_STATUS.DESTROYED)) {
+ PluginDebug.debug(identifier, " already destroyed. Returning.");
+ return;
+ }
+
+ PluginDebug.debug("Attempting to destroy frame ", identifier);
+
+ // Try to dispose the panel right away
+ if (pav != null) {
+ // If panel is already disposed, return
+ if (pav.panel.getApplet() == null) {
+ PluginDebug.debug(identifier, " panel inactive. Returning.");
+ return;
+ }
+
+ PluginDebug.debug("Attempting to destroy panel ", identifier);
+
+ pav.appletClose();
+ }
+
+ PluginDebug.debug(identifier, " destroyed");
+ }
+
+ /**
+ * Function to block until applet initialization is complete.
+ *
+ * This function will return if the wait is longer than {@link #APPLET_TIMEOUT}
+ *
+ * @param panel the instance to wait for.
+ */
+ public static void waitForAppletInit(NetxApplet3Panel panel) {
+
+ PluginDebug.debug("Waiting for applet init");
+
+ // Wait till initialization finishes
+ long maxTimeToSleep = APPLET_TIMEOUT;
+
+ panelLock.lock();
+ try {
+ while (!panel.isInitialized() &&
+ maxTimeToSleep > 0) {
+ PluginDebug.debug("Waiting for applet panel ", panel, " to initialize...");
+ maxTimeToSleep -= waitTillTimeout(panelLock, panelLive, maxTimeToSleep);
+ }
+ }
+ finally {
+ panelLock.unlock();
+ }
+
+ PluginDebug.debug("Applet panel ", panel, " initialized");
+ }
+
+ public void handleMessage(int reference, String message) {
+ if (message.startsWith("width")) {
+
+ // 0 => width, 1=> width_value, 2 => height, 3=> height_value
+ String[] dimMsg = message.split(" ");
+
+ final int width = Integer.parseInt(dimMsg[1]);
+ final int height = Integer.parseInt(dimMsg[3]);
+
+ /* Resize the applet asynchronously, to avoid the chance of
+ * deadlock while waiting for the applet to initialize.
+ *
+ * In general, worker threads should spawn new threads for any blocking operations. */
+ Thread resizeAppletThread = new Thread("resizeAppletThread") {
+ @Override
+ public void run() {
+ resize(width, height);
+ }
+ };
+
+ /* Let it eventually complete */
+ resizeAppletThread.start();
+
+ } else if (message.startsWith("GetJavaObject")) {
+
+ // FIXME: how do we determine what security context this
+ // object should belong to?
+ Object o;
+
+ // Wait for the panel to initialize
+ // (happens in a separate thread)
+ waitForAppletInit(panel);
+
+ PluginDebug.debug(panel, " -- ", panel.getApplet(), " -- initialized: ", panel.isInitialized());
+
+ // Still null?
+ if (panel.getApplet() == null) {
+ streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError: " + "Initialization failed");
+ streamhandler.write("context 0 reference " + reference + " Error");
+ return;
+ }
+
+ o = panel.getApplet();
+ PluginDebug.debug("Looking for object ", o, " panel is ", panel);
+ AppletSecurityContextManager.getSecurityContext(0).store(o);
+ PluginDebug.debug("WRITING 1: ", "context 0 reference ", reference, " GetJavaObject "
+ , AppletSecurityContextManager.getSecurityContext(0).getIdentifier(o));
+ streamhandler.write("context 0 reference " + reference + " GetJavaObject "
+ + AppletSecurityContextManager.getSecurityContext(0).getIdentifier(o));
+ PluginDebug.debug("WRITING 1 DONE");
+ }
+ }
+
+ private static Vector<NetxApplet3Panel> appletPanels = new Vector<NetxApplet3Panel>();
+
+ /**
+ * Get an applet by name.
+ */
+ @Override
+ public Applet3Context getAppletContext(String name) {
+ name = name.toLowerCase();
+ SocketPermission panelSp =
+ new SocketPermission(panel.getCodeBase().getHost(), "connect");
+ synchronized(appletPanels) {
+ for (Enumeration<NetxApplet3Panel> e = appletPanels.elements(); e.hasMoreElements();) {
+ Applet3Panel p = 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;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Applet3 getApplet() {
+ return panel.getApplet();
+ }
+
+ @Override
+ public String getAppletName() {
+ return panel.getAppletName();
+ }
+
+ @Override
+ public boolean isActive() {
+ return panel.isActive();
+ }
+
+ @Override
+ public URL getDocumentBase() {
+ return panel.getDocumentBase();
+ }
+
+ @Override
+ public URL getCodeBase() {
+ return panel.getCodeBase();
+ }
+
+ @Override
+ public String getParameter(String name) {
+ return panel.getParameter(name);
+ }
+
+ @Override
+ public Enumeration<Applet3Context> getAllAppletContexts() {
+ Vector<Applet3Context> v = new Vector<Applet3Context>();
+ SocketPermission panelSp =
+ new SocketPermission(panel.getCodeBase().getHost(), "connect");
+
+ synchronized(appletPanels) {
+ for (Enumeration<NetxApplet3Panel> e = appletPanels.elements(); e.hasMoreElements();) {
+ Applet3Panel p = e.nextElement();
+ if (p.getDocumentBase().equals(panel.getDocumentBase())) {
+
+ SocketPermission sp =
+ new SocketPermission(p.getCodeBase().getHost(), "connect");
+ if (panelSp.implies(sp)) {
+ v.addElement(p);
+ }
+ }
+ }
+ }
+ return v.elements();
+ }
+
+ /* Resizes an applet panel, waiting for the applet to initialze.
+ * Should be done asynchronously to avoid the chance of deadlock. */
+ @Override
+ public void resize(final int width, final int height) {
+ /** FIXME: Resize native browser window !
+ if (appEvtQ != null){
+ appEvtQ.postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
+ new Runnable(){
+ public void run(){
+ if(ap != null)
+ {
+ ap.dispatchAppletEvent(APPLET_RESIZE, currentSize);
+ }
+ }
+ }));
+ }
+ */
+ appletResize(width, height);
+ }
+
+ /**
+ * Called when the applet wants to be resized.
+ *
+ * @param width the new requested width for the applet.
+ * @param height the new requested height for the applet.
+ */
+ public void appletResize(int width, int height) {
+ // Wait for panel to come alive
+ waitForAppletInit(panel);
+ panel.appletResize(width, height);
+ }
+
+ @Override
+ public void showDocument(URL url) {
+ PluginDebug.debug("Showing document...");
+ showDocument(url, "_self");
+ }
+
+ @Override
+ public void showDocument(URL url, String target) {
+ // If it is a javascript document, eval on current page.
+ if ("javascript".equals(url.getProtocol())) {
+ // Snip protocol off string
+ String evalString = url.toString().substring("javascript:".length());
+ eval(getWindow(), evalString);
+ return;
+ }
+ try {
+ Long reference = getRequestIdentifier();
+ write("reference " + reference + " LoadURL " + UrlUtil.encode(url.toString(), "UTF-8") + " " + target);
+ } catch (IOException exception) {
+ // Deliberately ignore IOException. showDocument may be
+ // called from threads other than the main thread after
+ // streamhandler.pluginOutputStream has been closed.
+ }
+ }
+
+ /**
+ * Show status.
+ */
+ @Override
+ public void showStatus(String status) {
+ try {
+ // FIXME: change to postCallRequest
+ // For statuses, we cannot have a newline
+ status = status.replace("\n", " ");
+ write("status " + status);
+ } catch (IOException exception) {
+ // Deliberately ignore IOException. showStatus may be
+ // called from threads other than the main thread after
+ // streamhandler.pluginOutputStream has been closed.
+ }
+ }
+
+ /**
+ * Returns an incremental number (unique identifier) for a message.
+ * If identifier hits Long.MAX_VALUE it loops back starting at 0.
+ *
+ * @return A unique Long identifier for the request
+ */
+ private static long getRequestIdentifier() {
+ synchronized(requestMutex) {
+ if (requestIdentityCounter == Long.MAX_VALUE) {
+ requestIdentityCounter = 0L;
+ }
+
+ return requestIdentityCounter++;
+ }
+ }
+
+ public long getWindow() {
+ PluginDebug.debug("STARTING getWindow");
+ Long reference = getRequestIdentifier();
+
+ PluginCallRequest request = requestFactory.getPluginCallRequest("window",
+ "instance " + identifier + " reference " +
+ +reference + " " + "GetWindow", reference);
+
+ PluginDebug.debug("STARTING postCallRequest");
+ streamhandler.postCallRequest(request);
+ PluginDebug.debug("STARTING postCallRequest done");
+ streamhandler.write(request.getMessage());
+ try {
+ PluginDebug.debug("wait request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait request 2");
+ while ((Long) request.getObject() == 0)
+ request.wait();
+ PluginDebug.debug("wait request 3");
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted waiting for call request.",
+ e);
+ }
+
+ PluginDebug.debug("STARTING getWindow DONE");
+ return (Long) request.getObject();
+ }
+
+ // FIXME: make private, access via reflection.
+ public static Object getMember(long internal, String name) {
+ AppletSecurityContextManager.getSecurityContext(0).store(name);
+ int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name);
+ Long reference = getRequestIdentifier();
+
+ // Prefix with dummy instance for convenience.
+ PluginCallRequest request = requestFactory.getPluginCallRequest("member",
+ "instance " + 0 + " reference " + reference + " GetMember " +
+ internal + " " + nameID, reference);
+
+ streamhandler.postCallRequest(request);
+ streamhandler.write(request.getMessage());
+ try {
+ PluginDebug.debug("wait getMEM request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait getMEM request 2");
+ while (request.isDone() == false)
+ request.wait();
+ PluginDebug.debug("wait getMEM request 3 GOT: ", request.getObject().getClass());
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted waiting for call request.",
+ e);
+ }
+ PluginDebug.debug(" getMember DONE");
+ return request.getObject();
+ }
+
+ public static void setMember(long internal, String name, Object value) {
+ PluginDebug.debug("Setting to class " + value.getClass() + ":" + value.getClass().isPrimitive());
+ PluginAppletSecurityContext securityContext = AppletSecurityContextManager.getSecurityContext(0);
+ securityContext.store(name);
+ int nameID = securityContext.getIdentifier(name);
+ Long reference = getRequestIdentifier();
+
+ // work on a copy of value, as we don't want to be manipulating
+ // complex objects
+ String objIDStr = securityContext.toObjectIDString(value,
+ value.getClass(), true /* unbox primitives */);
+
+ // Prefix with dummy instance for convenience.
+ PluginCallRequest request = requestFactory.getPluginCallRequest("void",
+ "instance " + 0 + " reference " + reference + " SetMember " +
+ internal + " " + nameID + " " + objIDStr, reference);
+
+ streamhandler.postCallRequest(request);
+ streamhandler.write(request.getMessage());
+ try {
+ PluginDebug.debug("wait setMem request: ", request.getMessage());
+ PluginDebug.debug("wait setMem request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait setMem request 2");
+ while (request.isDone() == false)
+ request.wait();
+ PluginDebug.debug("wait setMem request 3");
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted waiting for call request.",
+ e);
+ }
+ PluginDebug.debug(" setMember DONE");
+ }
+
+ // FIXME: handle long index as well.
+ public static void setSlot(long internal, int index, Object value) {
+ PluginAppletSecurityContext securityContext = AppletSecurityContextManager.getSecurityContext(0);
+ securityContext.store(value);
+ Long reference = getRequestIdentifier();
+
+ String objIDStr = securityContext.toObjectIDString(value,
+ value.getClass(), true /* unbox primitives */);
+
+ // Prefix with dummy instance for convenience.
+ PluginCallRequest request = requestFactory.getPluginCallRequest("void",
+ "instance " + 0 + " reference " + reference + " SetSlot " +
+ internal + " " + index + " " + objIDStr, reference);
+
+ streamhandler.postCallRequest(request);
+ streamhandler.write(request.getMessage());
+ try {
+ PluginDebug.debug("wait setSlot request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait setSlot request 2");
+ while (request.isDone() == false)
+ request.wait();
+ PluginDebug.debug("wait setSlot request 3");
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted waiting for call request.",
+ e);
+ }
+ PluginDebug.debug(" setSlot DONE");
+ }
+
+ public static Object getSlot(long internal, int index) {
+ Long reference = getRequestIdentifier();
+
+ // Prefix with dummy instance for convenience.
+ PluginCallRequest request = requestFactory.getPluginCallRequest("member",
+ "instance " + 0 + " reference " + reference + " GetSlot " +
+ internal + " " + index, reference);
+ streamhandler.postCallRequest(request);
+ streamhandler.write(request.getMessage());
+ try {
+ PluginDebug.debug("wait getSlot request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait getSlot request 2");
+ while (request.isDone() == false)
+ request.wait();
+ PluginDebug.debug("wait getSlot request 3");
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted waiting for call request.",
+ e);
+ }
+ PluginDebug.debug(" getSlot DONE");
+ return request.getObject();
+ }
+
+ public static Object eval(long internal, String s) {
+ AppletSecurityContextManager.getSecurityContext(0).store(s);
+ int stringID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(s);
+ Long reference = getRequestIdentifier();
+
+ // Prefix with dummy instance for convenience.
+ // FIXME: rename GetMemberPluginCallRequest ObjectPluginCallRequest.
+ PluginCallRequest request = requestFactory.getPluginCallRequest("member",
+ "instance " + 0 + " reference " + reference + " Eval " +
+ internal + " " + stringID, reference);
+ streamhandler.postCallRequest(request);
+ streamhandler.write(request.getMessage());
+ try {
+ PluginDebug.debug("wait eval request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait eval request 2");
+ while (request.isDone() == false) {
+ request.wait();
+ }
+ PluginDebug.debug("wait eval request 3");
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted waiting for call request.",
+ e);
+ }
+ PluginDebug.debug(" getSlot DONE");
+ return request.getObject();
+ }
+
+ public static void removeMember(long internal, String name) {
+ AppletSecurityContextManager.getSecurityContext(0).store(name);
+ int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name);
+ Long reference = getRequestIdentifier();
+
+ // Prefix with dummy instance for convenience.
+ PluginCallRequest request = requestFactory.getPluginCallRequest("void",
+ "instance " + 0 + " reference " + reference + " RemoveMember " +
+ internal + " " + nameID, reference);
+
+ streamhandler.postCallRequest(request);
+ streamhandler.write(request.getMessage());
+ try {
+ PluginDebug.debug("wait removeMember request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait removeMember request 2");
+ while (request.isDone() == false)
+ request.wait();
+ PluginDebug.debug("wait removeMember request 3");
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted waiting for call request.",
+ e);
+ }
+ PluginDebug.debug(" RemoveMember DONE");
+ }
+
+ public static Object call(long internal, String name, Object args[]) {
+ // FIXME: when is this removed from the object store?
+ // FIXME: reference should return the ID.
+ // FIXME: convenience method for this long line.
+ AppletSecurityContextManager.getSecurityContext(0).store(name);
+ int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name);
+ Long reference = getRequestIdentifier();
+
+ String argIDs = "";
+ for (Object arg : args) {
+ AppletSecurityContextManager.getSecurityContext(0).store(arg);
+ argIDs += AppletSecurityContextManager.getSecurityContext(0).getIdentifier(arg) + " ";
+ }
+ argIDs = argIDs.trim();
+
+ // Prefix with dummy instance for convenience.
+ PluginCallRequest request = requestFactory.getPluginCallRequest("member",
+ "instance " + 0 + " reference " + reference + " Call " +
+ internal + " " + nameID + " " + argIDs, reference);
+
+ streamhandler.postCallRequest(request);
+ streamhandler.write(request.getMessage());
+ try {
+ PluginDebug.debug("wait call request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait call request 2");
+ while (request.isDone() == false) {
+ request.wait();
+ }
+ PluginDebug.debug("wait call request 3");
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted waiting for call request.",
+ e);
+ }
+ PluginDebug.debug(" Call DONE");
+ return request.getObject();
+ }
+
+ public static Object requestPluginCookieInfo(URI uri) {
+
+ PluginCallRequest request;
+ Long reference = getRequestIdentifier();
+
+ try {
+ String encodedURI = UrlUtil.encode(uri.toString(), "UTF-8");
+ request = requestFactory.getPluginCallRequest("cookieinfo",
+ "plugin PluginCookieInfo " + "reference " + reference +
+ " " + encodedURI, reference);
+
+ } catch (UnsupportedEncodingException e) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e);
+ return null;
+ }
+
+ PluginMessageConsumer.registerPriorityWait(reference);
+ streamhandler.postCallRequest(request);
+ streamhandler.write(request.getMessage());
+ try {
+ PluginDebug.debug("wait cookieinfo request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait cookieinfo request 2");
+ while (request.isDone() == false) {
+ request.wait();
+ }
+ PluginDebug.debug("wait cookieinfo request 3");
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted waiting for cookieinfo request.",
+ e);
+ }
+ PluginDebug.debug(" Cookieinfo DONE");
+ return request.getObject();
+ }
+
+ /**
+ * Obtain information about the proxy from the browser.
+ *
+ * @param uri a String in url-encoded form
+ * @return a {@link URI} that indicates a proxy.
+ */
+ public static Object requestPluginProxyInfo(String uri) {
+ Long reference = getRequestIdentifier();
+
+ PluginCallRequest request = requestFactory.getPluginCallRequest("proxyinfo",
+ "plugin PluginProxyInfo reference " + reference + " " +
+ uri, reference);
+
+ PluginMessageConsumer.registerPriorityWait(reference);
+ streamhandler.postCallRequest(request);
+ streamhandler.write(request.getMessage());
+ try {
+ PluginDebug.debug("wait call request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait call request 2");
+ while (request.isDone() == false) {
+ request.wait();
+ }
+ PluginDebug.debug("wait call request 3");
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted waiting for call request.",
+ e);
+ }
+ PluginDebug.debug(" Call DONE");
+ return request.getObject();
+ }
+
+ public static void JavaScriptFinalize(long internal) {
+ Long reference = getRequestIdentifier();
+
+ // Prefix with dummy instance for convenience.
+ PluginCallRequest request = requestFactory.getPluginCallRequest("void",
+ "instance " + 0 + " reference " + reference + " Finalize " +
+ internal, reference);
+
+ streamhandler.postCallRequest(request);
+ streamhandler.write(request.getMessage());
+ try {
+ PluginDebug.debug("wait finalize request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait finalize request 2");
+ while (request.isDone() == false) {
+ request.wait();
+ }
+ PluginDebug.debug("wait finalize request 3");
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted waiting for call request.",
+ e);
+ }
+ PluginDebug.debug(" finalize DONE");
+ }
+
+ public static String javascriptToString(long internal) {
+ Long reference = getRequestIdentifier();
+
+ // Prefix with dummy instance for convenience.
+ PluginCallRequest request = requestFactory.getPluginCallRequest("member",
+ "instance " + 0 + " reference " + reference + " ToString " +
+ internal, reference);
+
+ streamhandler.postCallRequest(request);
+ streamhandler.write(request.getMessage());
+ PluginDebug.debug("wait ToString request 1");
+ synchronized (request) {
+ PluginDebug.debug("wait ToString request 2");
+ waitForRequestCompletion(request);
+ PluginDebug.debug("wait ToString request 3");
+ }
+
+ PluginDebug.debug(" ToString DONE");
+ return (String) request.getObject();
+ }
+
+ // FIXME: make this private and access it from JSObject using
+ // reflection.
+ private void write(String message) throws IOException {
+ PluginDebug.debug("WRITING 2: ", "instance ", identifier, " " + message);
+ streamhandler.write("instance " + identifier + " " + message);
+ PluginDebug.debug("WRITING 2 DONE");
+ }
+
+ @Override
+ public void setStream(String key, InputStream stream) throws IOException {
+ // We do nothing.
+ }
+
+ @Override
+ public InputStream getStream(String key) {
+ // We do nothing.
+ return null;
+ }
+
+ @Override
+ public Iterator<String> getStreamKeys() {
+ // We do nothing.
+ return null;
+ }
+
+ /**
+ * System parameters.
+ */
+ static Hashtable<String, String> systemParam = new Hashtable<String, String>();
+
+ static {
+ systemParam.put("codebase", "codebase");
+ systemParam.put("code", "code");
+ systemParam.put("alt", "alt");
+ systemParam.put("width", "width");
+ systemParam.put("height", "height");
+ systemParam.put("align", "align");
+ systemParam.put("vspace", "vspace");
+ systemParam.put("hspace", "hspace");
+ }
+
+ /**
+ * 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 {
+ ((Applet3Panel)panel).joinAppletThread();
+ ((Applet3Panel)panel).release();
+ } catch (InterruptedException e) {
+ return; // abort the reload
+ }
+
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ ((Applet3Panel)panel).createAppletThread();
+ return null;
+ }
+ });
+
+ panel.sendEvent(AppletPanel.APPLET_LOAD);
+ panel.sendEvent(AppletPanel.APPLET_INIT);
+ panel.sendEvent(AppletPanel.APPLET_START);
+ }
+
+ /**
+ * 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(Applet3Panel 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 Applet3Panel p = panel;
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ ClassLoader cl = p.getApplet().getClass().getClassLoader();
+
+ // Since we want to deal with JNLPClassLoader, extract it if this
+ // is a codebase loader
+ if (cl instanceof JNLPClassLoader.CodeBaseClassLoader) {
+ cl = ((JNLPClassLoader.CodeBaseClassLoader) cl).getParentJNLPClassLoader();
+ }
+
+ appletShutdown(p);
+ appletPanels.removeElement(p);
+
+ // Mark classloader unusable
+ ((JNLPClassLoader) cl).decrementLoaderUseCount();
+
+ if (countApplets() == 0) {
+ appletSystemExit();
+ }
+
+ updateStatus(identifier, PAV_INIT_STATUS.DESTROYED);
+ }
+ }).start();
+ }
+
+ /**
+ * Exit the program.
+ * Exit from the program (if not stand alone) - do no clean-up
+ */
+ private void appletSystemExit() {
+ // Do nothing. Exit is handled by another
+ // block of code, called when _all_ applets are gone
+ }
+
+ /**
+ * How many applets are running?
+ */
+
+ public static int countApplets() {
+ return appletPanels.size();
+ }
+
+
+ /**
+ * Waits on a given condition queue until timeout.
+ *
+ * <b>This function assumes that the monitor lock has already been
+ * acquired by the caller.</b>
+ *
+ * If the given lock is null, this function returns immediately.
+ *
+ * @param lock the lock that must be held when this method is called.
+ * @param cond the condition queue on which to wait for notifications.
+ * @param timeout The maximum time to wait (nanoseconds)
+ * @return Approximate time spent sleeping (not guaranteed to be perfect)
+ */
+ public static long waitTillTimeout(ReentrantLock lock, Condition cond,
+ long timeout) {
+
+ // Can't wait on null. Return 0 indicating no wait happened.
+ if (lock == null) {
+ return 0;
+ }
+
+ assert lock.isHeldByCurrentThread();
+
+ // Record when we started sleeping
+ long sleepStart = 0L;
+
+ try {
+ sleepStart = System.nanoTime();
+ cond.await(timeout, TimeUnit.NANOSECONDS);
+ } catch (InterruptedException ie) {} // Discarded, time to return
+
+ // Return the difference
+ return System.nanoTime() - sleepStart;
+ }
+
+ private class SplashCreator implements Runnable {
+
+ private final Applet3Panel fPanel;
+
+ public SplashCreator(Applet3Panel fPanel) {
+ this.fPanel = fPanel;
+ }
+
+ @Override
+ public void run() {
+ initializeViewAndSlash(fPanel);
+ }
+ }
+}
diff --git a/plugin/icedteanp/java/netscape/javascript/JSObject.java b/plugin/icedteanp/java/netscape/javascript/JSObject.java
index 489efa6..d3eec67 100644
--- a/plugin/icedteanp/java/netscape/javascript/JSObject.java
+++ b/plugin/icedteanp/java/netscape/javascript/JSObject.java
@@ -50,7 +50,7 @@ import java.applet.Applet;
import java.security.AccessControlException;
import java.security.AccessController;
-import sun.applet.PluginAppletViewer;
+import jogamp.plugin.applet.PluginApplet3Viewer;
import sun.applet.PluginDebug;
/**
@@ -162,7 +162,7 @@ public final class JSObject {
public Object getMember(String name) {
PluginDebug.debug("JSObject.getMember ", name);
- Object o = PluginAppletViewer.getMember(internal, name);
+ Object o = PluginApplet3Viewer.getMember(internal, name);
PluginDebug.debug("JSObject.getMember GOT ", o);
return o;
}
@@ -175,7 +175,7 @@ public final class JSObject {
public Object getSlot(int index) {
PluginDebug.debug("JSObject.getSlot ", index);
- return PluginAppletViewer.getSlot(internal, index);
+ return PluginApplet3Viewer.getSlot(internal, index);
}
/**
@@ -185,7 +185,7 @@ public final class JSObject {
public void setMember(String name, Object value) {
PluginDebug.debug("JSObject.setMember ", name, " ", value);
- PluginAppletViewer.setMember(internal, name, value);
+ PluginApplet3Viewer.setMember(internal, name, value);
}
/**
@@ -198,7 +198,7 @@ public final class JSObject {
public void setSlot(int index, Object value) {
PluginDebug.debug("JSObject.setSlot ", index, " ", value);
- PluginAppletViewer.setSlot(internal, index, value);
+ PluginApplet3Viewer.setSlot(internal, index, value);
}
/**
@@ -207,7 +207,7 @@ public final class JSObject {
public void removeMember(String name) {
PluginDebug.debug("JSObject.removeMember ", name);
- PluginAppletViewer.removeMember(internal, name);
+ PluginApplet3Viewer.removeMember(internal, name);
}
/**
@@ -223,7 +223,7 @@ public final class JSObject {
PluginDebug.debug(" ", arg);
}
PluginDebug.debug("");
- return PluginAppletViewer.call(internal, methodName, args);
+ return PluginApplet3Viewer.call(internal, methodName, args);
}
/**
@@ -233,7 +233,7 @@ public final class JSObject {
*/
public Object eval(String s) {
PluginDebug.debug("JSObject.eval ", s);
- return PluginAppletViewer.eval(internal, s);
+ return PluginApplet3Viewer.eval(internal, s);
}
/**
@@ -241,7 +241,7 @@ public final class JSObject {
*/
public String toString() {
PluginDebug.debug("JSObject.toString");
- return PluginAppletViewer.javascriptToString(internal);
+ return PluginApplet3Viewer.javascriptToString(internal);
}
// should use some sort of identifier rather than String
@@ -255,8 +255,7 @@ public final class JSObject {
PluginDebug.debug("JSObject.getWindow");
// FIXME: handle long case as well.
long internal = 0;
- internal = ((PluginAppletViewer)
- applet.getAppletContext()).getWindow();
+ internal = ((PluginApplet3Viewer)applet.getAppletContext()).getWindow();
PluginDebug.debug("GOT IT: ", internal);
return new JSObject(internal);
}
@@ -272,6 +271,6 @@ public final class JSObject {
return;
PluginDebug.debug("JSObject.finalize ");
- PluginAppletViewer.JavaScriptFinalize(internal);
+ PluginApplet3Viewer.JavaScriptFinalize(internal);
}
}
diff --git a/plugin/icedteanp/java/sun/applet/Applet3MessageHandler.java b/plugin/icedteanp/java/sun/applet/Applet3MessageHandler.java
new file mode 100644
index 0000000..140e5eb
--- /dev/null
+++ b/plugin/icedteanp/java/sun/applet/Applet3MessageHandler.java
@@ -0,0 +1,21 @@
+package sun.applet;
+
+import sun.applet.AppletMessageHandler;
+
+public class Applet3MessageHandler extends AppletMessageHandler {
+
+ public Applet3MessageHandler(String baseKey) {
+ super(baseKey);
+ }
+
+ public String getMessage(String key) {
+ return super.getMessage(key);
+ }
+ public String getMessage(String key, Object arg){
+ return super.getMessage(key, arg);
+ }
+ public String getMessage(String key, Object arg1, Object arg2){
+ return super.getMessage(key, arg1, arg2);
+ }
+
+}
diff --git a/plugin/icedteanp/java/sun/applet/PluginCookieManager.java b/plugin/icedteanp/java/sun/applet/PluginCookieManager.java
index 21bdbc0..de58d07 100644
--- a/plugin/icedteanp/java/sun/applet/PluginCookieManager.java
+++ b/plugin/icedteanp/java/sun/applet/PluginCookieManager.java
@@ -45,6 +45,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
+import jogamp.plugin.applet.PluginApplet3Viewer;
+
import com.sun.jndi.toolkit.url.UrlUtil;
public class PluginCookieManager extends CookieManager {
@@ -64,8 +66,7 @@ public class PluginCookieManager extends CookieManager {
Map<String, List<String>> cookieMap = new java.util.HashMap<String, List<String>>();
- String cookies = (String) PluginAppletViewer
- .requestPluginCookieInfo(uri);
+ String cookies = (String) PluginApplet3Viewer.requestPluginCookieInfo(uri);
List<String> cookieHeader = new java.util.ArrayList<String>();
if (cookies != null && cookies.length() > 0)
diff --git a/plugin/icedteanp/java/sun/applet/PluginMain.java b/plugin/icedteanp/java/sun/applet/PluginMain.java
index 421edb5..32b8ab6 100644
--- a/plugin/icedteanp/java/sun/applet/PluginMain.java
+++ b/plugin/icedteanp/java/sun/applet/PluginMain.java
@@ -77,14 +77,13 @@ import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
-import sun.awt.AppContext;
-import sun.awt.SunToolkit;
+import jogamp.applet.App3Context;
+import jogamp.plugin.applet.PluginApplet3Viewer;
import net.sourceforge.jnlp.config.DeploymentConfiguration;
import net.sourceforge.jnlp.runtime.JNLPRuntime;
import net.sourceforge.jnlp.security.JNLPAuthenticator;
import net.sourceforge.jnlp.util.logging.JavaConsole;
-import net.sourceforge.jnlp.util.logging.LogConfig;
import net.sourceforge.jnlp.util.logging.OutputController;
/**
@@ -127,8 +126,12 @@ public class PluginMain {
OutputController.getLogger().log(i + ": "+string);
}
+ /**
if (AppContext.getAppContext() == null) {
SunToolkit.createNewAppContext();
+ } */
+ if (App3Context.getAppContext() == null) {
+ App3Context.createAppContext();
}
installDummyJavascriptProtocolHandler();
@@ -152,8 +155,10 @@ public class PluginMain {
PluginAppletSecurityContext.setStreamhandler(streamHandler);
AppletSecurityContextManager.addContext(0, sc);
- PluginAppletViewer.setStreamhandler(streamHandler);
- PluginAppletViewer.setPluginCallRequestFactory(new PluginCallRequestFactory());
+ // FIXME PluginAppletViewer.setStreamhandler(streamHandler);
+ // FIXME PluginAppletViewer.setPluginCallRequestFactory(new PluginCallRequestFactory());
+ PluginApplet3Viewer.setStreamhandler(streamHandler); // FIXME
+ PluginApplet3Viewer.setPluginCallRequestFactory(new PluginCallRequestFactory()); // FIXME
init();
diff --git a/plugin/icedteanp/java/sun/applet/PluginMessageConsumer.java b/plugin/icedteanp/java/sun/applet/PluginMessageConsumer.java
index 1de8bd7..1975cba 100644
--- a/plugin/icedteanp/java/sun/applet/PluginMessageConsumer.java
+++ b/plugin/icedteanp/java/sun/applet/PluginMessageConsumer.java
@@ -41,7 +41,7 @@ import java.util.ArrayList;
import java.util.LinkedList;
import net.sourceforge.jnlp.util.logging.OutputController;
-class PluginMessageConsumer {
+public class PluginMessageConsumer {
private static final int MAX_PARALLEL_INITS = 1;
diff --git a/plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java b/plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java
index 79d925d..c945b8e 100644
--- a/plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java
+++ b/plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java
@@ -39,7 +39,7 @@ package sun.applet;
import net.sourceforge.jnlp.util.logging.OutputController;
-class PluginMessageHandlerWorker extends Thread {
+public class PluginMessageHandlerWorker extends Thread {
private boolean free = true;
private final boolean isPriorityWorker;
diff --git a/plugin/icedteanp/java/sun/applet/PluginParameterParser.java b/plugin/icedteanp/java/sun/applet/PluginParameterParser.java
index 1db6034..56dabc9 100644
--- a/plugin/icedteanp/java/sun/applet/PluginParameterParser.java
+++ b/plugin/icedteanp/java/sun/applet/PluginParameterParser.java
@@ -6,7 +6,7 @@ import java.util.Map;
import net.sourceforge.jnlp.PluginParameters;
-class PluginParameterParser {
+public class PluginParameterParser {
static private final char DELIMITER_ESCAPE = ':';
static private final String KEY_VALUE_DELIMITER = ";";
diff --git a/plugin/icedteanp/java/sun/applet/PluginProxySelector.java b/plugin/icedteanp/java/sun/applet/PluginProxySelector.java
index 25689f5..7355ab9 100644
--- a/plugin/icedteanp/java/sun/applet/PluginProxySelector.java
+++ b/plugin/icedteanp/java/sun/applet/PluginProxySelector.java
@@ -45,6 +45,8 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
+import jogamp.plugin.applet.PluginApplet3Viewer;
+
import com.sun.jndi.toolkit.url.UrlUtil;
import net.sourceforge.jnlp.config.DeploymentConfiguration;
@@ -135,7 +137,7 @@ public class PluginProxySelector extends JNLPProxySelector {
/** For tests to override */
protected Object getProxyFromRemoteCallToBrowser(String uri) {
- return PluginAppletViewer.requestPluginProxyInfo(uri);
+ return PluginApplet3Viewer.requestPluginProxyInfo(uri);
}
/**
diff --git a/plugin/icedteanp/java/sun/applet/PluginStreamHandler.java b/plugin/icedteanp/java/sun/applet/PluginStreamHandler.java
index 990a903..d45cdc4 100644
--- a/plugin/icedteanp/java/sun/applet/PluginStreamHandler.java
+++ b/plugin/icedteanp/java/sun/applet/PluginStreamHandler.java
@@ -46,7 +46,7 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
-import javax.swing.SwingUtilities;
+import jogamp.plugin.applet.PluginApplet3Viewer;
import net.sourceforge.jnlp.runtime.JNLPRuntime;
import net.sourceforge.jnlp.runtime.Translator;
import net.sourceforge.jnlp.util.logging.JavaConsole;
@@ -230,12 +230,14 @@ public class PluginStreamHandler {
final String frest = rest;
if (type.equals("instance")) {
- PluginAppletViewer.handleMessage(identifier, freference, frest);
+ PluginApplet3Viewer.handleMessage(identifier, freference, frest); // FIXME
+ // FIXME PluginAppletViewer.handleMessage(identifier, freference, frest);
} else if (type.equals("context")) {
PluginDebug.debug("Sending to PASC: ", identifier, "/", reference, " and ", rest);
AppletSecurityContextManager.handleMessage(identifier, reference, src, privileges, rest);
}
} catch (Exception e) {
+ e.printStackTrace(); // FIXME
throw new PluginException(this, identifier, reference, e);
}
}