Das Konzept der modellierten Workbench und ihr Rendering

Die Schaltzentrale von e4

Tom Schindl, Boris Bokowski

Der Zustand der Workbench wird bei e4 in Form von EMF-Modellobjekten verwaltet. Alle Elemente, die eine e4-Applikation ausmachen, sind in diesem Modell enthalten, und es gibt eine klare Trennung zwischen Modell auf der einen Seite und View bzw. Controller auf der anderen Seite. Der erste Teil dieses Artikels beleuchtet die Hintergründe dieser Architektur und stellt das Workbench-Modell in groben Zügen vor. Der zweite Teil befasst sich mit der Umsetzung des Modells in Widgets durch den Renderer.

Um die Entstehung des Workbench-Modells in e4 zu verstehen, ist es nützlich, sich vor Augen zu führen, wie eine klassische Eclipse-3.x-Anwendung erstellt wird. Egal, ob IDE oder RCP, die Anwendung besteht immer aus einer Reihe von so genannten Contributions (Views, Editors, Commands usw.), die von der Eclipse-Plattform zur Laufzeit zu einem großen Ganzen zusammengeführt werden. Die Contributions werden in plugin.xml-Dateien definiert, wobei jede Contribution (auch Extension genannt), im Prinzip nichts anderes ist als ein XML-Schnipsel in einem bestimmten Format. Das Schema für solche Schnipsel wird jeweils pro Extension Point in einem .exsd-File definiert, und die Schnipsel nehmen über ID-Attribute aufeinander Bezug. Die Plattform verwaltet diese Contributions zur Laufzeit in separaten Registries (z. B. ViewRegistry, EditorRegistry, …) und wandelt dazu die im .exsd-Schema vorliegenden Daten in Java-Objekte um, die in der Regel „Deskriptoren“ genannt werden (IViewDescriptor, IEditorDescriptor …). Dieser Ansatz bringt jedoch einige Nachteile mit sich:

  • Das Modell ist starr und nur mit hohem Aufwand manuell erweiterbar.
  • Es wird davon ausgegangen, dass die Applikation Dateien ausschließlich aus deklarativen Contributions in plugin.xml bildet und z. B. ein programmatorisches Erzeugen der Applikation nicht zulässt.
  • Das Modell zerfällt in mehrere, unverbundene Teile. Es gibt keine zentrale Instanz, an der ein Anwendungsentwickler modellweite Anpassungen vornehmen kann, um z. B. einen anderen Persistenzmechanismus zu verwenden, oder an zentraler Stelle Contributions zu filtern.
  • Als Anwendungsentwickler kann man sich nur durch Starten der Anwendung ein Gesamtbild machen, und das auch nur unter der Voraussetzung, dass man keine Fehler gemacht hat, wie z. B. den typischen Fehler von IDs, die nicht zu 100 % übereinstimmen.

Zusätzlich zu den Registries gibt es noch weitere, dem Entwickler mehr oder weniger komplett verborgene Zustandsinformationen. Neben verschiedenen Quellen solcher Informationen, wie die diversen Advisor-APIs (z. B. ActionBarAdvisor, WorkbenchWindowAdvisor), PerspectiveFactories und das Presentation API, gibt es auch noch die tatsächliche Information über den momentanen Zustand aller Workbench-Fenster, inklusive deren Position und Größe, aktueller Perspektive, welche Views und Editoren geöffnet sind, deren visuelle Anordnung und so weiter. Erst die Gesamtheit dieser Informationen lässt die typische Eclipse-Oberfläche entstehen.

Manche Informationen sind sogar nur über das resultierende UI selbst abfragbar, wie z. B. im ActionBarAdvisor erzeugte Actions. Als Resultat gibt es nicht nur keine Möglichkeit, sich ohne Starten der Anwendung ein Gesamtbild zu machen, es ist auch praktisch unmöglich, die einzelnen Modelldaten auszulesen, zu verarbeiten und zu verändern.

Das e4-Workbench-Modell

