aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginAppletPanelFactory.java228
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginAppletViewer.java334
3 files changed, 326 insertions, 245 deletions
diff --git a/ChangeLog b/ChangeLog
index 8de285c..1aff7fe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2012-12-04 Adam Domurad <[email protected]>
+ PluginAppletViewer refactoring.
+ * plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
+ (handleInitializationMessage): New, extracts initialization logic
+ from PluginAppletViewer.handleMessage.
+ * plugin/icedteanp/java/sun/applet/PluginAppletPanelFactory.java: Moved
+ into own file.
+
+2012-12-04 Adam Domurad <[email protected]>
+
Remove the applet/embed/object tag parser from ITW. Send the applet
parameters directly from the C++.
* Makefile.am: Allow unit-testing for classes in plugin.jar.
diff --git a/plugin/icedteanp/java/sun/applet/PluginAppletPanelFactory.java b/plugin/icedteanp/java/sun/applet/PluginAppletPanelFactory.java
new file mode 100644
index 0000000..122313e
--- /dev/null
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletPanelFactory.java
@@ -0,0 +1,228 @@
+/* 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 sun.applet;
+
+import java.applet.Applet;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.swing.SwingUtilities;
+
+import net.sourceforge.jnlp.NetxPanel;
+import net.sourceforge.jnlp.PluginParameters;
+
+/**
+ * Lets us construct one using unix-style one shot behaviors
+ */
+
+class PluginAppletPanelFactory {
+
+ public AppletPanel createPanel(PluginStreamHandler streamhandler,
+ final int identifier,
+ final long handle,
+ final URL doc,
+ final PluginParameters params) {
+ final NetxPanel panel = AccessController.doPrivileged(new PrivilegedAction<NetxPanel>() {
+ public NetxPanel run() {
+ NetxPanel panel = new NetxPanel(doc, params, false);
+ NetxPanel.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.
+ PluginDebug.debug("X and Y are: " + params.getWidth() + " " + params.getHeight());
+ panel.setAppletViewerFrame(PluginAppletViewer.framePanel(identifier, handle,
+ params.getWidth(), params.getHeight(), panel));
+
+ panel.init();
+ // Start the applet
+ initEventQueue(panel);
+ }
+ }, "NetXPanel initializer");
+
+ panelInit.start();
+ while(panelInit.isAlive()) {
+ try {
+ panelInit.join();
+ } catch (InterruptedException e) {
+ }
+ }
+
+ // Wait for the panel to initialize
+ PluginAppletViewer.waitForAppletInit(panel);
+
+ Applet 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");
+
+ /* 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.
+ */
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ panel.getParent().setSize(params.getWidth(), params.getHeight());
+ }
+ });
+ } catch (InvocationTargetException ite) {
+ // Not being able to resize is non-fatal
+ PluginDebug.debug("Unable to resize panel: ");
+ ite.printStackTrace();
+ } catch (InterruptedException ie) {
+ // Not being able to resize is non-fatal
+ PluginDebug.debug("Unable to resize panel: ");
+ ie.printStackTrace();
+ }
+
+ panel.removeSplash();
+
+ AppletSecurityContextManager.getSecurityContext(0).associateSrc(panel.getAppletClassLoader(), doc);
+ AppletSecurityContextManager.getSecurityContext(0).associateInstance(identifier, panel.getAppletClassLoader());
+
+ return panel;
+ }
+
+ public boolean isStandalone() {
+ return false;
+ }
+
+ /**
+ * Send the initial set of events to the appletviewer event queue.
+ * On start-up the current behaviour is to load the applet and call
+ * Applet.init() and Applet.start().
+ */
+ private void initEventQueue(AppletPanel panel) {
+ // appletviewer.send.event is an undocumented and unsupported system
+ // property which is used exclusively for testing purposes.
+ PrivilegedAction<String> pa = new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty("appletviewer.send.event");
+ }
+ };
+ String eventList = AccessController.doPrivileged(pa);
+
+ if (eventList == null) {
+ // Add the standard events onto the event queue.
+ panel.sendEvent(AppletPanel.APPLET_LOAD);
+ panel.sendEvent(AppletPanel.APPLET_INIT);
+ panel.sendEvent(AppletPanel.APPLET_START);
+ } else {
+ // We're testing AppletViewer. Force the specified set of events
+ // onto the event queue, wait for the events to be processed, and
+ // exit.
+
+ // The list of events that will be executed is provided as a
+ // ","-separated list. No error-checking will be done on the list.
+ String[] events = 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/sun/applet/PluginAppletViewer.java b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
index 611ed56..c98899a 100644
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
@@ -65,6 +65,8 @@ package sun.applet;
import java.applet.Applet;
import java.applet.AppletContext;
import java.applet.AudioClip;
+import java.awt.BorderLayout;
+import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
@@ -75,14 +77,11 @@ import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
-import java.awt.Component;
import java.io.IOException;
import java.io.InputStream;
-import java.io.PrintStream;
-import java.io.Reader;
-import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
import java.net.SocketPermission;
import java.net.URI;
import java.net.URL;
@@ -90,17 +89,15 @@ import java.net.URLConnection;
import java.security.AccessController;
import java.security.AllPermission;
import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
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 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;
@@ -109,173 +106,15 @@ import javax.swing.SwingUtilities;
import net.sourceforge.jnlp.NetxPanel;
import net.sourceforge.jnlp.PluginParameters;
import net.sourceforge.jnlp.runtime.JNLPClassLoader;
+import net.sourceforge.jnlp.splashscreen.SplashController;
+import net.sourceforge.jnlp.splashscreen.SplashPanel;
+import net.sourceforge.jnlp.splashscreen.SplashUtils;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
import sun.awt.X11.XEmbeddedFrame;
import sun.misc.Ref;
import com.sun.jndi.toolkit.url.UrlUtil;
-import java.awt.BorderLayout;
-import java.util.Hashtable;
-import java.util.Vector;
-import net.sourceforge.jnlp.splashscreen.SplashController;
-import net.sourceforge.jnlp.splashscreen.SplashPanel;
-import net.sourceforge.jnlp.splashscreen.SplashUtils;
-
-/**
- * Lets us construct one using unix-style one shot behaviors
- */
-
-class PluginAppletPanelFactory {
-
- public AppletPanel createPanel(PluginStreamHandler streamhandler,
- final int identifier,
- final long handle,
- final URL doc,
- final PluginParameters params) {
- final NetxPanel panel = AccessController.doPrivileged(new PrivilegedAction<NetxPanel>() {
- public NetxPanel run() {
- NetxPanel panel = new NetxPanel(doc, params, false);
- NetxPanel.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.
- PluginDebug.debug("X and Y are: " + params.getWidth() + " " + params.getHeight());
- panel.setAppletViewerFrame(PluginAppletViewer.framePanel(identifier, handle,
- params.getWidth(), params.getHeight(), panel));
-
- panel.init();
- // Start the applet
- initEventQueue(panel);
- }
- }, "NetXPanel initializer");
-
- panelInit.start();
- while(panelInit.isAlive()) {
- try {
- panelInit.join();
- } catch (InterruptedException e) {
- }
- }
-
- // Wait for the panel to initialize
- PluginAppletViewer.waitForAppletInit(panel);
-
- Applet 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");
-
- /* 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.
- */
- try {
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- panel.getParent().setSize(params.getWidth(), params.getHeight());
- }
- });
- } catch (InvocationTargetException ite) {
- // Not being able to resize is non-fatal
- PluginDebug.debug("Unable to resize panel: ");
- ite.printStackTrace();
- } catch (InterruptedException ie) {
- // Not being able to resize is non-fatal
- PluginDebug.debug("Unable to resize panel: ");
- ie.printStackTrace();
- }
-
- panel.removeSplash();
-
- AppletSecurityContextManager.getSecurityContext(0).associateSrc(panel.getAppletClassLoader(), doc);
- AppletSecurityContextManager.getSecurityContext(0).associateInstance(identifier, panel.getAppletClassLoader());
-
- return panel;
- }
-
- public boolean isStandalone() {
- return false;
- }
-
- /**
- * Send the initial set of events to the appletviewer event queue.
- * On start-up the current behaviour is to load the applet and call
- * Applet.init() and Applet.start().
- */
- private void initEventQueue(AppletPanel panel) {
- // appletviewer.send.event is an undocumented and unsupported system
- // property which is used exclusively for testing purposes.
- PrivilegedAction<String> pa = new PrivilegedAction<String>() {
- public String run() {
- return System.getProperty("appletviewer.send.event");
- }
- };
- String eventList = AccessController.doPrivileged(pa);
-
- if (eventList == null) {
- // Add the standard events onto the event queue.
- panel.sendEvent(AppletPanel.APPLET_LOAD);
- panel.sendEvent(AppletPanel.APPLET_INIT);
- panel.sendEvent(AppletPanel.APPLET_START);
- } else {
- // We're testing AppletViewer. Force the specified set of events
- // onto the event queue, wait for the events to be processed, and
- // exit.
-
- // The list of events that will be executed is provided as a
- // ","-separated list. No error-checking will be done on the list.
- String[] events = 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())
- ;
- }
- }
-}
/*
*/
@@ -567,92 +406,97 @@ public class PluginAppletViewer extends XEmbeddedFrame
requestFactory = rf;
}
- /**
- * Handle an incoming message from the plugin.
- */
- public static void handleMessage(int identifier, int reference, String message) {
+ private static void handleInitializationMessage(int identifier, String message) throws IOException {
- PluginDebug.debug("PAV handling: ", message);
+ // 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;
- try {
- if (message.startsWith("handle")) {
+ // 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);
+ }
- // 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;
+ long handle = Long.parseLong(msgParts[0]);
+ String width = msgParts[1];
+ String height = msgParts[2];
+
+ int spaceLocation = message.indexOf(' ', "tag".length() + 1);
+ String documentBase =
+ UrlUtil.decode(message.substring("tag".length() + 1, spaceLocation));
+ String paramString = message.substring(spaceLocation + 1);
+
+ PluginDebug.debug("Handle = ", handle, "\n",
+ "Width = ", width, "\n",
+ "Height = ", height, "\n",
+ "DocumentBase = ", documentBase, "\n",
+ "Params = ", paramString);
+
+ PluginAppletPanelFactory factory = new PluginAppletPanelFactory();
+ AppletMessageHandler amh = new AppletMessageHandler("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();
- // 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);
- }
+ PluginParameters params = new PluginParameterParser().parse(width, height, paramString);
- long handle = Long.parseLong(msgParts[0]);
- String width = msgParts[1];
- String height = msgParts[2];
-
- int spaceLocation = message.indexOf(' ', "tag".length() + 1);
- String documentBase =
- UrlUtil.decode(message.substring("tag".length() + 1, spaceLocation));
- String paramString = message.substring(spaceLocation + 1);
-
- PluginDebug.debug("Handle = ", handle, "\n",
- "Width = ", width, "\n",
- "Height = ", height, "\n",
- "DocumentBase = ", documentBase, "\n",
- "Params = ", paramString);
-
- PluginAppletPanelFactory factory = new PluginAppletPanelFactory();
- AppletMessageHandler amh = new AppletMessageHandler("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, handle, 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();
- }
+ // Let user know we are starting up
+ streamhandler.write("instance " + identifier + " status " + amh.getMessage("status.start"));
+ factory.createPanel(streamhandler, identifier, handle, url, params);
- // If wait exceeded maxWait, we timed out. Throw an exception
- if (maxTimeToSleep <= 0)
- throw new Exception("Applet initialization timeout");
+ 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();
+ }
- // 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);
+ // If wait exceeded maxWait, we timed out. Throw an exception
+ if (maxTimeToSleep <= 0) {
+ // Caught in handleMessage
+ throw new RuntimeException("Applet initialization timeout");
+ }
- // Should we proceed with reframing?
- PluginDebug.debug("Init complete");
+ // 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);
- if (updateStatus(identifier, PAV_INIT_STATUS.REFRAME_COMPLETE).equals(PAV_INIT_STATUS.INACTIVE)) {
- destroyApplet(identifier);
- return;
- }
+ // 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