annotate org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/Realm.d @ 95:6208d4f6a277

Added trees for databinding.beans and observable
author Frank Benoit <benoit@tionex.de>
date Tue, 21 Apr 2009 10:55:51 +0200
parents
children b74ac5dfcc06
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
95
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1 /*******************************************************************************
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
2 * Copyright (c) 2006, 2007 IBM Corporation and others.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
3 * All rights reserved. This program and the accompanying materials
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
4 * are made available under the terms of the Eclipse Public License v1.0
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
5 * which accompanies this distribution, and is available at
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
6 * http://www.eclipse.org/legal/epl-v10.html
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
7 *
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
8 * Contributors:
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
9 * IBM Corporation - initial API and implementation
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
10 * Brad Reynolds - bug 168153
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
11 *******************************************************************************/
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
12
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
13 package org.eclipse.core.databinding.observable;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
14
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
15 import org.eclipse.core.databinding.Binding;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
16 import org.eclipse.core.databinding.util.Policy;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
17 import org.eclipse.core.internal.databinding.Queue;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
18 import org.eclipse.core.runtime.ISafeRunnable;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
19 import org.eclipse.core.runtime.IStatus;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
20 import org.eclipse.core.runtime.SafeRunner;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
21 import org.eclipse.core.runtime.Status;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
22
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
23 /**
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
24 * A realm defines a context from which objects implementing {@link IObservable}
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
25 * must be accessed, and on which these objects will notify their listeners. To
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
26 * bridge between observables from different realms, subclasses of
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
27 * {@link Binding} can be used.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
28 * <p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
29 * A block of code is said to be executing within a realm if calling
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
30 * {@link #isCurrent()} from that block returns true. Code reached by calling
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
31 * methods from that block will execute within the same realm, with the
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
32 * exception of methods on this class that can be used to execute code within a
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
33 * specific realm. Clients can use {@link #syncExeccast(Runnable)},
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
34 * {@link #asyncExeccast(Runnable)}, or {@link #execcast(Runnable)} to execute a
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
35 * runnable within this realm. Note that using {@link #syncExeccast(Runnable)} can
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
36 * lead to deadlocks and should be avoided if the current thread holds any
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
37 * locks.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
38 * </p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
39 * <p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
40 * It is instructive to think about possible implementations of Realm: It can be
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
41 * based on executing on a designated thread such as a UI thread, or based on
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
42 * holding a lock. In the former case, calling syncExec on a realm that is not
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
43 * the current realm will execute the given runnable on a different thread (the
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
44 * designated thread). In the latter case, calling syncExec may execute the
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
45 * given runnable on the calling thread, but calling
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
46 * {@link #asyncExeccast(Runnable)} will execute the given runnable on a different
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
47 * thread. Therefore, no assumptions can be made about the thread that will
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
48 * execute arguments to {@link #asyncExeccast(Runnable)},
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
49 * {@link #syncExeccast(Runnable)}, or {@link #execcast(Runnable)}.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
50 * </p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
51 * <p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
52 * It is possible that a block of code is executing within more than one realm.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
53 * This can happen for implementations of Realm that are based on holding a lock
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
54 * but don't use a separate thread to run runnables given to
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
55 * {@link #syncExeccast(Runnable)}. Realm implementations of this kind should be
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
56 * appropriately documented because it increases the opportunity for deadlock.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
57 * </p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
58 * <p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
59 * Some implementations of {@link IObservable} provide constructors which do not
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
60 * take a Realm argument and are specified to create the observable instance
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
61 * with the current default realm. The default realm can be set for the
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
62 * currently executing thread by using {@link #runWithDefault(Realm, Runnable)}.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
63 * Note that the default realm does not have to be the current realm.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
64 * </p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
65 * <p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
66 * Subclasses must override at least one of asyncExec()/syncExec(). For realms
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
67 * based on a designated thread, it may be easier to implement asyncExec and
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
68 * keep the default implementation of syncExec. For realms based on holding a
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
69 * lock, it may be easier to implement syncExec and keep the default
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
70 * implementation of asyncExec.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
71 * </p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
72 *
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
73 * @since 1.0
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
74 *
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
75 * @see IObservable
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
76 */
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
77 public abstract class Realm {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
78
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
79 private static ThreadLocal defaultRealm = new ThreadLocal();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
80
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
81 /**
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
82 * Returns the default realm for the calling thread, or <code>null</code>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
83 * if no default realm has been set.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
84 *
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
85 * @return the default realm, or <code>null</code>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
86 */
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
87 public static Realm getDefault() {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
88 return cast(Realm) defaultRealm.get();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
89 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
90
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
91 /**
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
92 * Sets the default realm for the calling thread, returning the current
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
93 * default thread. This method is inherently unsafe, it is recommended to
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
94 * use {@link #runWithDefault(Realm, Runnable)} instead. This method is
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
95 * exposed to subclasses to facilitate testing.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
96 *
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
97 * @param realm
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
98 * the new default realm, or <code>null</code>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
99 * @return the previous default realm, or <code>null</code>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
100 */
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
101 protected static Realm setDefault(Realm realm) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
102 Realm oldValue = getDefault();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
103 defaultRealm.set(realm);
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
104 return oldValue;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
105 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
106
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
107 /**
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
108 * @return true if the caller is executing in this realm. This method must
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
109 * not have side-effects (such as, for example, implicitly placing
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
110 * the caller in this realm).
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
111 */
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
112 abstract public bool isCurrent();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
113
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
114 private Thread workerThread;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
115
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
116 Queue workQueue = new Queue();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
117
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
118 /**
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
119 * Runs the given runnable. If an exception occurs within the runnable, it
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
120 * is logged and not re-thrown. If the runnable implements
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
121 * {@link ISafeRunnable}, the exception is passed to its
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
122 * <code>handleException<code> method.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
123 *
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
124 * @param runnable
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
125 */
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
126 protected static void safeRun(final Runnable runnable) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
127 ISafeRunnable safeRunnable;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
128 if ( null !is cast(ISafeRunnable)runnable ) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
129 safeRunnable = cast(ISafeRunnable) runnable;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
130 } else {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
131 safeRunnable = new class() ISafeRunnable {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
132 public void handleException(Throwable exception) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
133 Policy
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
134 .getLog()
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
135 .log(
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
136 new Status(
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
137 IStatus.ERROR,
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
138 Policy.JFACE_DATABINDING,
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
139 IStatus.OK,
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
140 "Unhandled exception: " + exception.getMessage(), exception)); //$NON-NLS-1$
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
141 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
142 public void run() {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
143 runnable.run();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
144 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
145 };
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
146 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
147 SafeRunner.run(safeRunnable);
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
148 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
149
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
150 /**
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
151 * Causes the <code>run()</code> method of the runnable to be invoked from
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
152 * within this realm. If the caller is executing in this realm, the
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
153 * runnable's run method is invoked directly, otherwise it is run at the
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
154 * next reasonable opportunity using asyncExec.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
155 * <p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
156 * If the given runnable is an instance of {@link ISafeRunnable}, its
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
157 * exception handler method will be called if any exceptions occur while
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
158 * running it. Otherwise, the exception will be logged.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
159 * </p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
160 *
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
161 * @param runnable
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
162 */
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
163 public void exec(Runnable runnable) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
164 if (isCurrent()) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
165 safeRun(runnable);
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
166 } else {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
167 asyncExec(runnable);
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
168 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
169 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
170
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
171 /**
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
172 * Causes the <code>run()</code> method of the runnable to be invoked from
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
173 * within this realm at the next reasonable opportunity. The caller of this
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
174 * method continues to run in parallel, and is not notified when the
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
175 * runnable has completed.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
176 * <p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
177 * If the given runnable is an instance of {@link ISafeRunnable}, its
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
178 * exception handler method will be called if any exceptions occur while
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
179 * running it. Otherwise, the exception will be logged.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
180 * </p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
181 * <p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
182 * Subclasses should use {@link #safeRuncast(Runnable)} to run the runnable.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
183 * </p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
184 *
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
185 * @param runnable
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
186 */
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
187 public void asyncExec(Runnable runnable) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
188 synchronized (workQueue) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
189 ensureWorkerThreadIsRunning();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
190 workQueue.enqueue(runnable);
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
191 workQueue.notifyAll();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
192 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
193 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
194
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
195 /**
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
196 *
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
197 */
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
198 private void ensureWorkerThreadIsRunning() {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
199 if (workerThread is null) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
200 workerThread = new class() Thread {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
201 public void run() {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
202 try {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
203 while (true) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
204 Runnable work = null;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
205 synchronized (workQueue) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
206 while (workQueue.isEmpty()) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
207 workQueue.wait();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
208 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
209 work = cast(Runnable) workQueue.dequeue();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
210 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
211 syncExec(work);
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
212 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
213 } catch (InterruptedException e) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
214 // exit
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
215 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
216 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
217 };
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
218 workerThread.start();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
219 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
220 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
221
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
222 /**
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
223 * Causes the <code>run()</code> method of the runnable to be invoked from
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
224 * within this realm at the next reasonable opportunity. This method is
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
225 * blocking the caller until the runnable completes.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
226 * <p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
227 * If the given runnable is an instance of {@link ISafeRunnable}, its
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
228 * exception handler method will be called if any exceptions occur while
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
229 * running it. Otherwise, the exception will be logged.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
230 * </p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
231 * <p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
232 * Subclasses should use {@link #safeRuncast(Runnable)} to run the runnable.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
233 * </p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
234 * <p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
235 * Note: This class is not meant to be called by clients and therefore has
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
236 * only protected access.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
237 * </p>
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
238 *
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
239 * @param runnable
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
240 */
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
241 protected void syncExec(Runnable runnable) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
242 SyncRunnable syncRunnable = new SyncRunnable(runnable);
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
243 asyncExec(syncRunnable);
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
244 synchronized (syncRunnable) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
245 while (!syncRunnable.hasRun) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
246 try {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
247 syncRunnable.wait();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
248 } catch (InterruptedException e) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
249 Thread.currentThread().interrupt();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
250 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
251 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
252 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
253 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
254
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
255 static class SyncRunnable : Runnable {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
256 bool hasRun = false;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
257
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
258 private Runnable runnable;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
259
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
260 this(Runnable runnable) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
261 this.runnable = runnable;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
262 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
263
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
264 public void run() {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
265 try {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
266 safeRun(runnable);
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
267 } finally {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
268 synchronized (this) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
269 hasRun = true;
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
270 this.notifyAll();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
271 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
272 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
273 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
274 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
275
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
276 /**
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
277 * Sets the provided <code>realm</code> as the default for the duration of
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
278 * {@link Runnable#run()} and resets the previous realm after completion.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
279 * Note that this will not set the given realm as the current realm.
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
280 *
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
281 * @param realm
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
282 * @param runnable
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
283 */
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
284 public static void runWithDefault(Realm realm, Runnable runnable) {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
285 Realm oldRealm = Realm.getDefault();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
286 try {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
287 defaultRealm.set(realm);
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
288 runnable.run();
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
289 } finally {
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
290 defaultRealm.set(oldRealm);
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
291 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
292 }
6208d4f6a277 Added trees for databinding.beans and observable
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
293 }