Das e4-Projekt verfolgt einen integrativen Ansatz, indem es einer e4-Applikation ein zentrales Applikationsmodell zugrunde legt, das sowohl UI-Strukturen (Applikationsfenster, Menüeinträge, etc.) als auch nicht-visuelle Aspekte der Workbench, wie Kommandos und ihre dazugehörigen Handler in sich aufnimmt und verwaltet. Dem Anwendungsentwickler steht also eine zentrale Stelle zur Verfügung, in der er die Struktur seiner Applikation einsehen und darüber auch direkt beeinflussen kann – mehr dazu später im Kapitel über das Rendering. Abbildung 1 zeigt eine Modellinstanz einer laufenden e4-Applikation. Anhand dieses Beispiels identifizieren wir zunächst die Grundbauelemente und gehen auf einige von ihnen im Einzelnen ein.

Abb. 1: Beispiel einer vereinfachten Addressbuchdemo von Kai Tödter

Im Workbench-Modell finden sich folgende UI-Elemente:

  • Window
  • Window Trim
  • Part Sash Container
  • Menu und MenuItem
  • Part und SaveablePart

Und außerdem nicht-visuelle Elemente:

  • Key Binding
  • Command
  • Handler

Dem geschulten Auge dürfte in Abbildung 1 nicht entgangen sein, dass in e4 nicht ein JavaBean, POJO oder selbst geschriebenes Domain-Modell-Framework verwendet wird, sondern ein EMF-Modell. Das Eclipse Modeling Framework bringt viele Features mit sich, die für e4 wichtig sind:

  • Serialisierung und Deserialisierung der Objektgraphen
  • Eventsystem, das über Zustandsänderungen im Domain-Modell informiert
  • Codegeneratoren, um die Java-Sourcen automatisch zu erzeugen
  • Wohldefinierte Möglichkeiten, das Domain-Modell einfach zu erweitern

Ein weiterer wichtiger Grund ist das von EMF angebotene Tooling rund um Domain-Modelle, das sich bei Weitem nicht auf Editier- und Visualisierungstools beschränkt. Außerdem bietet sich so für e4 eine Verbindung zur starken und innovativen EMF-Community. Erste Synergieeffekte sind schon zu beobachten – z. B. arbeiten Xtext-Committer an einer e4-spezifischen, domänenspezifischen Sprache (DSL), mit der man eine e4-Applikation textuell definieren kann, und es wurde prototypisch gezeigt, dass man mithilfe von CDO das e4-Applikationsmodell zwischen verschiedenen JVMs synchronisieren kann.

[ header = Seite 2: Aufgaben des Workbench-Modells ]

Aufgaben des Workbench-Modells

Bevor wir einzelne Modellelemente genauer betrachten, ist es wichtig, zu verstehen, welche verschiedenen Aufgaben das Applikationsmodell übernimmt:

  • Abbildung der UI-Struktur der laufenden e4-Applikation: Das bedeutet, dass das Modell sich während der Ausführung einer Applikation laufend verändert. Attribute verändern ihren Wert, Elemente kommen hinzu, verschwinden oder wechseln die Position. Das Applikationsmodell spiegelt also immer den aktuellen Status der e4-Applikation wider, oder eigentlich umgekehrt: Die sichtbaren Widgets einer e4-Applikation spiegeln immer den aktuellen Status des Applikationsmodells wider.Dieses Verhalten wird oft als ein Live-Modell bezeichnet und ist vergleichbar mit dem DOM in Webbrowsern.
  • Einbettung (Hosting) von UI-Contributions: Das e4-Programmiermodell wurde von Boris Bokowski im Eclipse Magazin 1.10 [1] vorgestellt (Artikel ist auch Online auf JAXenter erschienen). Es arbeitet mit POJOs, um die anwendungsspezifischen Applikationselemente (z. B. Views und Editoren) abzubilden. Eine wichtige Aufgabe des e4-Applikationsmodells ist es, diese POJOs in Beziehung zu den UI-Strukturelementen zu setzen und somit deren Erscheinen in der Oberfläche und deren Kontext zu verwalten.
  • Speichern und Wiederherstellen des Applikationsstatus nach einem Neustart
Abbilden der UI-Struktur

