Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Bokowski2007-10-29 17:09:36 +0000
committerBoris Bokowski2007-10-29 17:09:36 +0000
commit66ae2b88c8d5c9a37cc19c16bc42bd290fed4b7b (patch)
treebca69374ae1ef801da8e2ff5b10a9fe037624218 /bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value
parentc3973fcd911aa89b19fb6d5af2141d135b106bba (diff)
downloadeclipse.platform.ui-66ae2b88c8d5c9a37cc19c16bc42bd290fed4b7b.tar.gz
eclipse.platform.ui-66ae2b88c8d5c9a37cc19c16bc42bd290fed4b7b.tar.xz
eclipse.platform.ui-66ae2b88c8d5c9a37cc19c16bc42bd290fed4b7b.zip
Fix for Bug 198211 [DataBinding] ComputedValue invokes doGetValue outside realm when adding a change listener
Diffstat (limited to 'bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value')
-rw-r--r--bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/ComputedValue.java48
1 files changed, 37 insertions, 11 deletions
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/ComputedValue.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/ComputedValue.java
index a113f7f83d2..18168098510 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/ComputedValue.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/ComputedValue.java
@@ -40,11 +40,10 @@ public abstract class ComputedValue extends AbstractObservableValue {
private Object cachedValue = null;
/**
- * Dependencies list. This is a collection that contains no duplicates. It
- * is normally an ArrayList to conserve memory, but if it ever grows above a
- * certain number of elements, a HashSet is substited to conserve runtime.
+ * Array of observables this computed value depends on. This field has
+ * a value of <code>null</code> if we are not currently listening.
*/
- private IObservable[] dependencies = new IObservable[0];
+ private IObservable[] dependencies = null;
/**
*
@@ -183,11 +182,14 @@ public abstract class ComputedValue extends AbstractObservableValue {
*/
private void stopListening() {
// Stop listening for dependency changes.
- for (int i = 0; i < dependencies.length; i++) {
- IObservable observable = dependencies[i];
-
- observable.removeChangeListener(privateInterface);
- observable.removeStaleListener(privateInterface);
+ if (dependencies != null) {
+ for (int i = 0; i < dependencies.length; i++) {
+ IObservable observable = dependencies[i];
+
+ observable.removeChangeListener(privateInterface);
+ observable.removeStaleListener(privateInterface);
+ }
+ dependencies = null;
}
}
@@ -200,11 +202,35 @@ public abstract class ComputedValue extends AbstractObservableValue {
public Object getValueType() {
return valueType;
}
+
+ // this method exists here so that we can call it from the runnable below.
+ protected boolean hasListeners() {
+ return super.hasListeners();
+ }
public synchronized void addChangeListener(IChangeListener listener) {
super.addChangeListener(listener);
- // If somebody is listening, we need to make sure we attach our own
- // listeners
+ // Some clients just add a listener and expect to get notified even if
+ // they never called getValue(), so we have to call getValue() ourselves
+ // here to be sure. Need to be careful about realms though, this method
+ // can be called outside of our realm.
+ // See also bug 198211. If a client calls this outside of our realm,
+ // they may receive change notifications before the runnable below has
+ // been executed. It is their job to figure out what to do with those
+ // notifications.
+ getRealm().exec(new Runnable() {
+ public void run() {
+ if (dependencies == null) {
+ // We are not currently listening.
+ if (hasListeners()) {
+ // But someone is listening for changes. Call getValue()
+ // to make sure we start listening to the observables we
+ // depend on.
+ getValue();
+ }
+ }
+ }
+ });
getValue();
}

Back to the top