aboutsummaryrefslogtreecommitdiffstats
path: root/netx/jogamp/plugin/jnlp/NetxApplet3Panel.java
diff options
context:
space:
mode:
Diffstat (limited to 'netx/jogamp/plugin/jnlp/NetxApplet3Panel.java')
-rw-r--r--netx/jogamp/plugin/jnlp/NetxApplet3Panel.java230
1 files changed, 230 insertions, 0 deletions
diff --git a/netx/jogamp/plugin/jnlp/NetxApplet3Panel.java b/netx/jogamp/plugin/jnlp/NetxApplet3Panel.java
new file mode 100644
index 0000000..875dc5a
--- /dev/null
+++ b/netx/jogamp/plugin/jnlp/NetxApplet3Panel.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ * This file is part of IcedTea, http://icedtea.classpath.org
+ * 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.
+ */
+
+package jogamp.plugin.jnlp;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import jogamp.applet.App3Context;
+import jogamp.applet.Applet3Panel;
+import jogamp.plugin.jnlp.runtime.Applet3Instance;
+import net.sourceforge.jnlp.Launcher;
+import net.sourceforge.jnlp.PluginBridge;
+import net.sourceforge.jnlp.PluginParameters;
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+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 com.jogamp.plugin.applet.Applet3Context;
+
+/**
+ * This panel calls into netx to run an applet, and pipes the display
+ * into a panel from the icedtea-web browser plugin.
+ *
+ * @author Francis Kung <[email protected]>
+ */
+public class NetxApplet3Panel extends Applet3Panel implements SplashController {
+ private final PluginParameters pluginParameters;
+ private PluginBridge bridge = null;
+ private Applet3Instance appInst = null;
+ private SplashController splashController;
+ /** The plugin .. */
+ private Applet3Context upstreamContext = null;
+ private volatile boolean initialized;
+
+ // We use this so that we can create exactly one thread group
+ // for all panels with the same uKey.
+ private static final Map<String, ThreadGroup> uKeyToTG =
+ new HashMap<String, ThreadGroup>();
+ private static final Object TGMapMutex = new Object();
+
+ // This map is actually a set (unfortunately there is no ConcurrentSet
+ // in java.util.concurrent). If KEY is in this map, then we know that
+ // an app context has been created for the panel that has uKey.equals(KEY),
+ // so we avoid creating it a second time for panels with the same uKey.
+ // Because it's a set, only the keys matter. However, we can't insert
+ // null values in because if we did, we couldn't use null checks to see
+ // if a key was absent before a putIfAbsent.
+ private static final ConcurrentMap<String, Boolean> appContextCreated =
+ new ConcurrentHashMap<String, Boolean>();
+
+ public NetxApplet3Panel(long nativeWindowHandle, int width, int height, URL documentURL, PluginParameters params) {
+ super(nativeWindowHandle, width, height, documentURL, params.getUnderlyingHashtable());
+
+ this.pluginParameters = params;
+ this.initialized = false;
+
+ String uniqueKey = params.getUniqueKey(getCodeBase());
+ synchronized(TGMapMutex) {
+ if (!uKeyToTG.containsKey(uniqueKey)) {
+ ThreadGroup tg = new ThreadGroup(Launcher.getMainGroup(), this.documentURL.toString());
+ uKeyToTG.put(uniqueKey, tg);
+ }
+ }
+ }
+
+ @Override
+ protected void showAppletException(Throwable t) {
+ /*
+ * Log any exceptions thrown while loading, initializing, starting,
+ * and stopping the applet.
+ */
+ OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, t); //new logger
+ super.showAppletException(t);
+ }
+
+ //Overriding to use Netx classloader. You might need to relax visibility
+ //in sun.applet.AppletPanel for runLoader().
+ @Override
+ protected void runLoader() {
+
+ try {
+ bridge = new PluginBridge(baseURL,
+ getDocumentBase(),
+ getJarFiles(),
+ getCode(),
+ getWidth(),
+ getHeight(),
+ pluginParameters);
+
+ doInit = true;
+ dispatchAppletEvent(APPLET_LOADING, null);
+ status = APPLET_LOAD;
+
+ App3Launcher l = new App3Launcher(false);
+
+ // May throw LaunchException:
+ appInst = (Applet3Instance) l.launch(bridge);
+ applet = appInst.getApplet();
+
+ if (applet != null) {
+ // Stick it in the frame
+ showAppletStatus("loaded");
+ }
+ } catch (Exception e) {
+ status = APPLET_ERROR;
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL, e);
+ replaceSplash(SplashUtils.getErrorSplashScreen(getWidth(), getHeight(), e));
+ } finally {
+ // PR1157: This needs to occur even in the case of an exception
+ // so that the applet's event listeners are signaled.
+ // Once PluginAppletViewer.AppletEventListener is signaled PluginAppletViewer can properly stop waiting
+ // in PluginAppletViewer.waitForAppletInit
+ this.initialized = true;
+ dispatchAppletEvent(APPLET_LOADING_COMPLETED, null);
+ }
+ }
+
+ /**
+ * Creates a new Thread (in a new applet-specific ThreadGroup) for running
+ * the applet
+ */
+ // Reminder: Relax visibility in sun.applet.AppletPanel
+ @Override
+ public synchronized void createAppletThread() {
+ // initialize JNLPRuntime in the main threadgroup
+ synchronized (JNLPRuntime.initMutex) {
+ //The custom NetX Policy and SecurityManager are set here.
+ if (!JNLPRuntime.isInitialized()) {
+ OutputController.getLogger().log("initializing JNLPRuntime...");
+
+ JNLPRuntime.initialize(false);
+ } else {
+ OutputController.getLogger().log("JNLPRuntime already initialized");
+ }
+ }
+
+ handler = new Thread(getThreadGroup(), this, "NetxPanelThread@" + this.documentURL);
+ handler.start();
+ }
+
+ public final void setAppletContext(Applet3Context ctx) {
+ upstreamContext = ctx;
+ }
+
+ @Override
+ protected final Applet3Context getAppletContext() {
+ if( null != upstreamContext ) {
+ return upstreamContext;
+ } else {
+ return appInst.getAppletEnvironment();
+ }
+ }
+
+ @Override
+ public ClassLoader getAppletClassLoader() {
+ return appInst.getClassLoader();
+ }
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ public ThreadGroup getThreadGroup() {
+ synchronized(TGMapMutex) {
+ return uKeyToTG.get(pluginParameters.getUniqueKey(getCodeBase()));
+ }
+ }
+
+ public void createNewAppContext() {
+ if (Thread.currentThread().getThreadGroup() != getThreadGroup()) {
+ throw new RuntimeException("createNewAppContext called from the wrong thread.");
+ }
+ // only create a new context if one hasn't already been created for the
+ // applets with this unique key.
+ if (null == appContextCreated.putIfAbsent(pluginParameters.getUniqueKey(getCodeBase()), Boolean.TRUE)) {
+ App3Context.createAppContext(); // FIXME: Really ?
+ // SunToolkit.createNewAppContext();
+ }
+ }
+
+ public void setAppletViewerFrame(SplashController framePanel) {
+ splashController=framePanel;
+ }
+
+ @Override
+ public void removeSplash() {
+ splashController.removeSplash();
+ }
+
+ @Override
+ public void replaceSplash(SplashPanel r) {
+ splashController.replaceSplash(r);
+ }
+
+ @Override
+ public int getSplashWidth() {
+ return splashController.getSplashWidth();
+ }
+
+ @Override
+ public int getSplashHeigth() {
+ return splashController.getSplashHeigth();
+ }
+
+}