Die im Workbench-Modell verankerten UI-Elemente bilden vergleichsweise abstrakte UI-Konzepte wie etwa Fenster, Menü oder Container ab. Erst das Rendering-Framework setzt diese Elemente in konkrete SWT-Widgets um. Dabei ist es wichtig, zwischen der Ebene der Workbench und der Ebene der einzelnen UI-Contributions zu unterscheiden. Auf der Ebene der Workbench geht es nur um die Integrationsplattform für die eigentlichen, anwendungsspezifischen UI-Contributions wie Views und Editoren, nicht aber darum, das Innere dieser Contributions auch abzubilden. Mit anderen Worten endet das Workbench-Modell dort, wo anwendungsspezifischer Inhalt anfängt, mit konkreten Widgets wie Tabellen, Bäumen, Textfeldern, Formularelementen und so weiter. Im Groben kann man die UI-Elemente, die auf der Workbench-Ebene eine Rolle spielen, in zwei Gruppen unterteilen:

  • Containerelemente: Die Aufgabe von Containerelementen ist es, eine Baumstruktur aufzubauen, in der die zweite Art von Elementen (Items) ihren Platz finden. Die zwei wichtigsten Container sind PartSash und PartStack. Während ein PartSash-Container alle Kinder zur gleichen Zeit nebeneinander präsentiert, zeigt ein PartStack-Container jeweils immer nur eins der enthaltenen Elemente.
  • Item-Elemente: Item-Elemente bilden die Blätter im Strukturbaum des Applikationsmodells. Typische Vertreter sind ToolItemMenuItem oder Part. Das Part-Element steht dabei sowohl für Views wie auch Editoren.
Einbettung von UI-Contributions

Die zweite zentrale Aufgabe des Modells ist die Verwaltung der anwendungsspezifischen Applikationselemente. Eines der wichtigsten ist das Part-Element in Abbildung 2, das mehr oder weniger einem ViewPart aus Eclipse 3.x entspricht.

Abb. 2: Part-Element

Das e4-Schema definiert konkrete Klassen wie Part mithilfe von Mehrfachvererbung von atomaren, abstrakten Mixin-Interfaces wie z. B. Contribution oder UILabel. Das hat eher technische Gründe und kann in der Regel ignoriert werden. Wichtig ist, welche Attribute und Beziehungen für die jeweiligen konkreten Klassen definiert sind.

Das wichtigste Attribut der Part-Klasse hat den Namen „URI“. Dieser URI verweist auf eine Java-Klasse (Listing 1), die die Anwendungslogik enthält. Das typische Format eines solchen URIs istplatform:/plugin/com.myapp/com.myapp.views.DetailsView, ganz allgemein also der Name der Klasse und die Angabe, aus welchem OSGi-Bundle diese geladen werden soll. Durch die Verwendung von URIs ist es möglich, dass Parts – und auch andere Contributions – in anderer Form als durch Java-Klassen definiert werden. Die Verallgemeinerung hin zur Unterstützung von anderen Programmiersprachen und Technologien ist also schon vorgesehen.

	package com.myapp.views;
	
	public class DetailsView {
	@Inject
	private EHandlerService handlerService;
	@Inject
	public DetailsView(Composite parent) {
	// Applikationscode
	}
	}


Erzeugung des Workbench-Modells

Wie beim Blick auf Eclipse 3.x schon kurz angesprochen wurde, ist die Verwendung von plugin.xml-Elementen zwingend vorgeschrieben, dem Benutzer bleibt also keine Wahl. Einer e4-Applikation ist es hingegen eigentlich egal, wie das Applikationsmodell entsteht.

Die erste Standardmöglichkeit ist, das Modell mithilfe des Standard-EMF-Toolings (Abb. 1) zu definieren und die entstandene Datei als ein Attribut im OSGi-Produkt-Extension-Point zu übergeben (Abb. 3). Diese Möglichkeit wird wahrscheinlich oft bei RCP-Applikationen gewählt werden, weil dort in der Regel eine relativ ausführliche Grundstruktur feststeht und später nur noch erweitert wird.

Abb. 3: Vordefinition einer e4-Applikation

Die zweite Standardmöglichkeit fängt mit einem relativ schlanken Grundmodell an und erweitert dieses ähnlich wie in Eclipse 3.x um Contributions. Diese Erweiterung geschieht über den Extension Point org.eclipse.e4.workbench.model. Dieser erlaubt es dem Entwickler (im aktuellen Stand), alle Typen von Modellelementen als XMI-Snippets in das e4-Applikationsmodell einzubringen (Abb. 4 und 5). Dabei ist es durchaus möglich und erwünscht, dass logisch zusammenhängende Contributions innerhalb eines solchen Snippets definiert und als Ganzes in das Grundmodell eingefügt werden.

