Xtext meets Scala meets WWW

Lift: Modernes Webframework auf Scala-Basis – Teil 2

Michael Adams
© shutterstock.com/bofotolux

Der zweite Teil des Artikels zeigt weitere Beispiele der Umsetzung von Lift-Funktionalitäten durch die Xtext-Lift-DSL. Zum einen beschreibt er die Formulierung der Lift-Demowebseite „Seven Things“ in einer Lift-DSL. Diese Webseite demonstriert, wie die anhand gängiger Webframeworks nur komplex umzusetzenden Sachverhalte in Lift elegant und knapp gelöst werden. Zum anderen zeigt sie auf, wie die DSL für die Entwicklung von portalorientierten Webanwendungen auf der Basis von Xtext, Lift, Scala und jQuery-Widgets dienen kann. Das Portal orientiert sich dabei an der Workbench in Eclipse RCP.

David Pollak, der Erfinder von Lift, zeigt auf der Webseite „Seven Things“ sieben Funktionalitäten, die in anderen Webframeworks nur mit erheblichem Aufwand umzusetzen sind. Folgende Funktionalitäten des Frameworks sind Inhalt dieser Seite:

  1. Verzögertes Laden (Lazy Loading): Simulation eines komplexeren Serveraufrufs und der angepassten Anzeigeverarbeitung in Lift
  2. Mehrfachverarbeitung (Multi-Threading): Verteilte Ausführung von Serveranfragen
  3. Ajax und Comet: Darstellung der asynchronen Client-und Serververarbeitung von Webanfragen, dargestellt am Beispiel eines Chats
  4. Verlinkung von Widgets: Erzeugung von Widget-Abhängigkeiten und automatische Aktualisierung von abhängigen Werten
  5. Designerfreundliche Templates: Demonstration des Templatemechanismus in Lift
  6. Wizards: Erzeugung von Widget-Assistenten
  7. Sicherheit: Erläuterung der Sicherheitsfunktionalitäten in Lift

Abb. 1: Lift-Demo der lazy-loading-Funktionalität

Die folgende DSL beschreibt den Rahmen für diese Anwendung, ohne eine vollständige Implementierung der Funktionalität vorzugeben. Das bedeutet, dass eine lauffähige Anwendung entsteht, deren Anwendungslogik in den Methoden der einzelnen Komponenten zu implementieren ist. Für die transienten Datenstrukturen stehen Transportobjekte zur Verfügung. Diese definieren in einer allgemeinen Architekturbeschreibung Container, die den Austausch zu persistierender Daten zwischen Client und Server vornehmen. Der folgende Abschnitt beschreibt beispielhaft zwei der sieben Funktionalitäten, „Lazy Loading“ und „Comet und Ajax“.

Das Beispiel startet mit der Beschreibung der Menüstruktur. Als Startseite definiert diese Struktur aus Gründen der Einfachheit den ersten Punkt, das verzögerte Laden.

Abb. 2: DSL-Erfassung der Einstiegssicht der Lift-Demoseite

Die zugehörige Websicht (Abb. 2) definiert den Inhalt in dem Contentbereich mit den Standardtemplates. Den interessanten Teil definiert hier das Tag lift:LazyLoad, welches dafür sorgt, dass die Webseite erst dann aktualisiert wird, wenn die Berechnung der Anwendungslogik in der Komponente LongTime abgeschlossen ist. Der Threadaufruf simuliert eine langlaufende Aktion. Durch die Angabe des #-Tags in den Tag-Referenzierungen ermittelt das Framework alle Tags mit der ID des angegebenen Namens (hier start und end) in der Webview.

Abb. 3: Erfassung der Anwendungslogik

Die Beschreibung der zweiten Funktionalität, der Verarbeitung asynchroner Client- und Serveranfragen, erfordert sowohl die Definition einer Websicht für den Aufbau des Eingabebereichs über eine Ajax-Form als auch die Definition des Comet-Teils für die Aktualisierung der Anzeige nach Verarbeitung einer Chatnachricht durch den Server:

Abb. 4: Beschreibung der Sicht für das Beispiel eines Chats

