jdk/src/java.desktop/share/classes/sun/awt/AppContext.java
author ddehaven
Tue, 19 Aug 2014 10:32:16 -0700
changeset 26037 508779ce6619
parent 26004 jdk/src/share/classes/sun/awt/AppContext.java@7507a1b93f67
parent 25859 jdk/src/share/classes/sun/awt/AppContext.java@3317bb8137f4
child 28231 b608ffcaed74
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
23010
6dadb192ad81 8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents: 21677
diff changeset
     2
 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4365
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4365
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4365
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4365
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4365
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.awt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.EventQueue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.Window;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.SystemTray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.awt.TrayIcon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.awt.Toolkit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.awt.GraphicsEnvironment;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.awt.event.InvocationEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.security.AccessController;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.security.PrivilegedAction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.util.Collections;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.util.HashMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.util.IdentityHashMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.util.Map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.util.Set;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.util.HashSet;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.beans.PropertyChangeSupport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import java.beans.PropertyChangeListener;
23666
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
    45
import java.lang.ref.SoftReference;
3938
ef327bd847c0 6879044: Eliminate the dependency on logging from the AWT/2D/Swing classes
mchung
parents: 113
diff changeset
    46
import sun.util.logging.PlatformLogger;
4365
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
    47
import java.util.concurrent.locks.Condition;
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
    48
import java.util.concurrent.locks.Lock;
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
    49
import java.util.concurrent.locks.ReentrantLock;
12412
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
    50
import java.util.concurrent.atomic.AtomicInteger;
23666
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
    51
import java.util.function.Supplier;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * The AppContext is a table referenced by ThreadGroup which stores
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * application service instances.  (If you are not writing an application
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * service, or don't know what one is, please do not use this class.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * The AppContext allows applet access to what would otherwise be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * potentially dangerous services, such as the ability to peek at
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * EventQueues or change the look-and-feel of a Swing application.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * Most application services use a singleton object to provide their
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * services, either as a default (such as getSystemEventQueue or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * getDefaultToolkit) or as static methods with class data (System).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * The AppContext works with the former method by extending the concept
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * of "default" to be ThreadGroup-specific.  Application services
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * lookup their singleton in the AppContext.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * For example, here we have a Foo service, with its pre-AppContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * code:<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * <code><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 *    public class Foo {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 *        private static Foo defaultFoo = new Foo();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 *        public static Foo getDefaultFoo() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 *            return defaultFoo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 *        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 *    ... Foo service methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 *    }</pre></code><p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 * The problem with the above is that the Foo service is global in scope,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * so that applets and other untrusted code can execute methods on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 * single, shared Foo instance.  The Foo service therefore either needs
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * to block its use by untrusted code using a SecurityManager test, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * restrict its capabilities so that it doesn't matter if untrusted code
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * executes it.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * Here's the Foo class written to use the AppContext:<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 * <code><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 *    public class Foo {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 *        public static Foo getDefaultFoo() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 *            Foo foo = (Foo)AppContext.getAppContext().get(Foo.class);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 *            if (foo == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 *                foo = new Foo();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 *                getAppContext().put(Foo.class, foo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 *            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 *            return foo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 *        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
 *    ... Foo service methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
 *    }</pre></code><p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
 * Since a separate AppContext can exist for each ThreadGroup, trusted
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
 * and untrusted code have access to different Foo instances.  This allows
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
 * untrusted code access to "system-wide" services -- the service remains
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
 * within the AppContext "sandbox".  For example, say a malicious applet
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
 * wants to peek all of the key events on the EventQueue to listen for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
 * passwords; if separate EventQueues are used for each ThreadGroup
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
 * using AppContexts, the only key events that applet will be able to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
 * listen to are its own.  A more reasonable applet request would be to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
 * change the Swing default look-and-feel; with that default stored in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
 * an AppContext, the applet's look-and-feel will change without
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
 * disrupting other applets or potentially the browser itself.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
 * Because the AppContext is a facility for safely extending application
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
 * service support to applets, none of its methods may be blocked by a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
 * a SecurityManager check in a valid Java implementation.  Applets may
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
 * therefore safely invoke any of its methods without worry of being
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
 * blocked.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
 * Note: If a SecurityManager is installed which derives from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
 * sun.awt.AWTSecurityManager, it may override the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
 * AWTSecurityManager.getAppContext() method to return the proper
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
 * AppContext based on the execution context, in the case where
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
 * the default ThreadGroup-based AppContext indexing would return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
 * the main "system" AppContext.  For example, in an applet situation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
 * if a system thread calls into an applet, rather than returning the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
 * main "system" AppContext (the one corresponding to the system thread),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
 * an installed AWTSecurityManager may return the applet's AppContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
 * based on the execution context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
 * @author  Thomas Ball
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
 * @author  Fred Ecks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
