queue = null;
-
- public synchronized void addAppletListener(AppletListener l) {
- listeners = AppletEventMulticaster.add(listeners, l);
- }
-
- public synchronized void removeAppletListener(AppletListener l) {
- listeners = AppletEventMulticaster.remove(listeners, l);
- }
-
- /**
- * Dispatch event to the listeners..
- */
- public void dispatchAppletEvent(int id, Object argument) {
- //System.out.println("SEND= " + id);
- if (listeners != null) {
- AppletEvent evt = new AppletEvent(this, id, argument);
- listeners.appletStateChanged(evt);
- }
- }
-
- /**
- * Send an event. Queue it for execution by the handler thread.
- */
- public void sendEvent(int id) {
- synchronized(this) {
- if (queue == null) {
- //System.out.println("SEND0= " + id);
- queue = new LinkedBlockingQueue<>();
- }
- boolean inserted = queue.add(id);
- notifyAll();
- }
- if (id == APPLET_QUIT) {
- try {
- joinAppletThread(); // Let the applet event handler exit
- } catch (InterruptedException e) {
- }
-
- // AppletClassLoader.release() must be called by a Thread
- // not within the applet's ThreadGroup
- if (loader == null)
- loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
- release();
- }
- }
-
- /**
- * Get an event from the queue.
- */
- synchronized AppletEvent getNextEvent() throws InterruptedException {
- while (queue == null || queue.isEmpty()) {
- wait();
- }
- int eventId = queue.take();
- return new AppletEvent(this, eventId, null);
- }
-
- boolean emptyEventQueue() {
- if ((queue == null) || (queue.isEmpty()))
- return true;
- else
- return false;
- }
-
- /**
- * This kludge is specific to get over AccessControlException thrown during
- * Applet.stop() or destroy() when static thread is suspended. Set a flag
- * in AppletClassLoader to indicate that an
- * AccessControlException for RuntimePermission "modifyThread" or
- * "modifyThreadGroup" had occurred.
- */
- private void setExceptionStatus(AccessControlException e) {
- Permission p = e.getPermission();
- if (p instanceof RuntimePermission) {
- if (p.getName().startsWith("modifyThread")) {
- if (loader == null)
- loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
- loader.setExceptionStatus();
- }
- }
- }
-
- /**
- * Execute applet events.
- * Here is the state transition diagram
- *
- * {@literal
- * Note: (XXX) is the action
- * APPLET_XXX is the state
- * (applet code loaded) --> APPLET_LOAD -- (applet init called)--> APPLET_INIT --
- * (applet start called) --> APPLET_START -- (applet stop called) --> APPLET_STOP --
- * (applet destroyed called) --> APPLET_DESTROY --> (applet gets disposed) -->
- * APPLET_DISPOSE --> ...
- * }
- *
- * In the legacy lifecycle model. The applet gets loaded, inited and started. So it stays
- * in the APPLET_START state unless the applet goes away(refresh page or leave the page).
- * So the applet stop method called and the applet enters APPLET_STOP state. Then if the applet
- * is revisited, it will call applet start method and enter the APPLET_START state and stay there.
- *
- * In the modern lifecycle model. When the applet first time visited, it is same as legacy lifecycle
- * model. However, when the applet page goes away. It calls applet stop method and enters APPLET_STOP
- * state and then applet destroyed method gets called and enters APPLET_DESTROY state.
- *
- * This code is also called by AppletViewer. In AppletViewer "Restart" menu, the applet is jump from
- * APPLET_STOP to APPLET_DESTROY and to APPLET_INIT .
- *
- * Also, the applet can jump from APPLET_INIT state to APPLET_DESTROY (in Netscape/Mozilla case).
- * Same as APPLET_LOAD to
- * APPLET_DISPOSE since all of this are triggered by browser.
- *
- */
- @Override
- public void run() {
-
- Thread curThread = Thread.currentThread();
- if (curThread == loaderThread) {
- // if we are in the loader thread, cause
- // loading to occur. We may exit this with
- // status being APPLET_DISPOSE, APPLET_ERROR,
- // or APPLET_LOAD
- runLoader();
- return;
- }
-
- boolean disposed = false;
- while (!disposed && !curThread.isInterrupted()) {
- AppletEvent evt;
- try {
- evt = getNextEvent();
- } catch (InterruptedException e) {
- showAppletStatus("bail");
- return;
- }
-
- //showAppletStatus("EVENT = " + evt.getID());
- try {
- switch (evt.getID()) {
- case APPLET_LOAD:
- if (!okToLoad()) {
- break;
- }
- // This complexity allows loading of applets to be
- // interruptable. The actual thread loading runs
- // in a separate thread, so it can be interrupted
- // without harming the applet thread.
- // So that we don't have to worry about
- // concurrency issues, the main applet thread waits
- // until the loader thread terminates.
- // (one way or another).
- if (loaderThread == null) {
- setLoaderThread(new Thread(null, this,
- "AppletLoader", 0, false));
- loaderThread.start();
- // we get to go to sleep while this runs
- loaderThread.join();
- setLoaderThread(null);
- } else {
- // REMIND: issue an error -- this case should never
- // occur.
- }
- break;
-
- case APPLET_INIT:
- // AppletViewer "Restart" will jump from destroy method to
- // init, that is why we need to check status w/ APPLET_DESTROY
- if (status != APPLET_LOAD && status != APPLET_DESTROY) {
- showAppletStatus("notloaded");
- break;
- }
- applet.resize(defaultAppletSize);
-
- if (PerformanceLogger.loggingEnabled()) {
- PerformanceLogger.setTime("Applet Init");
- PerformanceLogger.outputLog();
- }
- applet.init();
-
- //Need the default(fallback) font to be created in this AppContext
- Font f = getFont();
- if (f == null ||
- "dialog".equals(f.getFamily().toLowerCase(Locale.ENGLISH)) &&
- f.getSize() == 12 && f.getStyle() == Font.PLAIN) {
- setFont(new Font(Font.DIALOG, Font.PLAIN, 12));
- }
-
- // Validate the applet in event dispatch thread
- // to avoid deadlock.
- try {
- final AppletPanel p = this;
- Runnable r = new Runnable() {
- @Override
- public void run() {
- p.validate();
- }
- };
- AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
- }
- catch(InterruptedException ie) {
- }
- catch(InvocationTargetException ite) {
- }
-
- status = APPLET_INIT;
- showAppletStatus("inited");
- break;
-
- case APPLET_START:
- {
- if (status != APPLET_INIT && status != APPLET_STOP) {
- showAppletStatus("notinited");
- break;
- }
- applet.resize(currentAppletSize);
- applet.start();
-
- // Validate and show the applet in event dispatch thread
- // to avoid deadlock.
- try {
- final AppletPanel p = this;
- final Applet a = applet;
- Runnable r = new Runnable() {
- @Override
- public void run() {
- p.validate();
- a.setVisible(true);
-
- // Fix for BugTraq ID 4041703.
- // Set the default focus for an applet.
- if (hasInitialFocus()) {
- setDefaultFocus();
- }
- }
- };
- AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
- }
- catch(InterruptedException ie) {
- }
- catch(InvocationTargetException ite) {
- }
-
- status = APPLET_START;
- showAppletStatus("started");
- break;
- }
-
- case APPLET_STOP:
- if (status != APPLET_START) {
- showAppletStatus("notstarted");
- break;
- }
- status = APPLET_STOP;
-
- // Hide the applet in event dispatch thread
- // to avoid deadlock.
- try {
- final Applet a = applet;
- Runnable r = new Runnable() {
- @Override
- public void run() {
- a.setVisible(false);
- }
- };
- AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
- }
- catch(InterruptedException ie) {
- }
- catch(InvocationTargetException ite) {
- }
-
-
- // During Applet.stop(), any AccessControlException on an involved Class remains in
- // the "memory" of the AppletClassLoader. If the same instance of the ClassLoader is
- // reused, the same exception will occur during class loading. Set the AppletClassLoader's
- // exceptionStatusSet flag to allow recognition of what had happened
- // when reusing AppletClassLoader object.
- try {
- applet.stop();
- } catch (java.security.AccessControlException e) {
- setExceptionStatus(e);
- // rethrow exception to be handled as it normally would be.
- throw e;
- }
- showAppletStatus("stopped");
- break;
-
- case APPLET_DESTROY:
- if (status != APPLET_STOP && status != APPLET_INIT) {
- showAppletStatus("notstopped");
- break;
- }
- status = APPLET_DESTROY;
-
- // During Applet.destroy(), any AccessControlException on an involved Class remains in
- // the "memory" of the AppletClassLoader. If the same instance of the ClassLoader is
- // reused, the same exception will occur during class loading. Set the AppletClassLoader's
- // exceptionStatusSet flag to allow recognition of what had happened
- // when reusing AppletClassLoader object.
- try {
- applet.destroy();
- } catch (java.security.AccessControlException e) {
- setExceptionStatus(e);
- // rethrow exception to be handled as it normally would be.
- throw e;
- }
- showAppletStatus("destroyed");
- break;
-
- case APPLET_DISPOSE:
- if (status != APPLET_DESTROY && status != APPLET_LOAD) {
- showAppletStatus("notdestroyed");
- break;
- }
- status = APPLET_DISPOSE;
-
- try {
- final Applet a = applet;
- Runnable r = new Runnable() {
- @Override
- public void run() {
- remove(a);
- }
- };
- AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
- }
- catch(InterruptedException ie)
- {
- }
- catch(InvocationTargetException ite)
- {
- }
- applet = null;
- showAppletStatus("disposed");
- disposed = true;
- break;
-
- case APPLET_QUIT:
- return;
- }
- } catch (Exception e) {
- status = APPLET_ERROR;
- if (e.getMessage() != null) {
- showAppletStatus("exception2", e.getClass().getName(),
- e.getMessage());
- } else {
- showAppletStatus("exception", e.getClass().getName());
- }
- showAppletException(e);
- } catch (ThreadDeath e) {
- showAppletStatus("death");
- return;
- } catch (Error e) {
- status = APPLET_ERROR;
- if (e.getMessage() != null) {
- showAppletStatus("error2", e.getClass().getName(),
- e.getMessage());
- } else {
- showAppletStatus("error", e.getClass().getName());
- }
- showAppletException(e);
- }
- clearLoadAbortRequest();
- }
- }
-
- /**
- * Gets most recent focus owner component associated with the given window.
- * It does that without calling Window.getMostRecentFocusOwner since it
- * provides its own logic contradicting with setDefautlFocus. Instead, it
- * calls KeyboardFocusManager directly.
- */
- private Component getMostRecentFocusOwnerForWindow(Window w) {
- return AWTAccessor.getKeyboardFocusManagerAccessor()
- .getMostRecentFocusOwner(w);
- }
-
- /*
- * Fix for BugTraq ID 4041703.
- * Set the focus to a reasonable default for an Applet.
- */
- private void setDefaultFocus() {
- Component toFocus = null;
- Container parent = getParent();
-
- if(parent != null) {
- if (parent instanceof Window) {
- toFocus = getMostRecentFocusOwnerForWindow((Window)parent);
- if (toFocus == parent || toFocus == null) {
- toFocus = parent.getFocusTraversalPolicy().
- getInitialComponent((Window)parent);
- }
- } else if (parent.isFocusCycleRoot()) {
- toFocus = parent.getFocusTraversalPolicy().
- getDefaultComponent(parent);
- }
- }
-
- if (toFocus != null) {
- if (parent instanceof EmbeddedFrame) {
- ((EmbeddedFrame) parent).synthesizeWindowActivation(true);
- }
- // EmbeddedFrame might have focus before the applet was added.
- // Thus after its activation the most recent focus owner will be
- // restored. We need the applet's initial focusabled component to
- // be focused here.
- toFocus.requestFocusInWindow();
- }
- }
-
- /**
- * Load the applet into memory.
- * Runs in a seperate (and interruptible) thread from the rest of the
- * applet event processing so that it can be gracefully interrupted from
- * things like HotJava.
- */
- @SuppressWarnings("deprecation")
- private void runLoader() {
- if (status != APPLET_DISPOSE) {
- showAppletStatus("notdisposed");
- return;
- }
-
- dispatchAppletEvent(APPLET_LOADING, null);
-
- // REMIND -- might be cool to visually indicate loading here --
- // maybe do animation?
- status = APPLET_LOAD;
-
- // Create a class loader
- loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
-
- // Load the archives if present.
- // REMIND - this probably should be done in a separate thread,
- // or at least the additional archives (epll).
-
- String code = getCode();
-
- // setup applet AppContext
- // this must be called before loadJarFiles
- setupAppletAppContext();
-
- try {
- loadJarFiles(loader);
- applet = createApplet(loader);
- } catch (ClassNotFoundException e) {
- status = APPLET_ERROR;
- showAppletStatus("notfound", code);
- showAppletLog("notfound", code);
- showAppletException(e);
- return;
- } catch (InstantiationException e) {
- status = APPLET_ERROR;
- showAppletStatus("nocreate", code);
- showAppletLog("nocreate", code);
- showAppletException(e);
- return;
- } catch (IllegalAccessException e) {
- status = APPLET_ERROR;
- showAppletStatus("noconstruct", code);
- showAppletLog("noconstruct", code);
- showAppletException(e);
- // sbb -- I added a return here
- return;
- } catch (Exception e) {
- status = APPLET_ERROR;
- showAppletStatus("exception", e.getMessage());
- showAppletException(e);
- return;
- } catch (ThreadDeath e) {
- status = APPLET_ERROR;
- showAppletStatus("death");
- return;
- } catch (Error e) {
- status = APPLET_ERROR;
- showAppletStatus("error", e.getMessage());
- showAppletException(e);
- return;
- } finally {
- // notify that loading is no longer going on
- dispatchAppletEvent(APPLET_LOADING_COMPLETED, null);
- }
-
- // Fixed #4508194: NullPointerException thrown during
- // quick page switch
- //
- if (applet != null)
- {
- // Stick it in the frame
- applet.setStub(this);
- applet.hide();
- add("Center", applet);
- showAppletStatus("loaded");
- validate();
- }
- }
-
- protected Applet createApplet(final AppletClassLoader loader) throws ClassNotFoundException,
- IllegalAccessException, IOException, InstantiationException, InterruptedException {
- String code = getCode();
-
- if (code != null) {
- applet = (Applet)loader.loadCode(code).newInstance();
- } else {
- String msg = "nocode";
- status = APPLET_ERROR;
- showAppletStatus(msg);
- showAppletLog(msg);
- repaint();
- }
-
- // Determine the JDK level that the applet targets.
- // This is critical for enabling certain backward
- // compatibility switch if an applet is a JDK 1.1
- // applet. [stanley.ho]
- findAppletJDKLevel(applet);
-
- if (Thread.interrupted()) {
- try {
- status = APPLET_DISPOSE; // APPLET_ERROR?
- applet = null;
- // REMIND: This may not be exactly the right thing: the
- // status is set by the stop button and not necessarily
- // here.
- showAppletStatus("death");
- } finally {
- Thread.currentThread().interrupt(); // resignal interrupt
- }
- return null;
- }
- return applet;
- }
-
- protected void loadJarFiles(AppletClassLoader loader) throws IOException,
- InterruptedException {
- // Load the archives if present.
- // REMIND - this probably should be done in a separate thread,
- // or at least the additional archives (epll).
- String jarFiles = getJarFiles();
-
- if (jarFiles != null) {
- StringTokenizer st = new StringTokenizer(jarFiles, ",", false);
- while(st.hasMoreTokens()) {
- String tok = st.nextToken().trim();
- try {
- loader.addJar(tok);
- } catch (IllegalArgumentException e) {
- // bad archive name
- continue;
- }
- }
- }
- }
-
- /**
- * Request that the loading of the applet be stopped.
- */
- protected synchronized void stopLoading() {
- // REMIND: fill in the body
- if (loaderThread != null) {
- //System.out.println("Interrupting applet loader thread: " + loaderThread);
- loaderThread.interrupt();
- } else {
- setLoadAbortRequest();
- }
- }
-
-
- protected synchronized boolean okToLoad() {
- return !loadAbortRequest;
- }
-
- protected synchronized void clearLoadAbortRequest() {
- loadAbortRequest = false;
- }
-
- protected synchronized void setLoadAbortRequest() {
- loadAbortRequest = true;
- }
-
-
- private synchronized void setLoaderThread(Thread loaderThread) {
- this.loaderThread = loaderThread;
- }
-
- /**
- * Return true when the applet has been started.
- */
- @Override
- public boolean isActive() {
- return status == APPLET_START;
- }
-
-
- private EventQueue appEvtQ = null;
- /**
- * Is called when the applet wants to be resized.
- */
- @Override
- public void appletResize(int width, int height) {
- currentAppletSize.width = width;
- currentAppletSize.height = height;
- final Dimension currentSize = new Dimension(currentAppletSize.width,
- currentAppletSize.height);
-
- if(loader != null) {
- AppContext appCtxt = loader.getAppContext();
- if(appCtxt != null)
- appEvtQ = (java.awt.EventQueue)appCtxt.get(AppContext.EVENT_QUEUE_KEY);
- }
-
- final AppletPanel ap = this;
- if (appEvtQ != null){
- appEvtQ.postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
- new Runnable() {
- @Override
- public void run() {
- if (ap != null) {
- ap.dispatchAppletEvent(
- APPLET_RESIZE,
- currentSize);
- }
- }
- }));
- }
- }
-
- @Override
- public void setBounds(int x, int y, int width, int height) {
- super.setBounds(x, y, width, height);
- currentAppletSize.width = width;
- currentAppletSize.height = height;
- }
-
- public Applet getApplet() {
- return applet;
- }
-
- /**
- * Status line. Called by the AppletPanel to provide
- * feedback on the Applet's state.
- */
- protected void showAppletStatus(String status) {
- getAppletContext().showStatus(amh.getMessage(status));
- }
-
- protected void showAppletStatus(String status, Object arg) {
- getAppletContext().showStatus(amh.getMessage(status, arg));
- }
- protected void showAppletStatus(String status, Object arg1, Object arg2) {
- getAppletContext().showStatus(amh.getMessage(status, arg1, arg2));
- }
-
- /**
- * Called by the AppletPanel to print to the log.
- */
- protected void showAppletLog(String msg) {
- System.out.println(amh.getMessage(msg));
- }
-
- protected void showAppletLog(String msg, Object arg) {
- System.out.println(amh.getMessage(msg, arg));
- }
-
- /**
- * Called by the AppletPanel to provide
- * feedback when an exception has happened.
- */
- protected void showAppletException(Throwable t) {
- t.printStackTrace();
- repaint();
- }
-
- /**
- * Get caching key for classloader cache
- */
- public String getClassLoaderCacheKey()
- {
- /**
- * Fixed #4501142: Classloader sharing policy doesn't
- * take "archive" into account. This will be overridden
- * by Java Plug-in. [stanleyh]
- */
- return getCodeBase().toString();
- }
-
- /**
- * The class loaders
- */
- private static HashMap classloaders = new HashMap<>();
-
- /**
- * Flush a class loader.
- */
- public static synchronized void flushClassLoader(String key) {
- classloaders.remove(key);
- }
-
- /**
- * Flush all class loaders.
- */
- public static synchronized void flushClassLoaders() {
- classloaders = new HashMap<>();
- }
-
- /**
- * This method actually creates an AppletClassLoader.
- *
- * It can be override by subclasses (such as the Plug-in)
- * to provide different classloaders.
- */
- protected AppletClassLoader createClassLoader(final URL codebase) {
- return new AppletClassLoader(codebase);
- }
-
- /**
- * Get a class loader. Create in a restricted context
- */
- synchronized AppletClassLoader getClassLoader(final URL codebase, final String key) {
- AppletClassLoader c = classloaders.get(key);
- if (c == null) {
- AccessControlContext acc =
- getAccessControlContext(codebase);
- c = AccessController.doPrivileged(
- new PrivilegedAction() {
- @Override
- public AppletClassLoader run() {
- AppletClassLoader ac = createClassLoader(codebase);
- /* Should the creation of the classloader be
- * within the class synchronized block? Since
- * this class is used by the plugin, take care
- * to avoid deadlocks, or specialize
- * AppletPanel within the plugin. It may take
- * an arbitrary amount of time to create a
- * class loader (involving getting Jar files
- * etc.) and may block unrelated applets from
- * finishing createAppletThread (due to the
- * class synchronization). If
- * createAppletThread does not finish quickly,
- * the applet cannot process other messages,
- * particularly messages such as destroy
- * (which timeout when called from the browser).
- */
- synchronized (getClass()) {
- AppletClassLoader res = classloaders.get(key);
- if (res == null) {
- classloaders.put(key, ac);
- return ac;
- } else {
- return res;
- }
- }
- }
- },acc);
- }
- return c;
- }
-
- /**
- * get the context for the AppletClassLoader we are creating.
- * the context is granted permission to create the class loader,
- * connnect to the codebase, and whatever else the policy grants
- * to all codebases.
- */
- private AccessControlContext getAccessControlContext(final URL codebase) {
-
- PermissionCollection perms = AccessController.doPrivileged(
- new PrivilegedAction() {
- @Override
- public PermissionCollection run() {
- Policy p = java.security.Policy.getPolicy();
- if (p != null) {
- return p.getPermissions(new CodeSource(null,
- (java.security.cert.Certificate[]) null));
- } else {
- return null;
- }
- }
- });
-
- if (perms == null)
- perms = new Permissions();
-
- //XXX: this is needed to be able to create the classloader itself!
-
- perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
-
- Permission p;
- java.net.URLConnection urlConnection = null;
- try {
- urlConnection = codebase.openConnection();
- p = urlConnection.getPermission();
- } catch (java.io.IOException ioe) {
- p = null;
- }
-
- if (p != null)
- perms.add(p);
-
- if (p instanceof FilePermission) {
-
- String path = p.getName();
-
- int endIndex = path.lastIndexOf(File.separatorChar);
-
- if (endIndex != -1) {
- path = path.substring(0, endIndex+1);
-
- if (path.endsWith(File.separator)) {
- path += "-";
- }
- perms.add(new FilePermission(path,
- SecurityConstants.FILE_READ_ACTION));
- }
- } else {
- URL locUrl = codebase;
- if (urlConnection instanceof JarURLConnection) {
- locUrl = ((JarURLConnection)urlConnection).getJarFileURL();
- }
- String host = locUrl.getHost();
- if (host != null && (host.length() > 0))
- perms.add(new SocketPermission(host,
- SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION));
- }
-
- ProtectionDomain domain =
- new ProtectionDomain(new CodeSource(codebase,
- (java.security.cert.Certificate[]) null), perms);
- AccessControlContext acc =
- new AccessControlContext(new ProtectionDomain[] { domain });
-
- return acc;
- }
-
- public Thread getAppletHandlerThread() {
- return handler;
- }
-
- public int getAppletWidth() {
- return currentAppletSize.width;
- }
-
- public int getAppletHeight() {
- return currentAppletSize.height;
- }
-
- public static void changeFrameAppContext(Frame frame, AppContext newAppContext)
- {
- // Fixed #4754451: Applet can have methods running on main
- // thread event queue.
- //
- // The cause of this bug is that the frame of the applet
- // is created in main thread group. Thus, when certain
- // AWT/Swing events are generated, the events will be
- // dispatched through the wrong event dispatch thread.
- //
- // To fix this, we rearrange the AppContext with the frame,
- // so the proper event queue will be looked up.
- //
- // Swing also maintains a Frame list for the AppContext,
- // so we will have to rearrange it as well.
-
- // Check if frame's AppContext has already been set properly
- AppContext oldAppContext = SunToolkit.targetToAppContext(frame);
-
- if (oldAppContext == newAppContext)
- return;
-
- // Synchronization on Window.class is needed for locking the
- // critical section of the window list in AppContext.
- synchronized (Window.class)
- {
- WeakReference weakRef = null;
- // Remove frame from the Window list in wrong AppContext
- {
- // Lookup current frame's AppContext
- @SuppressWarnings("unchecked")
- Vector> windowList =
- (Vector>)oldAppContext.get(Window.class);
- if (windowList != null) {
- for (WeakReference ref : windowList) {
- if (ref.get() == frame) {
- weakRef = ref;
- break;
- }
- }
- // Remove frame from wrong AppContext
- if (weakRef != null)
- windowList.remove(weakRef);
- }
- }
-
- // Put the frame into the applet's AppContext map
- SunToolkit.insertTargetMapping(frame, newAppContext);
-
- // Insert frame into the Window list in the applet's AppContext map
- {
- @SuppressWarnings("unchecked")
- Vector> windowList =
- (Vector>)newAppContext.get(Window.class);
- if (windowList == null) {
- windowList = new Vector>();
- newAppContext.put(Window.class, windowList);
- }
- // use the same weakRef here as it is used elsewhere
- windowList.add(weakRef);
- }
- }
- }
-
- // Flag to indicate if applet is targeted for JDK 1.1.
- private boolean jdk11Applet = false;
-
- // Flag to indicate if applet is targeted for JDK 1.2.
- private boolean jdk12Applet = false;
-
- /**
- * Determine JDK level of an applet.
- */
- private void findAppletJDKLevel(Applet applet)
- {
- // To determine the JDK level of an applet, the
- // most reliable way is to check the major version
- // of the applet class file.
-
- // synchronized on applet class object, so calling from
- // different instances of the same applet will be
- // serialized.
- Class> appletClass = applet.getClass();
-
- synchronized(appletClass) {
- // Determine if the JDK level of an applet has been
- // checked before.
- Boolean jdk11Target = loader.isJDK11Target(appletClass);
- Boolean jdk12Target = loader.isJDK12Target(appletClass);
-
- // if applet JDK level has been checked before, retrieve
- // value and return.
- if (jdk11Target != null || jdk12Target != null) {
- jdk11Applet = (jdk11Target == null) ? false : jdk11Target.booleanValue();
- jdk12Applet = (jdk12Target == null) ? false : jdk12Target.booleanValue();
- return;
- }
-
- String name = appletClass.getName();
-
- // first convert any '.' to '/'
- name = name.replace('.', '/');
-
- // append .class
- final String resourceName = name + ".class";
-
- byte[] classHeader = new byte[8];
-
- try (InputStream is = AccessController.doPrivileged(
- (PrivilegedAction) () -> loader.getResourceAsStream(resourceName))) {
-
- // Read the first 8 bytes of the class file
- int byteRead = is.read(classHeader, 0, 8);
-
- // return if the header is not read in entirely
- // for some reasons.
- if (byteRead != 8)
- return;
- }
- catch (IOException e) {
- return;
- }
-
- // Check major version in class file header
- int major_version = readShort(classHeader, 6);
-
- // Major version in class file is as follows:
- // 45 - JDK 1.1
- // 46 - JDK 1.2
- // 47 - JDK 1.3
- // 48 - JDK 1.4
- // 49 - JDK 1.5
- if (major_version < 46)
- jdk11Applet = true;
- else if (major_version == 46)
- jdk12Applet = true;
-
- // Store applet JDK level in AppContext for later lookup,
- // e.g. page switch.
- loader.setJDK11Target(appletClass, jdk11Applet);
- loader.setJDK12Target(appletClass, jdk12Applet);
- }
- }
-
- /**
- * Return true if applet is targeted to JDK 1.1.
- */
- protected boolean isJDK11Applet() {
- return jdk11Applet;
- }
-
- /**
- * Return true if applet is targeted to JDK1.2.
- */
- protected boolean isJDK12Applet() {
- return jdk12Applet;
- }
-
- /**
- * Read short from byte array.
- */
- private int readShort(byte[] b, int off) {
- int hi = readByte(b[off]);
- int lo = readByte(b[off + 1]);
- return (hi << 8) | lo;
- }
-
- private int readByte(byte b) {
- return ((int)b) & 0xFF;
- }
-
-
- private static AppletMessageHandler amh = new AppletMessageHandler("appletpanel");
-}