E4 modeled workbench and wazaabi : the contact demo
The idea of integrating wazaabi UIs seamlessly into E4 modeled workbench ran through my mind when I discovered it.
This post shows and explains my recent work on this topic.

Extending the morkbench metamodel
Wazaabi 2.0 is a declarative UI framework based on live EMF models, therefore integrating wazaabi into E4 modeled workbench is done by extending the existing workbench metamodel.
I created WazaabiMItemPart, a new eClass deriving from MItemPart. This eClass adds some features :
- component: this reference is the connection point with wazaabi model displayed by this workbench part. The component might contain a single button, table or a container of graphical components.
- selection: this feature is a pure java object, and receives the current selection as triggered by IEclipseContext changes. The idea of getting selection changes here is to allow addition(s) of EMF adapter(s) or to connect it with other declarative databinding engine (like wazaabi’s one)
- input: this feature is a pure java object too and receives the input value when E4 injection mechanism calls setInput on selection changes. Like selection, it allows EMF adapter addition or connection to wazaabi binding engine.
- managerURI: this string property connects this instance of WazaabiMItemPart to a java class which can contain two methods : activate and deactivate. When the part is created, an object of this class (the manager) is instanciated and the activate method is called with the part given as parameter, when the part is disposed, the deactivate method is called. This methods gives a chance to programers to intercept lifecycle events.
Building the demo
This demo has not been built from scratch, I reused the existing E4 swt demo contact written by Kai Toedter.
Step one : removing java UI and inserting declarative UIs
The figure below shows the two WazaabiMItemParts. The contact list contains one single table, the detail form contains a composite which contains all the form components. Only this two points have been changed from the former SWT Application.xmi.
Step two : the managers
The DetailsManager
The DetailsManager is attached to the WazaabiMItemPart by setting managerURI to
“platform:/plugin/org.eclipse.e4.wazaabi.swtbridge.demo.contacts/…
…org.eclipse.e4.wazaabi.swtbridge.demo.contacts.managers.DetailsManager”
The activate method adds a new instance of the InputAdapter to the part. Please note, that only one instance should be added per part, otherwise, the setInput method will be called more than once when the selection changes.
Managers may be attached to more than one WazaabiMItemPart, then each addition or removal of adapter must include verifications : part.equals(adapter.getTarget())
Please note, that, nothing is the manager code is related to underlying graphical platform. The programer deals only with EMF concepts.
No SWT or E4 knowledge is required at this time.
public class DetailsManager {
/**
* The InputAdapter is attached to the WazaabiMItemPart and tracks the input
* changes. When the input changes, the component is update using binding
* informations.
*/
private class InputAdapter extends AdapterImpl {
private final WazaabiMItemPart<?> part;
public InputAdapter(WazaabiMItemPart<?> part) {
this.part = part;
}
public void notifyChanged(Notification msg) {
if (msg.getFeatureID(Selectable.class) == ApplicationPackage.WAZAABI_MITEM_PART__INPUT)
BindingUtils.update((Contact) msg.getNewValue(), part
.getComponent());
}
public boolean isAdapterForType(Object type) {
return this.getClass().equals(type);
}
};
/**
* Adds a new InputAdapter to the part, ensuring that there is only one
* attached to the same part.
*
* @param part
*/
public void activate(WazaabiMItemPart<?> part) {
// since activate method could called multiple times on the same part,
// we must be sure that the InputAdapter will not be attached more than
// once to the part.
for (Adapter adapter : part.eAdapters())
if (adapter.isAdapterForType(InputAdapter.class)
&& part.equals(adapter.getTarget()))
return;
part.eAdapters().add(new InputAdapter(part));
}
/**
* Removes the InputAdapter.
*
* @param part
*/
public void deactivate(WazaabiMItemPart<?> part) {
// this manager does not own any variable (including the InputAdapter)
// before to remove an existing adapter, we need to find it!
Adapter inputAdapter = null;
for (Adapter adapter : part.eAdapters())
if (adapter.isAdapterForType(InputAdapter.class)
&& part.equals(adapter.getTarget()))
inputAdapter = adapter;
if (inputAdapter != null)
part.eAdapters().remove(inputAdapter);
}
}
The ContactListManager
This manager tracks table’s selection changes and sets the part selection when needed.
Like in the DetailsManager, no knowledge of E4 or SWT is required.
<pre>public class ContactsListManager {
/**
* The SelectionAdapter is attached to this part's table and tracks the
* selection changes. When the table selection changes, the
* WazaabiMItemPart's selection is set.
*/
private static class SelectionAdapter extends AdapterImpl {
private final WazaabiMItemPart<?> part;
public SelectionAdapter(WazaabiMItemPart<?> part) {
this.part = part;
}
public void notifyChanged(Notification msg) {
if (msg.getFeatureID(Selectable.class) == ViewablesPackage.SELECTABLE__SELECTION)
if (msg.getEventType() == Notification.ADD)
part.setSelection(msg.getNewValue());
}
public boolean isAdapterForType(Object type) {
return this.getClass().equals(type);
}
};
/**
* Adds a new SelectionAdapter if no SelectionAdapter exists.
*
* @param part
*/
public void activate(WazaabiMItemPart<?> part) {
org.wazaabi.model.core.widgets.AbstractTable table = getTable(part);
if (table == null)
return;
// sets the input with using Kai's code
table.setInput(ContactsRepositoryFactory.getContactsRepository()
.getAllContacts());
// since activate method could called multiple times on the same part,
// we must be sure that the SelectionAdapter will not be attached more
// than once to the part.
for (Adapter adapter : part.eAdapters())
if (adapter.isAdapterForType(SelectionAdapter.class)
&& table.equals(adapter.getTarget()))
return;
table.eAdapters().add(new SelectionAdapter(part));
}
/**
* Removes the SelectionAdapter.
*
* @param part
*/
public void deactivate(WazaabiMItemPart<?> part) {
org.wazaabi.model.core.widgets.AbstractTable table = getTable(part);
if (table == null)
return;
// this manager does not own any variable (including the
// SelectionAdapter) before to remove an existing adapter, we need to
// find it!
Adapter selectionAdapter = null;
for (Adapter adapter : table.eAdapters())
if (adapter.isAdapterForType(SelectionAdapter.class)
&& table.equals(adapter.getTarget()))
selectionAdapter = adapter;
if (selectionAdapter != null)
table.eAdapters().remove(selectionAdapter);
}
/**
* Returns the table of our part. <br/>
* Since we do not use wazaabi <i>path</i> here, we need to find the table by
* iterating on container children.
*
* @param part
* @return
*/
private org.wazaabi.model.core.widgets.AbstractTable getTable(
WazaabiMItemPart<?> part) {
return (org.wazaabi.model.core.widgets.AbstractTable) part
.getComponent();
}
}
For both managers, the behavior is higly predictable : tracking table selection changes or running databinding on input changes. A next version, I will add mechanism for declaring a such behavior instead of writing it in java.
Step three : nothing to do, that’s finished !!
Running the demo
In a separate JVM
Runing the demo in a separate JVM is quite simple, just select the launch link in the product form and test …
In the same JVM
Running the demo in the same JVM than Eclipse itself is really more funny.
In this case, you can change directly the model using the EMF reflexive editor and observe the changes directly on the running application.
The context menu proposes an new option when the MApplication item is selected in the tree editor : “Open with live model”. In this case, the whole application is ran using in the same JVM as shown in the figure below :
Please refer to knwon issues paragraph if the behavior of the demo is not the one you expect. The E4 intergation is a work in progress.
Installing and testing
Eclipse, EMF and GEF
The demo has been built and tested in Eclipse 3.5 and JDK 1.5.
EMF of course is required.
GEF is required in this version of wazaabi. GEF dependency will be removed soon.
You can find GEF update site here : http://download.eclipse.org/tools/gef/updates/releases/
Wazaabi plugins and E4 dependencies
I exported the E4 dependencies i worked with (version 0.9) and the minimum set of wazaabi plugins in psf format :
Known issues
As explained above, the E4 integration is a work in progress.
Layout issues
Adding a component (or a group of component) will not systematically appear, sometime the users will need to resize the window, therefore forcing a layout.
EMF Reflexive Tree Editor issues
The Application.xmi cannot be edited using the reflexive emf editor if the wazaabi plugins are in the workspace (not real registered plugins). If you want to edit the application.xmi as shown in the figures above, you need to launch another workbench from the first one, and import only the demo project. In this case, it works.
CSS Issues
The CSS mechanism is partially supported. The table does not reflect the CSS defined background, etc… To be honnest, it is the first time I am in contact with the CSS work in E4.