public final class AppContext {
3938
ef327bd847c0 6879044: Eliminate the dependency on logging from the AWT/2D/Swing classes
mchung
parents: 113
diff changeset
   136
    private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.AppContext");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    /* Since the contents of an AppContext are unique to each Java
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * session, this class should never be serialized. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
4365
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   141
    /*
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   142
     * The key to put()/get() the Java EventQueue into/from the AppContext.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    public static final Object EVENT_QUEUE_KEY = new StringBuffer("EventQueue");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
4365
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   146
    /*
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   147
     * The keys to store EventQueue push/pop lock and condition.
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   148
     */
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   149
    public final static Object EVENT_QUEUE_LOCK_KEY = new StringBuilder("EventQueue.Lock");
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   150
    public final static Object EVENT_QUEUE_COND_KEY = new StringBuilder("EventQueue.Condition");
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   151
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    /* A map of AppContexts, referenced by ThreadGroup.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    private static final Map<ThreadGroup, AppContext> threadGroup2appContext =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            Collections.synchronizedMap(new IdentityHashMap<ThreadGroup, AppContext>());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * Returns a set containing all <code>AppContext</code>s.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    public static Set<AppContext> getAppContexts() {
112
c7ed16a1bef2 6636331: ConcurrentModificationException in AppContext code
son
parents: 108
diff changeset
   161
        synchronized (threadGroup2appContext) {
c7ed16a1bef2 6636331: ConcurrentModificationException in AppContext code
son
parents: 108
diff changeset
   162
            return new HashSet<AppContext>(threadGroup2appContext.values());
c7ed16a1bef2 6636331: ConcurrentModificationException in AppContext code
son
parents: 108
diff changeset
   163
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    /* The main "system" AppContext, used by everything not otherwise
18202
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   167
       contained in another AppContext. It is implicitly created for
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   168
       standalone apps only (i.e. not applets)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     */
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   170
    private static volatile AppContext mainAppContext = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
21242
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   172
    private static class GetAppContextLock {};
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   173
    private final static Object getAppContextLock = new GetAppContextLock();
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   174
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     * The hash map associated with this AppContext.  A private delegate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
     * is used instead of subclassing HashMap so as to avoid all of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     * HashMap's potentially risky methods, such as clear(), elements(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
     * putAll(), etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     */
11264
54f2f4c6bd30 7117008: Warnings cleanup day: reduce number of javac warnings in the sun.awt package
art
parents: 5506
diff changeset
   181
    private final Map<Object, Object> table = new HashMap<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    private final ThreadGroup threadGroup;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * If any <code>PropertyChangeListeners</code> have been registered,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     * the <code>changeSupport</code> field describes them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * @see #addPropertyChangeListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     * @see #removePropertyChangeListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * @see #firePropertyChange
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    private PropertyChangeSupport changeSupport = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    public static final String DISPOSED_PROPERTY_NAME = "disposed";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    public static final String GUI_DISPOSED = "guidisposed";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
18262
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   198
    private enum State {
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   199
        VALID,
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   200
        BEING_DISPOSED,
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   201
        DISPOSED
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   202
    };
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   203
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   204
    private volatile State state = State.VALID;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    public boolean isDisposed() {
18262
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   207
        return state == State.DISPOSED;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
12412
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
   210
    /*
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
   211
     * The total number of AppContexts, system-wide.  This number is
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
   212
     * incremented at the beginning of the constructor, and decremented
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
   213
     * at the end of dispose().  getAppContext() checks to see if this
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
   214
     * number is 1.  If so, it returns the sole AppContext without
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
   215
     * checking Thread.currentThread().
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
   216
     */
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
   217
    private static final AtomicInteger numAppContexts = new AtomicInteger(0);
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
   218
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     * The context ClassLoader that was used to create this AppContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    private final ClassLoader contextClassLoader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     * Constructor for AppContext.  This method is <i>not</i> public,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * nor should it ever be used as such.  The proper way to construct
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     * an AppContext is through the use of SunToolkit.createNewAppContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * A ThreadGroup is created for the new AppContext, a Thread is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * created within that ThreadGroup, and that Thread calls
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     * SunToolkit.createNewAppContext before calling anything else.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     * That creates both the new AppContext and its EventQueue.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     * @param   threadGroup     The ThreadGroup for the new AppContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     * @see     sun.awt.SunToolkit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * @since   1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    AppContext(ThreadGroup threadGroup) {
12412
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
   239
        numAppContexts.incrementAndGet();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        this.threadGroup = threadGroup;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        threadGroup2appContext.put(threadGroup, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        this.contextClassLoader =
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   245
             AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   246
                    public ClassLoader run() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                        return Thread.currentThread().getContextClassLoader();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                });
4365
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   250
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   251
        // Initialize push/pop lock and its condition to be used by all the
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   252
        // EventQueues within this AppContext
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   253
        Lock eventQueuePushPopLock = new ReentrantLock();
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   254
        put(EVENT_QUEUE_LOCK_KEY, eventQueuePushPopLock);
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   255
        Condition eventQueuePushPopCond = eventQueuePushPopLock.newCondition();
4ac67034e98b 4913324: Deadlock when using two event queues
art
parents: 3938
diff changeset
   256
        put(EVENT_QUEUE_COND_KEY, eventQueuePushPopCond);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   259
    private static final ThreadLocal<AppContext> threadAppContext =
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   260
            new ThreadLocal<AppContext>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
26004
7507a1b93f67 6521783: Unnecessary final modifier for a method in a final class
serb
parents: 25529
diff changeset
   262
    private static void initMainAppContext() {
18202
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   263
        // On the main Thread, we get the ThreadGroup, make a corresponding
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   264
        // AppContext, and instantiate the Java EventQueue.  This way, legacy
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   265
        // code is unaffected by the move to multiple AppContext ability.
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   266
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   267
            public Void run() {
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   268
                ThreadGroup currentThreadGroup =
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   269
                        Thread.currentThread().getThreadGroup();
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   270
                ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   271
                while (parentThreadGroup != null) {
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   272
                    // Find the root ThreadGroup to construct our main AppContext
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   273
                    currentThreadGroup = parentThreadGroup;
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   274
                    parentThreadGroup = currentThreadGroup.getParent();
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   275
                }
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   276
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   277
                mainAppContext = SunToolkit.createNewAppContext(currentThreadGroup);
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   278
                return null;
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   279
            }
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   280
        });
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   281
    }
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   282
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
     * Returns the appropriate AppContext for the caller,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     * as determined by its ThreadGroup.  If the main "system" AppContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
     * would be returned and there's an AWTSecurityManager installed, it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     * is called to get the proper AppContext based on the execution
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     * @return  the AppContext for the caller.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     * @see     java.lang.ThreadGroup
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     * @since   1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
     */
