Difference between revisions of "JFace Data Binding/Realm"

From Eclipsepedia

Jump to: navigation, search
m (provided a meaning for Realm for non English readers)
 
(4 intermediate revisions by one user not shown)
Line 1: Line 1:
Realm is the core concept of [[JFace Data Binding]] in regards to synchronization.  A realm can be thought of as a special thread, or a lock, that serializes access to a set of [[Observable|observables]] in that realm.  Each observable belongs to a Realm.  It can only be accessed from that realm, and it will always fire change events on that realm.  One important example of a realm is the SWT UI thread.  Like for the SWT UI thread, you can execute code within a realm by using Realm.asyncExec(); in fact, the SWT realm implementation just delegates to Display.asyncExec().  This means that while the data binding framework can be used in a multi-threaded environment, each observable is essentially single-threaded. Java bean observables implement this contract on the observable side, but don't require it on the Java beans side: Even if a bean fires a PropertyChangeEvent on a different thread, the change events originating from the observable will happen within its realm.  To bridge between observables in different realms, use a data binding context - you can bind two observables even if they belong to different realms and the bindings take care of this for you by using Realm.asyncExec() where necessary.
+
{{JFace Data Binding}}
 +
Realm ([http://en.wikipedia.org/wiki/Realm "Kingdom"]) is the core concept of [[JFace Data Binding]] in regards to synchronization.  A realm can be thought of as a special thread, or a lock, that serializes access to a set of [[Observable|observables]] in that realm.  Each observable belongs to a Realm.  It can only be accessed from that realm, and it will always fire change events on that realm.  One important example of a realm is the SWT UI thread.  Like for the SWT UI thread, you can execute code within a realm by using Realm.asyncExec(); in fact, the SWT realm implementation just delegates to Display.asyncExec().  This means that while the data binding framework can be used in a multi-threaded environment, each observable is essentially single-threaded. Java bean observables implement this contract on the observable side, but don't require it on the Java beans side: Even if a bean fires a PropertyChangeEvent on a different thread, the change events originating from the observable will happen within its realm.  To bridge between observables in different realms, use a data binding context - you can bind two observables even if they belong to different realms and the bindings take care of this for you by using Realm.asyncExec() where necessary.
  
 
== Unit Testing ==
 
== Unit Testing ==
Line 42: Line 43:
 
     }
 
     }
 
  }
 
  }
 +
 +
public class SampleTestCase extends TestCase {
 +
    private DefaultRealm realm;
 +
   
 +
    /**
 +
      * Creates a new default realm for every test.
 +
      */
 +
    protected void setUp() throws Exception {
 +
        super.setUp();
 +
        realm = new DefaultRealm();
 +
    }
 +
   
 +
    /**
 +
      * Removes the default realm.
 +
      */
 +
    protected void tearDown() throws Exception {
 +
        super.tearDown();
 +
        realm.dispose();
 +
    }
 +
}
 +
 +
[[Category:Data Binding]]

Latest revision as of 17:21, 22 September 2009

JFace Data Binding
Home
How to Contribute
FAQ
Snippets
Concepts
Binding
Converter
Observable
Realm

Realm ("Kingdom") is the core concept of JFace Data Binding in regards to synchronization. A realm can be thought of as a special thread, or a lock, that serializes access to a set of observables in that realm. Each observable belongs to a Realm. It can only be accessed from that realm, and it will always fire change events on that realm. One important example of a realm is the SWT UI thread. Like for the SWT UI thread, you can execute code within a realm by using Realm.asyncExec(); in fact, the SWT realm implementation just delegates to Display.asyncExec(). This means that while the data binding framework can be used in a multi-threaded environment, each observable is essentially single-threaded. Java bean observables implement this contract on the observable side, but don't require it on the Java beans side: Even if a bean fires a PropertyChangeEvent on a different thread, the change events originating from the observable will happen within its realm. To bridge between observables in different realms, use a data binding context - you can bind two observables even if they belong to different realms and the bindings take care of this for you by using Realm.asyncExec() where necessary.

[edit] Unit Testing

When writing unit tests for observables or bindings it is difficult to set the default Realm without wrapping the test code in a Runnable and invoking Realm.runWithDefault(Realm realm, Runnable runnable). The following implementation can be used as a stub Realm for unit testing purposes and fits into the setUp() and tearDown() testing paradigm.

/**
 * Simple realm implementation that will set itself as default when constructed. Invoke
 * {@link #dispose()} to remove the realm from being the default. Does not support asyncExec(...).
 */
public class DefaultRealm extends Realm {
    private Realm previousRealm;

    public DefaultRealm() {
        previousRealm = super.setDefault(this);
    }

    /**
     * @return always returns true
     */
    public boolean isCurrent() {
        return true;
    }

    protected void syncExec(Runnable runnable) {
        runnable.run();
    }

    /**
     * @throws UnsupportedOperationException
     */
    public void asyncExec(Runnable runnable) {
        throw new UnsupportedOperationException("asyncExec is unsupported");
    }

    /**
     * Removes the realm from being the current and sets the previous realm to the default.
     */
    public void dispose() {
        if (getDefault() == this) {
            setDefault(previousRealm);
        }
    }
}
public class SampleTestCase extends TestCase {
    private DefaultRealm realm;
    
    /**
     * Creates a new default realm for every test.
     */
    protected void setUp() throws Exception {
        super.setUp();
        realm = new DefaultRealm();
    }
    
    /**
     * Removes the default realm.
     */
    protected void tearDown() throws Exception {
        super.tearDown();
        realm.dispose();
    }
}