Abb. 4: org.eclipse.e4.workbench.model Extension Point

Abb. 5: Contribution zum Workbench-Model

[ header = Seite 3: Die Übersetzung des Modells in ein UI ]

Die Übersetzung des Modells in ein UI

Abbildung 6 zeigt das Grunddesign für die Übersetzung des Workbench-Modells in ein UI. Die Grundidee ist, dass der e4-Applikationscontainer sich nicht selbst um die Übersetzung des Applikationsmodells in eine Oberfläche kümmert, sondern das an ein IPresentationEngine genannten Service delegiert und damit selbst keine Abhängigkeiten auf Oberflächentechnologien hat. Die Schnittstelle zum IPresentationEngine-Service ist zurzeit ganze fünf Methoden schlank.

Abb. 6: Grunddesign IPresentationEngine

Die Standard-IPresentationEngine in e4 verwendet SWT und setzt das Standardaussehen von e4 um. Diese PresentationEngine arbeitet im Prinzip so, dass für jedes UI-Element im Applikationsmodell zumindest ein zuständiger so genannter Renderer existieren muss (Abb. 7).

Abb. 7: Stack Renderers

Die erste Aufgabe dieses Renderers ist, ein konkretes UI-Widget zu erzeugen und es am Ende, wenn es nicht mehr gebraucht wird, auch wieder zu zerstören. Die zweite Aufgabe ist es, die Attribute des erzeugten UI-Widgets und des entsprechenden Modellelements zu synchronisieren. Das gilt für einfache Attributsänderungen wie die Änderung eines Textattributs, aber auch für komplexe, wie das Verschieben eines Elements von einem zu einem anderen Elternteil.

Eine Auswirkung dieses Designs ist es aber auch, dass alle Änderungen, die in der Oberfläche angezeigt werden, immer über das Workbench-Modell gemacht werden können und müssen. Der Anwendungsentwickler kann nicht wissen, welches UI-Widget verwendet wird, um ein Modellelement darzustellen. Das ermöglicht einerseits, dass man mithilfe eines anwendungsspezifischen Renderers komplett andere Widgets verwenden kann und somit zusätzlich zu den von Kai Tödter bereits besprochenen CSS-Styling-Möglichkeiten [2] auch strukturell anderes Aussehen erreichen kann. Im Extremfall ist es sogar möglich (natürlich nicht ohne gewissen Aufwand), ein komplett anderes UI-Toolkit zu verwenden. Swing-Fans könnten also theoretisch das e4-Anwendungs- und Programmiermodell übernehmen, das UI aber vollständig in Swing implementieren.

Zusammenfassung

Die Stärke von e4 ist die zugrunde liegende Philosophie lose gekoppelter Teile, wovon die klare Trennung zwischen Applikationsmodell und Präsentationsschicht ein Beispiel ist. Wir haben die Vorteile des EMF-basierenden Modells aufgeführt und beschrieben, wie das Modell durch austauschbare Renderer mit der Präsentationsschicht synchronisiert wird. Aus unserer Sicht ist e4 besonders für RCP-Entwickler interessant. Die neue Eclipse-Plattform bietet Flexibilität und Freiheiten, die es ermöglichen, e4-Applikationen zu erstellen, die auf dem mittlerweile umkämpften Rich-Client-Markt gegen Konkurrenten bestehen können.

Boris Bokowski arbeitet für IBM Canada in Ottawa. Er leitet das Eclipse Platform UI Team und hat entscheidenden Anteil an der Entwicklung des e4-Projekts. Er hat an der TU Darmstadt studiert und an der FU Berlin promoviert.

Tom Schindl ist Gründer und Mitbesitzer von BestSolution.at, einem auf Java- und Eclipse-Technologie spezialisierten Entwicklungs- und Consulting-Unternehmen. Er ist Committer in verschiedenen Eclipse-Projekten und Mitglied des Architectural Council von Eclipse.

Geschrieben von
Tom Schindl, Boris Bokowski
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.