Die referenzierte Anwendungslogik ist aus Gründen der Lift-Namensraumkonventionen auf zwei Namensräume verteilt. Dies ist zum einen der Standardnamensraum für Lift-View-First-Komponenten snippet. Die Tag-Referenzierung verbindet die Ausführung des Formulars mit dem Senden der Nachrichtenzeile an den Chatserver und der Inkrementierung des Zeilenzählers, der als Sessionvariable realisiert ist. Es erfolgt zudem das Zurücksetzen der Eingabezeile des Chats:

 Abb. 5: Darstellungslogik für das Chatbeispiel

Der Standardnamensraum für Lift-Comet-Anwendungen ist der comet-Bereich. Hier definiert das Beispiel die Comet-Logik für den Chat. Diese teilt sich in die Beschreibung der Clientlogik in der Komponente Chat sowie die Beschreibung der Serverlogik in der Komponente ChatServer auf.

Der ChatServer ist als LiftActor und ListenerManager realisiert. Damit besitzt er per Lift-Konvention die Eigenschaften, als asynchroner Server-Actor zu dienen sowie gleichzeitig die Versorgung der angemeldeten Chatclients zu ermöglichen. Dazu verwaltet der Server eine Liste der Nachrichten, die die Eingabeform der ChatIn-Komponente über die Methode lowPriority füllt. Diese Methode ruft Lift per Konvention auf, wenn der Server eine Nachricht erhält. Über die Schachtelung partieller Scala-Funktionen definiert Lift zudem eine Priorisierung möglicher Aufrufe (highPriority, mediumPriority, lowPriority). Die Methoden createUpdate und updateListeners liefern die Nachrichten an den Client und aktualisieren die Chats der angemeldeten Benutzer.

Die Clientkomponente erhält die Nachrichten als Comet-Actor ebenfalls in der lowPriority-Methode und aktualisiert die komplette Seite über den reRender-Aufruf. Alternativ könnte der Client den Chatbereich der Seite auch partiell aktualisieren.

Abb. 6: Comet-Client-und -Serveranteile für den Chat

Abb. 7: Lift-Demo des Chats

[ header = Seite 2: Eclipse-Xtext Lift-Portal ]

Eclipse-Xtext Lift-Portal

Heutige Webanwendungen stellen sowohl aufgrund der stetig steigenden fachlichen Anforderungen als auch wegen der technischen Weiterentwicklung der Webframeworks hohe Ansprüche an Aussehen, Nutzerfreundlichkeit und Bedienbarkeit der grafischen Oberflächen. Häufig ist die Vorgabe, die Oberflächen der Geschäftsanwendungen sowohl als native Desktop-, als auch als Weboberflächen umzusetzen.

Das folgende Beispiel zeigt, wie anhand der vorgestellten Architektursprache in Xtext und Lift zusammen mit jQuery-Widgets ein Portaleinstieg für die Konstruktion komplexer Weboberflächen nach dem Vorbild der Workbench in Eclipse RCP generiert werden kann.

Als fachlicher Hintergrund des Beispiels dient die Beschreibung eines Serviceportals, das die Recherche nach Kunden und die für diese Kunden erbrachten Angebote und Leistungen ermöglichen soll:

Abb. 8: Einstiegsseite des Angebots- und Leistungsportals

Das Portal besteht im oberen Bereich aus einem Menüteil, der Basisfunktionalitäten zur Verfügung stellt. Unter dem Menü befindet sich ein Suchfenster, dessen Suchen sich auf die fachliche Struktur der darunterliegenden Baumstruktur auswirken. In diesem Beispiel ergibt sich die Basisstruktur zunächst aus den fachlichen Entitäten der Kunden und der Leistungen.

Der rechte Teil definiert den Detailbereich für die Anzeige der Ergebnisse einer Knotenauswahl. Der dargestellte Bereich zeigt die Übersichtsseite für den Kundenbereich. Der untere Teil des Portals definiert den Ergebnisbereich einer Suche auf den Entitäten der Kunden und Leistungen.

Die zugehörige Lift-Domänensprache definiert im Darstellungsbereich die Übersichtsseite für Kunden und Leistungen in mehreren Abschnitten. Diese Abschnitte können durch einen Navigationsbutton angesprungen werden. Für den Kundenbereich übernimmt diese Darstellung die customerIntroView.