26004
7507a1b93f67 6521783: Unnecessary final modifier for a method in a final class
serb
parents: 25529
diff changeset
   294
    public static AppContext getAppContext() {
18202
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   295
        // we are standalone app, return the main app context
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   296
        if (numAppContexts.get() == 1 && mainAppContext != null) {
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   297
            return mainAppContext;
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   298
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   300
        AppContext appContext = threadAppContext.get();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   302
        if (null == appContext) {
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   303
            appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>()
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   304
            {
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   305
                public AppContext run() {
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   306
                    // Get the current ThreadGroup, and look for it and its
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   307
                    // parents in the hash from ThreadGroup to AppContext --
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   308
                    // it should be found, because we use createNewContext()
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   309
                    // when new AppContext objects are created.
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   310
                    ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   311
                    ThreadGroup threadGroup = currentThreadGroup;
18202
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   312
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   313
                    // Special case: we implicitly create the main app context
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   314
                    // if no contexts have been created yet. This covers standalone apps
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   315
                    // and excludes applets because by the time applet starts
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   316
                    // a number of contexts have already been created by the plugin.
21242
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   317
                    synchronized (getAppContextLock) {
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   318
                        if (numAppContexts.get() == 0) {
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   319
                            if (System.getProperty("javaplugin.version") == null &&
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   320
                                    System.getProperty("javawebstart.version") == null) {
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   321
                                initMainAppContext();
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   322
                            } else if (System.getProperty("javafx.version") != null &&
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   323
                                    threadGroup.getParent() != null) {
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   324
                                // Swing inside JavaFX case
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   325
                                SunToolkit.createNewAppContext();
dd191df75e13 8019623: Lack of synchronization in AppContext.getAppContext()
leonidr
parents: 19809
diff changeset
   326
                            }
18202
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   327
                        }
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   328
                    }
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   329
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   330
                    AppContext context = threadGroup2appContext.get(threadGroup);
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   331
                    while (context == null) {
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   332
                        threadGroup = threadGroup.getParent();
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   333
                        if (threadGroup == null) {
25529
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   334
                            // We've got up to the root thread group and did not find an AppContext
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   335
                            // Try to get it from the security manager
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   336
                            SecurityManager securityManager = System.getSecurityManager();
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   337
                            if (securityManager != null) {
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   338
                                ThreadGroup smThreadGroup = securityManager.getThreadGroup();
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   339
                                if (smThreadGroup != null) {
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   340
                                    /*
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   341
                                     * If we get this far then it's likely that
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   342
                                     * the ThreadGroup does not actually belong
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   343
                                     * to the applet, so do not cache it.
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   344
                                     */
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   345
                                    return threadGroup2appContext.get(smThreadGroup);
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   346
                                }
a6c103245f63 8028285: RMI Thread can no longer call out to AWT
pchelko
parents: 24538
diff changeset
   347
                            }
18202
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   348
                            return null;
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   349
                        }
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   350
                        context = threadGroup2appContext.get(threadGroup);
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   351
                    }
18202
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   352
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   353
                    // In case we did anything in the above while loop, we add
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   354
                    // all the intermediate ThreadGroups to threadGroup2appContext
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   355
                    // so we won't spin again.
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   356
                    for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   357
                        threadGroup2appContext.put(tg, context);
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   358
                    }
18202
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   359
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   360
                    // Now we're done, so we cache the latest key/value pair.
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   361
                    threadAppContext.set(context);
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   362
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   363
                    return context;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                }
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   365
            });
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
18202
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   368
        return appContext;
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   369
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
18202
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   371
    /**
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   372
     * Returns true if the specified AppContext is the main AppContext.
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   373
     *
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   374
     * @param   ctx the context to compare with the main context
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   375
     * @return  true if the specified AppContext is the main AppContext.
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   376
     * @since   1.8
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   377
     */
26004
7507a1b93f67 6521783: Unnecessary final modifier for a method in a final class
serb
parents: 25529
diff changeset
   378
    public static boolean isMainContext(AppContext ctx) {
18202
e9a6d59491ab 8004584: Augment applet contextualization
leonidr
parents: 16098
diff changeset
   379
        return (ctx != null && ctx == mainAppContext);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
26004
7507a1b93f67 6521783: Unnecessary final modifier for a method in a final class
serb
parents: 25529
diff changeset
   382
    private static AppContext getExecutionAppContext() {
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   383
        SecurityManager securityManager = System.getSecurityManager();
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   384
        if ((securityManager != null) &&
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   385
            (securityManager instanceof AWTSecurityManager))
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   386
        {
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   387
            AWTSecurityManager awtSecMgr = (AWTSecurityManager) securityManager;
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   388
            AppContext secAppContext = awtSecMgr.getAppContext();
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   389
            return secAppContext; // Return what we're told
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   390
        }
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   391
        return null;
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   392
    }
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   393
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    private long DISPOSAL_TIMEOUT = 5000;  // Default to 5-second timeout
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                                           // for disposal of all Frames
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                                           // (we wait for this time twice,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                                           // once for dispose(), and once
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                                           // to clear the EventQueue).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
    private long THREAD_INTERRUPT_TIMEOUT = 1000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                            // Default to 1-second timeout for all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                            // interrupted Threads to exit, and another
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                            // 1 second for all stopped Threads to die.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     * Disposes of this AppContext, all of its top-level Frames, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     * all Threads and ThreadGroups contained within it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
     * This method must be called from a Thread which is not contained
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
     * within this AppContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
     * @exception  IllegalThreadStateException  if the current thread is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     *                                    contained within this AppContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
     * @since      1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    public void dispose() throws IllegalThreadStateException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        // Check to be sure that the current Thread isn't in this AppContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        if (this.threadGroup.parentOf(Thread.currentThread().getThreadGroup())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            throw new IllegalThreadStateException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                "Current Thread is contained within AppContext to be disposed."
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
              );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        synchronized(this) {
18262
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   425
            if (this.state != State.VALID) {
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   426
                return; // If already disposed or being disposed, bail.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
            }
18262
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   428
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   429
            this.state = State.BEING_DISPOSED;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        final PropertyChangeSupport changeSupport = this.changeSupport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        if (changeSupport != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            changeSupport.firePropertyChange(DISPOSED_PROPERTY_NAME, false, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        // First, we post an InvocationEvent to be run on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        // EventDispatchThread which disposes of all top-level Frames and TrayIcons
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        final Object notificationLock = new Object();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        Runnable runnable = new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                Window[] windowsToDispose = Window.getOwnerlessWindows();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                for (Window w : windowsToDispose) {
108
deaaed5cedb7 6592751: EmbeddedFrame disposal is fragile and breaks clean AppContext termination
son
parents: 2
diff changeset
   446
                    try {
deaaed5cedb7 6592751: EmbeddedFrame disposal is fragile and breaks clean AppContext termination
son
parents: 2
diff changeset
   447
                        w.dispose();
deaaed5cedb7 6592751: EmbeddedFrame disposal is fragile and breaks clean AppContext termination
son
parents: 2
diff changeset
   448
                    } catch (Throwable t) {
21591
35320b590d9b 8026491: Typos in string literals
malenkov
parents: 21276
diff changeset
   449
                        log.finer("exception occurred while disposing app context", t);
108
deaaed5cedb7 6592751: EmbeddedFrame disposal is fragile and breaks clean AppContext termination
son
parents: 2
diff changeset
   450
                    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                }
11264
54f2f4c6bd30 7117008: Warnings cleanup day: reduce number of javac warnings in the sun.awt package
art
parents: 5506
diff changeset
   452
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
54f2f4c6bd30 7117008: Warnings cleanup day: reduce number of javac warnings in the sun.awt package
art
parents: 5506
diff changeset
   453
                        public Void run() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                            if (!GraphicsEnvironment.isHeadless() && SystemTray.isSupported())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                                SystemTray systemTray = SystemTray.getSystemTray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                                TrayIcon[] trayIconsToDispose = systemTray.getTrayIcons();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                                for (TrayIcon ti : trayIconsToDispose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                                    systemTray.remove(ti);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                    });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                // Alert PropertyChangeListeners that the GUI has been disposed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                if (changeSupport != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                    changeSupport.firePropertyChange(GUI_DISPOSED, false, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                synchronized(notificationLock) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                    notificationLock.notifyAll(); // Notify caller that we're done
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        synchronized(notificationLock) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            SunToolkit.postEvent(this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                notificationLock.wait(DISPOSAL_TIMEOUT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            } catch (InterruptedException e) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        // Next, we post another InvocationEvent to the end of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        // EventQueue.  When it's executed, we know we've executed all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
        // events in the queue.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        runnable = new Runnable() { public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
            synchronized(notificationLock) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                notificationLock.notifyAll(); // Notify caller that we're done
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        } };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        synchronized(notificationLock) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            SunToolkit.postEvent(this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                notificationLock.wait(DISPOSAL_TIMEOUT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            } catch (InterruptedException e) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
18262
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   499
        // We are done with posting events, so change the state to disposed
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   500
        synchronized(this) {
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   501
            this.state = State.DISPOSED;
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   502
        }
ee7c925ab7ed 8012933: Test closed/java/awt/Dialog/DialogAnotherThread/JaWSTest.java fails since jdk 7u25 b07
leonidr
parents: 18202
diff changeset
   503
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        // Next, we interrupt all Threads in the ThreadGroup
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        this.threadGroup.interrupt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            // Note, the EventDispatchThread we've interrupted may dump an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
            // InterruptedException to the console here.  This needs to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
            // fixed in the EventDispatchThread, not here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        // Next, we sleep 10ms at a time, waiting for all of the active
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        // Threads in the ThreadGroup to exit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        long startTime = System.currentTimeMillis();
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   514
        long endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        while ((this.threadGroup.activeCount() > 0) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
               (System.currentTimeMillis() < endTime)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
                Thread.sleep(10);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
            } catch (InterruptedException e) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
        // Then, we stop any remaining Threads
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        this.threadGroup.stop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        // Next, we sleep 10ms at a time, waiting for all of the active
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        // Threads in the ThreadGroup to die.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        startTime = System.currentTimeMillis();
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   529
        endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        while ((this.threadGroup.activeCount() > 0) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
               (System.currentTimeMillis() < endTime)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                Thread.sleep(10);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            } catch (InterruptedException e) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        // Next, we remove this and all subThreadGroups from threadGroup2appContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        int numSubGroups = this.threadGroup.activeGroupCount();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        if (numSubGroups > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            ThreadGroup [] subGroups = new ThreadGroup[numSubGroups];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            numSubGroups = this.threadGroup.enumerate(subGroups);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            for (int subGroup = 0; subGroup < numSubGroups; subGroup++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                threadGroup2appContext.remove(subGroups[subGroup]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        threadGroup2appContext.remove(this.threadGroup);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   548
        threadAppContext.set(null);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
        // Finally, we destroy the ThreadGroup entirely.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            this.threadGroup.destroy();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        } catch (IllegalThreadStateException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            // Fired if not all the Threads died, ignore it and proceed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        synchronized (table) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            this.table.clear(); // Clear out the Hashtable to ease garbage collection
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
12412
5966891c3f48 7080700: numAppContexts is accessed in non-threadsafe way in sun.awt.AppContext
anthony
parents: 11902
diff changeset
   561
        numAppContexts.decrementAndGet();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
        mostRecentKeyValue = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    static final class PostShutdownEventRunnable implements Runnable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        private final AppContext appContext;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
        public PostShutdownEventRunnable(AppContext ac) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
            appContext = ac;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            final EventQueue eq = (EventQueue)appContext.get(EVENT_QUEUE_KEY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
            if (eq != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                eq.postEvent(AWTAutoShutdown.getShutdownEvent());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
11264
54f2f4c6bd30 7117008: Warnings cleanup day: reduce number of javac warnings in the sun.awt package
art
parents: 5506
diff changeset
   581
    static final class CreateThreadAction implements PrivilegedAction<Thread> {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        private final AppContext appContext;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        private final Runnable runnable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        public CreateThreadAction(AppContext ac, Runnable r) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
            appContext = ac;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            runnable = r;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
11264
54f2f4c6bd30 7117008: Warnings cleanup day: reduce number of javac warnings in the sun.awt package
art
parents: 5506
diff changeset
   590
        public Thread run() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            Thread t = new Thread(appContext.getThreadGroup(), runnable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
            t.setContextClassLoader(appContext.getContextClassLoader());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
            t.setPriority(Thread.NORM_PRIORITY + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            t.setDaemon(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
            return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    static void stopEventDispatchThreads() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        for (AppContext appContext: getAppContexts()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
            if (appContext.isDisposed()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
            Runnable r = new PostShutdownEventRunnable(appContext);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
            // For security reasons EventQueue.postEvent should only be called
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
            // on a thread that belongs to the corresponding thread group.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            if (appContext != AppContext.getAppContext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                // Create a thread that belongs to the thread group associated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                // with the AppContext and invokes EventQueue.postEvent.
11264
54f2f4c6bd30 7117008: Warnings cleanup day: reduce number of javac warnings in the sun.awt package
art
parents: 5506
diff changeset
   610
                PrivilegedAction<Thread> action = new CreateThreadAction(appContext, r);
54f2f4c6bd30 7117008: Warnings cleanup day: reduce number of javac warnings in the sun.awt package
art
parents: 5506
diff changeset
   611
                Thread thread = AccessController.doPrivileged(action);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
                thread.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
                r.run();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
    private MostRecentKeyValue mostRecentKeyValue = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    private MostRecentKeyValue shadowMostRecentKeyValue = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
     * Returns the value to which the specified key is mapped in this context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
     * @param   key   a key in the AppContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
     * @return  the value to which the key is mapped in this AppContext;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     *          <code>null</code> if the key is not mapped to any value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     * @see     #put(Object, Object)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
     * @since   1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
    public Object get(Object key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
         * The most recent reference should be updated inside a synchronized
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
         * block to avoid a race when put() and get() are executed in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
         * parallel on different threads.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        synchronized (table) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
            // Note: this most recent key/value caching is thread-hot.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            // A simple test using SwingSet found that 72% of lookups
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            // were matched using the most recent key/value.  By instantiating
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
            // a simple MostRecentKeyValue object on cache misses, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
            // cache hits can be processed without synchronization.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
            MostRecentKeyValue recent = mostRecentKeyValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            if ((recent != null) && (recent.key == key)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                return recent.value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
            Object value = table.get(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
            if(mostRecentKeyValue == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                mostRecentKeyValue = new MostRecentKeyValue(key, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                shadowMostRecentKeyValue = new MostRecentKeyValue(key, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
                MostRecentKeyValue auxKeyValue = mostRecentKeyValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                shadowMostRecentKeyValue.setPair(key, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
                mostRecentKeyValue = shadowMostRecentKeyValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
                shadowMostRecentKeyValue = auxKeyValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
            return value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
     * Maps the specified <code>key</code> to the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
     * <code>value</code> in this AppContext.  Neither the key nor the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
     * value can be <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
     * The value can be retrieved by calling the <code>get</code> method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
     * with a key that is equal to the original key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     * @param      key     the AppContext key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
     * @param      value   the value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
     * @return     the previous value of the specified key in this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
     *             AppContext, or <code>null</code> if it did not have one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
     * @exception  NullPointerException  if the key or value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
     *               <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
     * @see     #get(Object)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
     * @since   1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
    public Object put(Object key, Object value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
        synchronized (table) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
            MostRecentKeyValue recent = mostRecentKeyValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            if ((recent != null) && (recent.key == key))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                recent.value = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            return table.put(key, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
     * Removes the key (and its corresponding value) from this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
     * AppContext. This method does nothing if the key is not in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
     * AppContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
     * @param   key   the key that needs to be removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     * @return  the value to which the key had been mapped in this AppContext,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
     *          or <code>null</code> if the key did not have a mapping.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
     * @since   1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
    public Object remove(Object key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        synchronized (table) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
            MostRecentKeyValue recent = mostRecentKeyValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
            if ((recent != null) && (recent.key == key))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
                recent.value = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
            return table.remove(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
     * Returns the root ThreadGroup for all Threads contained within
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
     * this AppContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
     * @since   1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
    public ThreadGroup getThreadGroup() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        return threadGroup;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
     * Returns the context ClassLoader that was used to create this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
     * AppContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
     * @see java.lang.Thread#getContextClassLoader
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
    public ClassLoader getContextClassLoader() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        return contextClassLoader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
     * Returns a string representation of this AppContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
     * @since   1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
     */
113
d35e2fc341c7 6636370: minor corrections and simplification of code in AppContext
son
parents: 112
diff changeset
   731
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
        return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
     * Returns an array of all the property change listeners
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
     * registered on this component.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
     * @return all of this component's <code>PropertyChangeListener</code>s
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
     *         or an empty array if no property change
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
     *         listeners are currently registered
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
     * @see      #addPropertyChangeListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
     * @see      #removePropertyChangeListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
     * @see      #getPropertyChangeListeners(java.lang.String)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
     * @see      java.beans.PropertyChangeSupport#getPropertyChangeListeners
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
     * @since    1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
    public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        if (changeSupport == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
            return new PropertyChangeListener[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        return changeSupport.getPropertyChangeListeners();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
     * Adds a PropertyChangeListener to the listener list for a specific
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
     * property. The specified property may be one of the following:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
     * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
     *    <li>if this AppContext is disposed ("disposed")</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
     * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
     *    <li>if this AppContext's unowned Windows have been disposed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
     *    ("guidisposed").  Code to cleanup after the GUI is disposed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
     *    (such as LookAndFeel.uninitialize()) should execute in response to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
     *    this property being fired.  Notifications for the "guidisposed"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
     *    property are sent on the event dispatch thread.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
     * If listener is null, no exception is thrown and no action is performed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
     * @param propertyName one of the property names listed above
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
     * @param listener the PropertyChangeListener to be added
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
     * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
     * @see #getPropertyChangeListeners(java.lang.String)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
     * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    public synchronized void addPropertyChangeListener(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                             String propertyName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                             PropertyChangeListener listener) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
        if (listener == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
        if (changeSupport == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
            changeSupport = new PropertyChangeSupport(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
        changeSupport.addPropertyChangeListener(propertyName, listener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
     * Removes a PropertyChangeListener from the listener list for a specific
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
     * property. This method should be used to remove PropertyChangeListeners
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
     * that were registered for a specific bound property.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
     * If listener is null, no exception is thrown and no action is performed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
     * @param propertyName a valid property name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
     * @param listener the PropertyChangeListener to be removed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
     * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
     * @see #getPropertyChangeListeners(java.lang.String)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
     * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
    public synchronized void removePropertyChangeListener(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
                             String propertyName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
                             PropertyChangeListener listener) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        if (listener == null || changeSupport == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
        changeSupport.removePropertyChangeListener(propertyName, listener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
     * Returns an array of all the listeners which have been associated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
     * with the named property.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
     * @return all of the <code>PropertyChangeListeners</code> associated with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
     *         the named property or an empty array if no listeners have
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
     *         been added
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
     * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
     * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
     * @see #getPropertyChangeListeners
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
     * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
    public synchronized PropertyChangeListener[] getPropertyChangeListeners(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
                                                        String propertyName) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
        if (changeSupport == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
            return new PropertyChangeListener[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
        return changeSupport.getPropertyChangeListeners(propertyName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
    }
11896
eb4d5334fccf 6351654: Problem with java/classes_util_i18n
okutsu
parents: 5506
diff changeset
   835
eb4d5334fccf 6351654: Problem with java/classes_util_i18n
okutsu
parents: 5506
diff changeset
   836
    // Set up JavaAWTAccess in SharedSecrets
eb4d5334fccf 6351654: Problem with java/classes_util_i18n
okutsu
parents: 5506
diff changeset
   837
    static {
eb4d5334fccf 6351654: Problem with java/classes_util_i18n
okutsu
parents: 5506
diff changeset
   838
        sun.misc.SharedSecrets.setJavaAWTAccess(new sun.misc.JavaAWTAccess() {
20792
8d5c16e4f64c 8026404: Logging in Applet can trigger ACE: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
dfuchs
parents: 19809
diff changeset
   839
            private boolean hasRootThreadGroup(final AppContext ecx) {
8d5c16e4f64c 8026404: Logging in Applet can trigger ACE: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
dfuchs
parents: 19809
diff changeset
   840
                return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
8d5c16e4f64c 8026404: Logging in Applet can trigger ACE: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
dfuchs
parents: 19809
diff changeset
   841
                    @Override
8d5c16e4f64c 8026404: Logging in Applet can trigger ACE: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
dfuchs
parents: 19809
diff changeset
   842
                    public Boolean run() {
8d5c16e4f64c 8026404: Logging in Applet can trigger ACE: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
dfuchs
parents: 19809
diff changeset
   843
                        return ecx.threadGroup.getParent() == null;
8d5c16e4f64c 8026404: Logging in Applet can trigger ACE: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
dfuchs
parents: 19809
diff changeset
   844
                    }
8d5c16e4f64c 8026404: Logging in Applet can trigger ACE: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
dfuchs
parents: 19809
diff changeset
   845
                });
8d5c16e4f64c 8026404: Logging in Applet can trigger ACE: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
dfuchs
parents: 19809
diff changeset
   846
            }
8d5c16e4f64c 8026404: Logging in Applet can trigger ACE: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
dfuchs
parents: 19809
diff changeset
   847
19809
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   848
            /**
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   849
             * Returns the AppContext used for applet logging isolation, or null if
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   850
             * the default global context can be used.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   851
             * If there's no applet, or if the caller is a stand alone application,
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   852
             * or running in the main app context, returns null.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   853
             * Otherwise, returns the AppContext of the calling applet.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   854
             * @return null if the global default context can be used,
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   855
             *         an AppContext otherwise.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   856
             **/
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   857
            public Object getAppletContext() {
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   858
                // There's no AppContext: return null.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   859
                // No need to call getAppContext() if numAppContext == 0:
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   860
                // it means that no AppContext has been created yet, and
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   861
                // we don't want to trigger the creation of a main app
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   862
                // context since we don't need it.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   863
                if (numAppContexts.get() == 0) return null;
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   864
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   865
                // Get the context from the security manager
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   866
                AppContext ecx = getExecutionAppContext();
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   867
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   868
                // Not sure we really need to re-check numAppContexts here.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   869
                // If all applets have gone away then we could have a
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   870
                // numAppContexts coming back to 0. So we recheck
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   871
                // it here because we don't want to trigger the
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   872
                // creation of a main AppContext in that case.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   873
                // This is probably not 100% MT-safe but should reduce
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   874
                // the window of opportunity in which that issue could
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   875
                // happen.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   876
                if (numAppContexts.get() > 0) {
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   877
                   // Defaults to thread group caching.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   878
                   // This is probably not required as we only really need
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   879
                   // isolation in a deployed applet environment, in which
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   880
                   // case ecx will not be null when we reach here
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   881
                   // However it helps emulate the deployed environment,
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   882
                   // in tests for instance.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   883
                   ecx = ecx != null ? ecx : getAppContext();
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   884
                }
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   885
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   886
                // getAppletContext() may be called when initializing the main
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   887
                // app context - in which case mainAppContext will still be
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   888
                // null. To work around this issue we simply use
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   889
                // AppContext.threadGroup.getParent() == null instead, since
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   890
                // mainAppContext is the only AppContext which should have
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   891
                // the root TG as its thread group.
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   892
                // See: JDK-8023258
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   893
                final boolean isMainAppContext = ecx == null
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   894
                    || mainAppContext == ecx
20792
8d5c16e4f64c 8026404: Logging in Applet can trigger ACE: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
dfuchs
parents: 19809
diff changeset
   895
                    || mainAppContext == null && hasRootThreadGroup(ecx);
19809
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   896
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   897
                return isMainAppContext ? null : ecx;
16098
9001e536ab4e 6664509: Add logging context
mchung
parents: 12412
diff changeset
   898
            }
19809
dc0480c1b36c 8019853: Break logging and AWT circular dependency
dfuchs
parents: 19174
diff changeset
   899
11896
eb4d5334fccf 6351654: Problem with java/classes_util_i18n
okutsu
parents: 5506
diff changeset
   900
        });
eb4d5334fccf 6351654: Problem with java/classes_util_i18n
okutsu
parents: 5506
diff changeset
   901
    }
23666
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   902
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   903
    public static <T> T getSoftReferenceValue(Object key,
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   904
            Supplier<T> supplier) {
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   905
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   906
        final AppContext appContext = AppContext.getAppContext();
24538
25bf8153fbfe 8039642: Fix raw and unchecked warnings in sun.awt.*
henryjen
parents: 23666
diff changeset
   907
        @SuppressWarnings("unchecked")
23666
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   908
        SoftReference<T> ref = (SoftReference<T>) appContext.get(key);
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   909
        if (ref != null) {
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   910
            final T object = ref.get();
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   911
            if (object != null) {
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   912
                return object;
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   913
            }
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   914
        }
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   915
        final T object = supplier.get();
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   916
        ref = new SoftReference<>(object);
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   917
        appContext.put(key, ref);
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   918
        return object;
a54bf43b5ba9 8035069: [macosx] Loading resolution variants by demand
alexsch
parents: 23010
diff changeset
   919
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
final class MostRecentKeyValue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
    Object key;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
    Object value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
    MostRecentKeyValue(Object k, Object v) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
        key = k;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
        value = v;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
    void setPair(Object k, Object v) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
        key = k;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
        value = v;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
}