1/*
2 * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package sun.awt.windows;
26
27import java.util.Map;
28import java.util.WeakHashMap;
29
30abstract class WObjectPeer {
31
32    static {
33        initIDs();
34    }
35
36    // The Windows handle for the native widget.
37    volatile long pData;
38    // if the native peer has been destroyed
39    private volatile boolean destroyed;
40    // The associated AWT object.
41    volatile Object target;
42
43    private volatile boolean disposed;
44
45    // set from JNI if any errors in creating the peer occur
46    volatile Error createError = null;
47
48    // used to synchronize the state of this peer
49    private final Object stateLock = new Object();
50
51    private volatile Map<WObjectPeer, WObjectPeer> childPeers;
52
53    public static WObjectPeer getPeerForTarget(Object t) {
54        WObjectPeer peer = (WObjectPeer) WToolkit.targetToPeer(t);
55        return peer;
56    }
57
58    public long getData() {
59        return pData;
60    }
61
62    public Object getTarget() {
63        return target;
64    }
65
66    public final Object getStateLock() {
67        return stateLock;
68    }
69
70    /*
71     * Subclasses should override disposeImpl() instead of dispose(). Client
72     * code should always invoke dispose(), never disposeImpl().
73     */
74    protected abstract void disposeImpl();
75    public final void dispose() {
76        boolean call_disposeImpl = false;
77
78        synchronized (this) {
79            if (!disposed) {
80                disposed = call_disposeImpl = true;
81            }
82        }
83
84        if (call_disposeImpl) {
85            if (childPeers != null) {
86                disposeChildPeers();
87            }
88            disposeImpl();
89        }
90    }
91    protected final boolean isDisposed() {
92        return disposed;
93    }
94
95    /**
96     * Initialize JNI field and method IDs
97     */
98    private static native void initIDs();
99
100    // if a child peer existence depends on this peer, add it to this collection
101    final void addChildPeer(WObjectPeer child) {
102        synchronized (getStateLock()) {
103            if (childPeers == null) {
104                childPeers = new WeakHashMap<>();
105            }
106            if (isDisposed()) {
107                throw new IllegalStateException("Parent peer is disposed");
108            }
109            childPeers.put(child, this);
110        }
111    }
112
113    // called to dispose dependent child peers
114    private void disposeChildPeers() {
115        synchronized (getStateLock()) {
116            for (WObjectPeer child : childPeers.keySet()) {
117                if (child != null) {
118                    try {
119                        child.dispose();
120                    }
121                    catch (Exception e) {
122                        // ignored
123                    }
124                }
125            }
126        }
127    }
128}
129