Abb. 9: Unterschiedliche Detailsichten der Einstiegsseite

Abb. 10: Portalsuche für den Kundenbereich

Abb. 11: Einstiegssicht und Einstiegsdetailsichten des Portals

Sie stellt den grafischen Rahmen zur Verfügung, der es erlaubt, die einzelnen Inhalte der jeweiligen Navigationsseite anzuzeigen. Per Default ist das in diesem Fall die webView customerIntro0. Durch Aktivierung des Navigationsbuttons erfolgt die Weiterschaltung auf customerIntro1. Dazu bedient sie sich der Komponente Customerintro, die die Steuerungslogik bereitstellt.

Abb. 12: Navigationslogik der Einstiegsdetailsichten

Das Scala-Objekt Intro realisiert die Steuerungslogik und verwendet für das Ein- und Ausblenden der Seiten JavaScript- und jQuery-Funktionalitäten des Lift-Frameworks.

Die Darstellungskomponente Portalclient definiert die Baumstruktur des Portals. Die Aktionen binden die zu öffnenden Sichten an die Knoten des Baums. Im vorliegenden Beispiel ist beispielsweise der Wurzelknoten AngebotsUndLeistungsportal mit der Aktion zum Öffnen einer Navigationsleiste verbunden.

Abb. 13: Beschreibung der Baumnavigation des Portals

Ein Portalknoten kann neben einer benutzerdefinierten Aktion ein Transportobjekt referenzieren, das die zugrundeliegende Modellentität beispielsweise für eine CRUD-Aktion beschreibt.

Abb. 14: Beschreibung der Transportobjekte des Portals

In dem vorliegenden Fall erfolgt eine Suche auf die Kundenentität mit dem Nachnamen „Meier“. Die Darstellung der Suchergebnisse übernimmt eine Tabelle, die im unteren Bereich des Portals liegt. Die Selektion der Ergebniszeile führt zur Darstellung der Detailsicht des Kunden.

Abb. 15: Darstellung des generischen Suchdialogs des Portals

Auf der Basis des hier gezeigten Vorgehens lassen sich weitere Sichten für das Angebotsportal hinzufügen.

Abb. 16: Anzeige des Suchergebnisses eines Kunden im Portal

Zusammenfassung und Ausblick

Der Artikel zeigt, wie die in früheren Eclipse-Ausgaben [1], [2] vorgestellte, allgemeine Architektursprache in Xtext die Erzeugung einer DSL für das Scala-Webframework Lift ermöglicht. Lift unterscheidet sich von gängigen Frameworks durch den hohen Abstraktionsgrad in vielen Bereichen wie Websicherheit, Ajax und Comet, Nebenläufigkeit und dem Template- und Viewmechanismus zur Erstellung von Webseiten unabhängig von der Anwendungslogik. Dadurch eignet sich Lift hervorragend, die Eigenschaften der Programmiersprache Scala auszunutzen. Anhand von Beispielen zeigt der Artikel, wie die Lift-DSL verschiedene Anwendungsrahmen für die genannten Lift-Funktionalitäten bereitstellt.

Der hohe Abstraktionsgrad von Lift erlaubt es zudem, in eleganter Weise JavaScript-Bibliotheken wie jQuery- und jQuery-Widgets in Scala zugänglich zu machen. Dies erlaubt die durchgängige Webentwicklung in einer einzigen Sprache. Hierbei unterstützen Xtext und die erzeugte Lift-DSL, jQuery-Widgets konfigurativ in die eigene Anwendung zu integrieren. Dies zeigt das Beispiel eines Portalrahmens für ein Angebots- und Leistungsportal. Der Rahmen definiert allgemeine Funktionalitäten wie CRUD und Suche für die fachlichen Entitäten der Anwendung.

Hinweis: Der erste Teil des Artikels wurde am 17.12.2013 hier auf JAXenter veröffentlicht.

Geschrieben von
Michael Adams
Michael Adams
Michael Adams ist technischer Seniorsoftwareberater bei der NTT Data, Deutschland in Köln und beschäftigt sich mit Softwarearchitekturthemen in Java, modellgesteuerter Entwicklung und Domänensprachen.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: