SlideShare ist ein Scribd-Unternehmen logo
1 von 138
Downloaden Sie, um offline zu lesen
Bachelorthesis zur Erlangung des akademischen Grades
          Bachelor of Science in Wirtschaftsinformatik




                   Vergleich des Scala
        Web-Frameworks Lift mit dem
          Java EE Programmiermodell



         Bachelorthesis im Fachbereich Wirtschaftswissenschaften II
                   im Studiengang Wirtschaftsinformatik
             der Hochschule für Technik und Wirtschaft Berlin
                   in Zusammenarbeit mit der adesso AG




vorgelegt von:         Felix Müller
Matrikelnummer:        524063
eingereicht am:        9. Juni 2011


Erstbetreuer:          Prof. Dr. Ingo Claßen
Zweitbetreuer:         Prof. Dr. Harald Brandenburg
Betrieblicher Betreuer: Eberhard Wolff
Inhaltsverzeichnis

Abbildungsverzeichnis                                                                  III

Listingsverzeichnis                                                                    IV

Abkürzungsverzeichnis                                                                 VIII

1 Einleitung                                                                            1
   1.1   Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     1
   1.2   Zielsetzung der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . .       1
   1.3   Abgrenzung zu anderen Arbeiten . . . . . . . . . . . . . . . . . . .           2
   1.4   Aufbau der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . .        2

2 Grundlagen                                                                            4
   2.1   Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     4
   2.2   Java EE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      5
         2.2.1   Java Persistence API . . . . . . . . . . . . . . . . . . . . . .       7
         2.2.2   Bean Validation . . . . . . . . . . . . . . . . . . . . . . . . . 10
         2.2.3   Dependency Injection for Java . . . . . . . . . . . . . . . . . 10
         2.2.4   JavaServer Faces . . . . . . . . . . . . . . . . . . . . . . . . 11
   2.3   Programmiersprache Scala . . . . . . . . . . . . . . . . . . . . . . . 16
         2.3.1   Klassen und Objekte . . . . . . . . . . . . . . . . . . . . . . 17
         2.3.2   Traits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
         2.3.3   Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
         2.3.4   Pattern Matching . . . . . . . . . . . . . . . . . . . . . . . . 26
         2.3.5   Self-Type Annotationen . . . . . . . . . . . . . . . . . . . . 27



                                                                                         I
Inhaltsverzeichnis


          2.3.6   Implicit Conversions . . . . . . . . . . . . . . . . . . . . . . 29
   2.4    Lift Web-Framework . . . . . . . . . . . . . . . . . . . . . . . . . . 30

3 Methodik der Evaluation                                                            34
   3.1    Beschreibung der Evaluation . . . . . . . . . . . . . . . . . . . . . . 34
   3.2    Evaluationskriterien . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
          3.2.1   Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
          3.2.2   Funktionalität . . . . . . . . . . . . . . . . . . . . . . . . . . 36
          3.2.3   Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

4 Entwicklung der Beispielanwendung                                                  40
   4.1    Entwurf der Anwendung . . . . . . . . . . . . . . . . . . . . . . . . 40
          4.1.1   Domänenmodell . . . . . . . . . . . . . . . . . . . . . . . . . 40
          4.1.2   Anwendungsfälle . . . . . . . . . . . . . . . . . . . . . . . . 42
   4.2    Umsetzung mit Java EE . . . . . . . . . . . . . . . . . . . . . . . . 43
          4.2.1   Domänenmodell . . . . . . . . . . . . . . . . . . . . . . . . . 43
          4.2.2   Anwendungsfälle . . . . . . . . . . . . . . . . . . . . . . . . 48
   4.3    Umsetzung mit Scala und Lift . . . . . . . . . . . . . . . . . . . . . 68
          4.3.1   Domänenmodell . . . . . . . . . . . . . . . . . . . . . . . . . 68
          4.3.2   Anwendungsfälle . . . . . . . . . . . . . . . . . . . . . . . . 77

5 Durchführung der Evaluation                                                        99
   5.1    Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
   5.2    Funktionalität . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
   5.3    Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

6 Fazit                                                                            122
   6.1    Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
   6.2    Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

Literaturverzeichnis                                                                 IX

A Inhalt der CD                                                                     XII




                                                                                      II
Abbildungsverzeichnis

 2.1   Prozessfluss des Ajax Modells von [Wik] . . . . . . . . . . . . . . .      5
 2.2   Lebenszyklus einer Persistent Entity aus [Obj] . . . . . . . . . . . .    8
 2.3   MVC-Architektur von JSF aus [MM10] . . . . . . . . . . . . . . . . 12
 2.4   JSF Standard Request-Response-Zyklus aus [EJ10] . . . . . . . . . 13
 2.5   Kontrollfluss im View-First-Ansatz von Lift aus [Per11] . . . . . . . 31
 2.6   Architektur von Lift aus [DCB11] . . . . . . . . . . . . . . . . . . . 32

 4.1   Domänenmodell der Beispielanwendung . . . . . . . . . . . . . . . . 41




                                                                                III
Listingsverzeichnis

 2.1   Eintragung des Faces-Servlet in der web.xml . . . . . . . . . . . . . 14
 2.2   Einbinden der Namensräume der beiden Standard-Tag-Libraries . . 16
 2.3   Einfache Scala Klasse . . . . . . . . . . . . . . . . . . . . . . . . . . 17
 2.4   Klasse mit dazugehörigem Companion Objekt . . . . . . . . . . . . 19
 2.5   Beispiel der Nutzung von Traits . . . . . . . . . . . . . . . . . . . . 20
 2.6   Beispiel einer einfachen Funktion . . . . . . . . . . . . . . . . . . . 22
 2.7   Beispiel der Zuweisung eines Funktionswertes     . . . . . . . . . . . . 22
 2.8   Anwendung einer Funktion höherer Ordnung . . . . . . . . . . . . . 22
 2.9   Vollständig ausgeschriebener Aufruf von map . . . . . . . . . . . . . 23
 2.10 Aufruf der map Funktion mit einem Platzhalter . . . . . . . . . . . 23
 2.11 Beispiel einer Funktion mit mehreren Parameterlisten . . . . . . . . 24
 2.12 Abbildung der sub Funktion auf mehrere Funktionen . . . . . . . . 24
 2.13 Beispiel einer partiell angewandten Funktion . . . . . . . . . . . . . 25
 2.14 Kontrollstruktur-ähnliche Konstrukte mit subTwoWith . . . . . . . 25
 2.15 Bespiel von Pattern Matching in printInt . . . . . . . . . . . . . . . 26
 2.16 Pattern Matching in Form einer partiellen Funktion . . . . . . . . . 27
 2.17 Beispiel einer Self-Type Annotation . . . . . . . . . . . . . . . . . . 28
 2.18 Beispiel einer Implicit Conversion . . . . . . . . . . . . . . . . . . . 29

 4.1   JPA Grundgerüst der Java Gebäude Fachklasse . . . . . . . . . . . 43
 4.2   String Attribute der Gebäude Klasse . . . . . . . . . . . . . . . . . 45
 4.3   Implementierung der Beziehung zwischen Räumen und Gebäuden . 46
 4.4   gebaeude Attribut in der Java Raum Fachklasse . . . . . . . . . . . 46
 4.5   Anzahl der Fenster eines Raumes . . . . . . . . . . . . . . . . . . . 47



                                                                                IV
Listingsverzeichnis


4.6   Raumausstattungen in der Raum Klasse . . . . . . . . . . . . . . . 47
4.7   Dao Interface für den Datenbankzugriff . . . . . . . . . . . . . . . . 48
4.8   Spezifisches Dao Interface für die Raum Klasse . . . . . . . . . . . . 49
4.9   EntityManager und findById Methode des AbstractJpaDao . . . . . 49
4.10 configure Methode des PersistenceModule       . . . . . . . . . . . . . . 50
4.11 Erzeugung und Konfiguration des PersistenceModules . . . . . . . .        51
4.12 warp-persist Servlet Filter Eintrag in der web.xml . . . . . . . . . .   51
4.13 Bindung der DAO Interfaces an ihre Implementierungen . . . . . . 52
4.14 Ablegen des Injectors im ServletContext . . . . . . . . . . . . . . . 53
4.15 Injection durch Guice in AbstractController . . . . . . . . . . . . . 53
4.16 XHTML Grundgerüst in layout.xhtml . . . . . . . . . . . . . . . . . 55
4.17 Auszug aus messages Datei für das de Länderkürzel . . . . . . . . . 56
4.18 Anzeige aller Gebäude in gebaeude.xhtml . . . . . . . . . . . . . . . 56
4.19 GebaeudeTableModel Eintrag in faces-config.xml . . . . . . . . . . . 57
4.20 TableModel Interface für die Abbildung von Tabellen . . . . . . . . 58
4.21 Laden aller Gebäude im GebaeudeTableController . . . . . . . . . . 59
4.22 Ajax Support zum Nachladen des ausgewählten Gebäudes . . . . . 59
4.23 GebaeudeTableSelectionHandler Eintrag in faces-config.xml . . . . . 60
4.24 Ereignisbehandlung in onSelectionChange . . . . . . . . . . . . . .      61
4.25 Anzeige der Bezeichnung des ausgewählten Gebäudes . . . . . . . . 62
4.26 Button Tag zum Speichern eines Gebäudes in gebaeude.xml . . . . 63
4.27 GebaeudeTableService Eintrag in faces-config.xml . . . . . . . . . . 63
4.28 Speichern des selektierten Gebäudes in AbstractTableController . . 64
4.29 Auszug des Tags für die Anzeige der Suchergebnisse . . . . . . . . . 65
4.30 Tag für den Suchbutton . . . . . . . . . . . . . . . . . . . . . . . . 66
4.31 Suchlogik in sucheRaeume Methode . . . . . . . . . . . . . . . . . . 66
4.32 Finder Methode für die Raumsuche . . . . . . . . . . . . . . . . . . 66
4.33 Auszug des Tags für das Löschen von Ausstattungsmerkmalen . . . 67
4.34 Abfragelogik, ob ein Ausstattungsmerkmal löschbar ist . . . . . . . 68
4.35 Finder Annotation von getAusstattungenByMerkmal . . . . . . . . 68
4.36 Deklaration der Scala/Lift Gebäude Fachklasse     . . . . . . . . . . . 69




                                                                              V
Listingsverzeichnis


4.37 Attribute der Building Klasse . . . . . . . . . . . . . . . . . . . . . 70
4.38 name Attribut der Building Klasse . . . . . . . . . . . . . . . . . . 70
4.39 Generische Signatur einer Mapper Validierungsfunktion . . . . . . .        71
4.40 Signatur von valMinLen . . . . . . . . . . . . . . . . . . . . . . . .     71
4.41 rooms Objekt der Building Klasse . . . . . . . . . . . . . . . . . . . 72
4.42 Überschriebene Löschfunktion der Building Klasse . . . . . . . . . . 73
4.43 Companion Objekt der Building Klasse . . . . . . . . . . . . . . . . 73
4.44 Rückgabe des Companion Objekts in getSingleton . . . . . . . . . . 74
4.45 Deklaration der Scala/Lift Raum Fachklasse . . . . . . . . . . . . . 74
4.46 Abbildung der Referenz auf ein Gebäude in Room . . . . . . . . . . 75
4.47 Anzahl der Fenster in der Scala/Lift Room Klasse . . . . . . . . . . 75
4.48 Erweiterter Validator für Ganzzahlen vom Typ Integer . . . . . . . 75
4.49 Raumausstattungen in der Room Klasse . . . . . . . . . . . . . . . 76
4.50 isDeletable Funktion der Attribute Klasse . . . . . . . . . . . . . . 77
4.51 Datenbankabfrage in der findByAttribute Funktion . . . . . . . . . 77
4.52 Verbindungseinstellungen für die Datenbank . . . . . . . . . . . . . 78
4.53 Datenbanksetup der Lift Anwendung . . . . . . . . . . . . . . . . . 79
4.54 Initialisieren der Datenbank . . . . . . . . . . . . . . . . . . . . . . 80
4.55 Snippet Konfiguration und Aufbau der SiteMap . . . . . . . . . . . 80
4.56 Ressourceneinträge für die Sitemap . . . . . . . . . . . . . . . . . .     81
4.57 Lift Servlet Filter Eintrag in web.xml . . . . . . . . . . . . . . . . .   81
4.58 Ausschnitt des allgemeinen Templates in default.html . . . . . . . . 83
4.59 Ausschnitt der Tabelle zum Anzeigen von Gebäuden . . . . . . . . . 84
4.60 Aufbau einer Tabelle im BaseTableSnippet . . . . . . . . . . . . . . 85
4.61 Generierung einer Tabellenzeile zur Anzeige eines Gebäudes . . . . 86
4.62 Erzeugung von selektierbaren Tabellenzeilen in SelectableTableRows 88
4.63 Ereignisbehandlung in Buildings für einen Klick auf eine Tabellenzeile 90
4.64 Speichern des ausgewählten Gebäudes in der Session        . . . . . . . . 90
4.65 Anzeige der Gebäudesbezeichnung und des Speichern Buttons . . .            91
4.66 Validierung der Eingaben für ein Gebäude . . . . . . . . . . . . . . 92
4.67 Anzeige von Fehlern durch Lift . . . . . . . . . . . . . . . . . . . . 93




                                                                                VI
Listingsverzeichnis


4.68 Speichern des ausgewählten Gebäudes . . . . . . . . . . . . . . . . . 94
4.69 Snippet-Funktionen für den Such-Button . . . . . . . . . . . . . . . 95
4.70 Snippet-Funktion für die Ausgabe der Suchergebnisse . . . . . . . . 96
4.71 Finder-Funktion für die Suche nach Räumen . . . . . . . . . . . . . 96
4.72 Tags für die Buttons zum Verwalten von Ausstattungsmerkmalen . 97
4.73 Bedingtes Rendern des Lösch-Button . . . . . . . . . . . . . . . . . 98

5.1   Exemplarische Gebäude Fachklasse mit CouchDB Anbindung . . . . 107
5.2   Injector Trait von Lift für Dependency Injection . . . . . . . . . . . 114
5.3   Deklaration der registerInjection Funktion . . . . . . . . . . . . . . 115
5.4   Lift Dependency Injection Beispiel      . . . . . . . . . . . . . . . . . . 116
5.5   Dekoration mit withTransaction . . . . . . . . . . . . . . . . . . . . 118
5.6   Service Trait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
5.7   Mögliche Dynamic Proxy Integration in Scala . . . . . . . . . . . . 120




                                                                                 VII
Abkürzungsverzeichnis

AOP Aspektorientierte Programmierung

API   Application Programming Interface

CRUD Create, Read, Update, Delete

DAO Data Access Object

DI    Dependency Injection

DSL Domain Specific Language

HTML HyperText Markup Language

IDE   Integrated Development Environment

JCP Java Community Process

JSON JavaScript Object Notation

JSR   Java Specification Request

XHTML eXtensible HyperText Markup Language

XML Extensible Markup Language




                                             VIII
1 Einleitung

1.1 Motivation

Das Entwickeln von Anwendungen für das World Wide Web gewinnt stetig an
Bedeutung. Bereits heutzutage verdrängen Web-Anwendungen (z.B. Google Docs)
einzelne Desktop-Anwendungen. Auf mobilen Geräten sind Web-Anwendungen
bereits eine wirkliche Konkurrenz zu den nativen Applikationen. Daher ist es
interessant und wichtig, Frameworks, die das Entwickeln von Web-Anwendungen
erleichtern und verallgemeinern, auf die tatsächliche Einsatztauglichkeit zu prüfen
und zu testen.

Auf der Hauptseite des Lift Web-Frameworks wird Lift als das derzeit mächtigs-
te Framework für die Entwicklung von Web-Anwendungen bezeichnet.1 Mit der
Programmiersprache Scala setzt Lift zudem eine neue Sprache für die JVM ein
und zeigt damit gleichzeitig den Einsatz dieser neuen Sprache in einem größeren
Projekt. Aufgrunddessen wird das Lift Web-Framework in dieser Arbeit mit dem
etablierten Java EE Programmiermodell verglichen.



1.2 Zielsetzung der Arbeit

Ziel der Arbeit ist es, durch den Vergleich des Lift Web-Frameworks mit dem Java
EE Programmiermodell Antworten auf mehrere Fragestellungen zu erhalten, die
folgend zusammengefasst dargelegt werden.

 1
     siehe http://liftweb.net




                                                                                 1
1.3 Abgrenzung zu anderen Arbeiten


Lift soll aus möglichst vielen Blickwinkeln betrachtet werden, damit zum Ende
der Arbeit die Vor- und Nachteile des Frameworks herausgearbeitet sind. Es gilt
außerdem zu untersuchen, was die besten Einsatzbereiche des Lift Frameworks
sind. Das Hauptziel ist dabei, Lift im Vergleich zum Java EE Programmiermodell
zu bewerten, da dieses einen der am häufigsten eingesetzten Standards in der
Web-Entwicklung darstellt. Außerdem setzt Lift auf die Java EE Plattform auf,
wie später noch erklärt wird, und tritt damit in mögliche Konkurrenz zum Java
EE Programmiermodell.



1.3 Abgrenzung zu anderen Arbeiten

Anders als in bisherigen Arbeiten wird Scala in dieser Arbeit nicht auf die Integration
mit bestehenden Java Anwendungen geprüft ([Kal10]) oder die Entwicklung einer
Web-Anwendung mit Scala und Lift ([TF11]) gezeigt. Im Mittelpunkt dieser Arbeit
steht der Vergleich von Scala und Lift als Technologiestack mit dem Java EE
Programmiermodell. Natürlich wurde dafür eine Beispielanwendung jeweils mit
Scala/Lift und Java EE entwickelt, was auch entsprechend ausführlich erläutert
wird. Ebenso wird an einigen Stellen kurz die Integration mit Java angesprochen.
Aber dies geschieht dann zwecks des Vergleichs und der Bewertung.



1.4 Aufbau der Arbeit

Zu Beginn der Arbeit werden die Grundlagen der verwendeten Konzepte und
eingesetzten Technologien erklärt. Dabei erfolgt eine Einführung in die Program-
miersprache Scala. Allerdings kann keine vollständige Sprachdefinition gegeben
werden. Alle Sprachmittel, die zum Verständnis der Arbeit nötig sind, werden
gezeigt und erläutert. Außerdem wird davon ausgegangen, dass der Leser dieser
Arbeit bereits mit der Sprache Java entwickelt, sodass eine Einführung in die
eingesetzten Java EE Techniken für das Verständnis ausreicht.




                                                                                     2
1.4 Aufbau der Arbeit


Danach wird die Methodik der Evaluation beschrieben. Dabei werden die ver-
wendeten Methoden erläutert und die Evaluationskriterien vorgestellt. Da für
den Vergleich der beiden Technologiestacks jeweils eine Beispielanwendung ent-
wickelt wurde, folgt im Kapitel 4 die Darstellung der Entwicklung. Dabei wird
die Umsetzung der Prototypen anhand von Programmcodeauszügen erläutert. An-
schließend wird die Evaluation durchgeführt. Dafür werden die zuvor festgelegten
Evaluationskriterien verwendet.

Zum Abschluss wird das Ergebnis der Arbeit im Fazit zusammengefasst und ein
Ausblick gegeben, indem weitere untersuchenswerte Themen benannt werden, die
durch die Arbeit entstanden sind.

Die entwickelten Beispielanwendungen liegen dieser Arbeit auf einer CD bei, deren
Inhalt im Anhang kurz beschrieben wird.




                                                                               3
2 Grundlagen

2.1 Ajax

Die Begrifflichkeit Ajax ist heutzutage ein gängiges Schlagwort bei der Entwicklung
von Web-Anwendungen. Damit wird ein Konzept bezeichnet, dass unter Verwendung
gängiger Technologien die asynchrone Übertragung von Daten zwischen Server und
Client, meistens dem Browser, ermöglicht. Ajax steht dabei für „Asynchronous
JavaScript and XML“.1

Web-Anwendungen, in denen Ajax eingesetzt wird, verhalten sich oftmals ähnlich
einer Desktop-Anwendung. Die Webseiten reagieren auf Interaktionen des Nut-
zers flüssiger. Dies liegt daran, dass die Webseiten beim Einsatz von Ajax nicht
komplett neu geladen werden. Vielmehr werden sukzessive einzelne Seitenbereiche
nachgeladen. Damit dies funktioniert, wird auf Seiten des Clients eine Zwischen-
schicht eingebaut, die Ajax Engine. Diese Engine ist üblicherweise eine existierende
JavaScript-Bibliothek, die die asynchrone Datenübetragung steuert.

Eine Anfrage des Clients wird dabei nicht direkt an den Server gesendet, sondern
über eine Ajax Engine mittels XML, wie in Abbildung 2.1 zu sehen ist.2 Während
der Anfragebearbeitung auf dem Server kann der Client somit noch auf Nutzerin-
teraktionen reagieren. Durch die Ajax Engine muss die Server-Antwort nur die
notwendigen Daten zur Änderung der Webseite enthalten, die anschließend von der
Ajax Engine zur Seitenaktualisierung genutzt werden.3

 1
   Vgl. [Wik]
 2
   Neben XML ist auch die Verwendung von HTML oder JSON häufig anzutreffen.
 3
   siehe [MM10, S. 230 ff.]




                                                                                  4
2.2 Java EE




               Abb. 2.1: Prozessfluss des Ajax Modells von [Wik]


2.2 Java EE

Die Java Platform Enterprise Edition (Java EE) gilt umgangssprachlich als das
Java für Geschäftsanwendungen. Da in diesem Zusammenhang oft unklar ist, was
Java EE wirklich ist und wie es sich in das bestehende Java Ökosystem eingliedert,
erfolgt eine Einordnung von Java EE.

Oftmals wird nicht zwischen Java als Sprache und Java als Plattform unterschie-
den. Wobei mit Java SE, der Java Platform Standard Edition, durchaus diese
Unterscheidung vorliegt. Java SE definiert eine Plattform, die sich aus der Java
Standardbibliothek, der Java Virtual Machine und den Entwicklungstools (z.B. der
Java Compiler) zusammensetzt. Hinzu kommen viele Bibliotheken von Drittanbie-
tern. Die Java Standardbibliothek implementiert dabei die Kernfunktionalitäten
der Programmiersprache Java und liefert eine Fülle an bereits implementierten
Klassen. Darunter sind zum Beispiel Klassen für die Entwicklung grafischer Benut-
zeroberflächen, für die Kommunikation über das Netzwerk oder auch Klassen zum



                                                                                5
2.2 Java EE


Parsen von XML-Dokumenten.4

„Die Java Platform, Enterprise Edition (Java EE) ist ein Aufsatz für die Java SE
und integriert Pakete, die zur Entwicklung von Geschäftsanwendungen (Enterprise-
Applikationen genannt) nötig sind.“5 Diese Beschreibung fasst es gut zusammen.
Zusätzlich ist bei Java EE zwischen der Plattform und dem Programmiermodell zu
unterscheiden. Unter Java EE als Plattform werden in dieser Arbeit die Komponen-
ten der Laufzeitumgebung für Java Enterprise-Applikationen und die dafür nötigen
Technologien verstanden. So werden z.B. Anwendungen, die mit Java EE entwickelt
wurden, üblicherweise in einem Application Server oder Webcontainer installiert,
die als Laufzeitumgebung dienen. Java EE als Programmiermodell definiert Pro-
grammierschnittstellen (APIs) und Frameworks, mit deren Nutzung mehrschichtige,
lose gekoppelte und skalierbare Geschäftsanwendungen entwickelt werden.

Java EE besteht dabei aus einer Vielzahl an Spezifikationen bzw. Standards, die
durch den JCP erarbeitet werden. JCP steht für den Java Community Process
und bezeichnet einen Zusammenschluss von mehreren Firmen, Vereinigungen und
Einzelpersonen, die in einem vorgeschriebenen Verfahren Spezifikationen für die
Java Technologie erarbeiten. Diese Spezifikationen werden Java Specification Re-
quests (JSR) genannt. Dabei ist es üblich, dass durch eine Spezifikation lediglich
die abstrakte Programmierschnittstelle definiert wird und die konkreten Implemen-
tierungen dafür durch mehrere Anbieter zur Verfügung gestellt werden. Dadurch ist
der Entwickler nicht von einem Hersteller abhängig und kann die Implementierung
jederzeit austauschen.6

In den folgenden Abschnitten wird auf die in der Arbeit verwendeten Spezifikationen
des Java EE Programmiermodells eingegangen.




 4
   Vgl. [EJ10, Kapitel 2]
 5
   [Ull11, Kapitel 1.4.4]
 6
   siehe [Sta06, S. 22]




                                                                                6
2.2 Java EE


2.2.1 Java Persistence API

Der Standard für die Persistenzabbildung in Java EE wurde mit JPA im JSR 317
spezifiziert. Die Java Persistence API ist dabei zusammen mit EJB 3.0 im JSR 220
entstanden.7 Zwar ist JPA eine Java EE Spezifikation, es kann aber genauso in
Java SE Anwendungen eingesetzt werden.8

JPA definiert unter Nutzung eines objektrelationalen Mappers das Persistieren
von Java Objekten in einer relationalen Datenbank. Dabei wird das Data Mapper
Pattern umgesetzt. Das Data Mapper Pattern ist ein Entwurfsmuster zur Separie-
rung von Objekten und der Abbildung dieser in Datenbanktabellen. Die Objekte
haben im Data Mapper Pattern keine direkte Kenntniss von der Datenbank. Die
Abbildung in den Tabellen wird durch einen korrespondierenden Mapper geregelt.9
Die Grundkonzepte von JPA sind Persistent Entities, der Entity Manager, der
Persistence Context, die Persistence Unit und der JPA Provider.

Der zentrale Bestandteil von JPA sind die Persistent Entities.10 Damit werden
einfache Java-Objekte (Plain Old Java Objects, abgekürzt POJOs) bezeichnet, die
über die Entity-Annotation durch JPA persistierbar werden.11 Als POJO wird ein
Java Objekt bezeichnet, dass keine externen Abhängigkeiten zu anderen Schnitt-
stellen oder Frameworks hat und somit keiner Konvention, z.B. hinsichtlich der
Benennung von Klassen oder Methoden, unterworfen ist.12 Sämtliche Informationen
für die Abbildung in der relationalen Datenbank werden in der Persistent Entity
über Annotationen angegeben. Alternativ können diese Informationen in Form von
Deployment Deskriptoren beschrieben werden, was dem Vorgehen vor der Nutzung
von Annotationen entspricht. Ein Deployment Deskriptor ist ein XML Dokument,


 7
   EJB (Enterprise Java Beans) beschreibt ein Programmiermodell zur Entwicklung von Java
    Komponenten, wobei dem Entwickler die Implementierung von infrastrukturellen Code, z.B.
    zur Transaktionssteuerung oder Lastverteilung, abgenommen wird. (Vgl. [OI07, S. 32])
 8
   siehe [Wol10, S. 189]
 9
   Vgl. [Fow03, S. 165 ff.]
10
   In der Arbeit werden für die Persistent Entities auch Synonyme wie JPA Fachklassen oder JPA
    Entity verwendet.
11
   Vgl. [OI07, S. 187 f.]
12
   siehe [Fow]




                                                                                            7
2.2 Java EE


das unteranderem Meta-Informationen für Persistent Entities enthalten kann.13

Das Speichern, Löschen, Laden und Suchen von Persistent Entities in einer Daten-
bank übernimmt ein so genannter Entity Manager. Dabei werden die Persistent
Entities von einem Entity Manager verwaltet. Mit dem Begriff Persistent Unit
werden dabei alle vom Entity Manager verwalteten Klassen bezeichnet. Im Ge-
gensatz dazu werden alle vom Manager verwalteten Entities, also die Objekte der
Klassen einer Persistent Unit, unter dem Begriff Persistence Context zusammenge-
fasst. Dabei unterliegen die Persistent Entities einem Lebenszyklus, der durch die
Verwendung des Entity Managers bestimmt wird, wie Abbildung 2.2 zeigt.14




                  Abb. 2.2: Lebenszyklus einer Persistent Entity aus [Obj]

Wurde eine Persistent Entity mit dem new-Operator instanziiert, befindet sie
sich im Zustand New. Zu dem Zeitpunkt ist die Entity nicht in der Datenbank
abgebildet. Durch die persist- oder merge-Operation des Entity Managers kann
die Persistent Entity dem Persistence Context hinzugefügt werden. Dann wird die
Entity vom Entity Manager verwaltet und ist im so genannten Managed Zustand.
Gleichzeitig wird die Persistent Entity dabei in der Datenbank abgebildet. Entweder
werden neue Datenbankeinträge angelegt oder bestehende aktualisiert. Je nach
Konfiguration kann das auch erst beim Commit einer Transaktion oder durch den
expliziten Aufruf der flush-Methode erfolgen. Dadurch dass die Persistent Entities
13
     siehe [OI07, S. 189 f.]
14
     Vgl. [OI07, S. 194 ff.]




                                                                                      8
2.2 Java EE


im Zustand Managed sind, werden Änderungen der Attributswerte vom Entity
Manager registriert und mit der Datenbank synchronisiert. Mit der find-Methode
des Entity Managers können Persistent Entities aus der Datenbank geladen werden.
Diese sind dann ebenfalls im Managed Zustand. Sollen Entities in der Datenbank
gelöscht werden, genügt es, die remove-Methode vom Entity Manager aufzurufen.
Dafür müssen die Entities jedoch im Managed Zustand sein. Wird der Entity
Manager geschlossen, werden sämtliche Persistent Entities entkoppelt und gelangen
in den Detached Zustand.

Für die Abfrage von Persistent Entities aus der Datenbank wird in JPA eine
Abfragesprache definiert, die Java Persistence Query Language (JPQL). Die JPQL
ist unabhängig von der Persistenzschicht. Das bedeutet, die Abfragen werden nicht
in SQL formuliert, sondern auf Ebene der Objekte. Diese Abfragesprache ist jedoch
SQL-ähnlich bei der Formulierung von Abfragen. Die formulierten JPQL Abfragen
werden über den Entity Manager ausgeführt.15

Da JPA lediglich eine Programmierschnittstelle spezifiziert, muss für die Ver-
wendung eine Implementierung der Schnittstellen eingebunden werden. Solche
Implementierungen werden JPA Provider genannt. Für JPA in der Version 2.0 ist
das Projekt EclipseLink16 die Referenzimplementierung eines JPA Providers.17 In
dieser Arbeit wird jedoch Hibernate als JPA Provider eingesetzt.18

Konfiguriert wird ein JPA Provider über den Deployment Deskriptor in der Datei
persistence.xml. In der persistence.xml werden die Persistence Units definiert
und der Entity Manager konfiguriert. So wird dort z.B. eingestellt, zu welchem
Zeitpunkt Persistent Entities in die Datenbank geschrieben werden oder welche
Caching Methode verwendet wird, um die Performance der Persistenzschicht zu
verbessern.19



15
   Vgl. [OI07, S. 300 ff.]
16
   siehe http://www.eclipse.org/eclipselink
17
   siehe dazu http://www.eclipse.org/org/press-release/20080317_Eclipselink.php
18
   siehe http://www.hibernate.org
19
   Vgl. [OI07, S. 200 ff.]




                                                                                       9
2.2 Java EE


2.2.2 Bean Validation

Der JSR 303 (Bean Validation) definiert für Java einen Standard zur Validierung von
Objekten. Dabei werden Klassen und deren Attribute mit Annotationen versehen,
die die Informationen zur Validierung enthalten. Einige Annotationen werden durch
den Bean Validation Standard bereits vorgegeben. Mit der Size-Annotation kann
beispielsweise die minimale und maximale Größe von Zeichenketten, Arrays und
Listen festgelegt werden. Möglichkeiten zur Formulierung eigener Annotationen
sind ebenso gegeben.20
Dadurch dass die Validierungsregeln deklarativ mit Annotationen hinterlegt wer-
den, ist die Ausführung der Validierung entkoppelt. Diese kann somit an mehreren
Stellen in der Anwendung durchgeführt werden, z.B. im Webframework bei der
Eingabe von Daten in Formularen oder in der Persistenzschicht beim Speichern
von Anwendungsdaten. Der JPA Provider Hibernate bietet mit der Referenzim-
plementierung des JSR 303, Hibernate Validator, unteranderem die Möglichkeit,
die mit Bean-Validation-Annotationen hinterlegten Validierungsregeln im Entity
Manager einzusetzen und somit mit JPA zu vereinen.21


2.2.3 Dependency Injection for Java

Wenn Anwendungen in Java entwickelt werden, bestehen diese aus vielen Klassen,
die sich gegenseitig nutzen, um die erforderten Funktionalitäten umzusetzen. Die
Klassen haben dadurch häufig mehrere Abhängigkeiten zu anderen Klassen. Diese
müssen aufgelöst werden. Das geschieht, indem Objekte von abhängigen Klassen am
Ort ihrer Nutzung erzeugt werden oder bestenfalls bei der Erzeugung von Klassen
über den Konstruktor reingereicht werden. Das Problem bei diesem Vorgehen ist die
enge Kopplung der Klassen untereinander und die Unflexibilität bei Änderungen,
z.B. beim Austausch einzelner Klassen für Testzwecke. Soll die Implementierung
einer Klasse ausgetauscht werden, müssen überall im Programmcode Änderungen
erfolgen. Eine Lösung für dieses Problem ist Dependency Injection. Dabei werden
20
     Vgl. [Wol10, S. 250 ff.]
21
     siehe http://www.hibernate.org/subprojects/validator.html




                                                                               10
2.2 Java EE


abhängige Objekte zur Laufzeit injiziert. Das Objekt, dessen Abhängigkeiten
aufgelöst werden, ist passiv bei diesem Vorgang. Das hat den Vorteil, dass zum
einen große Objektnetze einfach erzeugt werden können, da die Objekte ihre
Abhängigkeiten injiziert bekommen, und zum anderen ist der Austausch von
Implementierungen darüber sehr leicht möglich.22

Mit dem JSR 330, Dependency Injection for Java, werden im Paket javax.inject
Annotationen zur Verfügung gestellt, die die Nutzung und Implementierung von
DI in Java standardisieren. Das Versehen von Attributen, Konstruktoren oder
Methoden mit der Inject-Annotation sorgt dafür, dass die abhängigen Objekte
an dieser Stelle injiziert werden. Um die Dependency Injection feiner zu steuern,
können die Qualifier- und Named-Annotationen verwendet werden.23 In der Arbeit
wird ausschließlich die Inject-Annotation genutzt.

Genau genommen zählt der JSR 330 nicht zu den Java EE Spezifikationen. Aller-
dings ermöglicht die Spezifikation das Bauen von lose gekoppelten Systemen in der
gesamten Java Technologie, wovon Java EE eine Teilmenge ist.


2.2.4 JavaServer Faces

JavaServer Faces (JSF) ist ein komponentenbasiertes Framework für die Entwicklung
von Web-Anwendungen.24 Die in der Arbeit verwendete Version 1.2 wird durch
den JSR 252 spezifiziert.25 Die Referenzimplementierung von JSF ist das Mojarra
Projekt, welches ebenfalls in dieser Arbeit eingesetzt wird.26

Das zugrundeliegende Entwurfsmuster von JSF ist das Model-View-Controller-
Muster (MVC). Durch das MVC-Entwurfsmuster sollen Anwendungen mit einer
grafischen Oberfläche besser strukturiert werden. Ziel ist es, die Bestandteile der
Anwendung wiederverwendbarer, erweiterbarer und wartbarer zu gestalten, indem

22
   Vgl. [Wol10, S. 20]
23
   Vgl. [Wol10, S. 81 ff.]
24
   Vgl. [MM10, S. 6]
25
   siehe http://www.jcp.org/en/jsr/detail?id=252
26
   siehe http://javaserverfaces.java.net




                                                                              11
2.2 Java EE


die Daten (Model), die Darstellung (View) und das Verhalten (Controller) vonein-
ander getrennt implementiert werden.27 Der Einsatz des MVC-Entwurfsmusters in
JSF wird in Abbildung 2.3 gezeigt.




                  Abb. 2.3: MVC-Architektur von JSF aus [MM10]


Der Controller wird in JSF durch das Faces-Servlet implementiert. Dabei wird die
Servlet Technologie der Java EE Plattform verwendet. Servlets werden durch den
JSR 154 beschrieben.28 Für diese Arbeit genügt es zu wissen, dass Servlets den
ersten Versuch darstellten, dynamische Webseiten mit Java zu erzeugen. Servlet
Klassen können auf HTTP Anfragen reagieren und diese beantworten, indem sie
im Java Code z.B. über Streams HTML schreiben.29 In JSF wird die Servlet
Technologie nur intern verwendet. Das Faces-Servlet enthält die Steuerungslogik
einer JSF Anwendung. Dieses Servlet steuert aufgrund einer Anfrage des Clients
den Aufruf des benötigten Views und erzeugt die korrespondierenden Models.

JSF unterstützt bisher zwei verschiedene View-Technologien: Facelets und JSP
(JavaServer Pages). In dieser Arbeit wird Facelets verwendet. Der View wird bei
der Nutzung von Facelets durch XHTML-Dokumente implementiert, die spezifische
Tags aus der Facelets Tag Library enthalten. Eine Tag Library ist eine Sammlung
von XHTML-Tags, die über einen eigenen XML Namensraum (engl. Namespace)

27
   Vgl. [Bos04, S. 45 ff.]
28
   sieh http://www.jcp.org/en/jsr/detail?id=154
29
   Vgl. [MM10, S. 2 ff.]




                                                                             12
2.2 Java EE


eindeutig identifizierbar sind. Außerdem kann die Darstellung bei Verwendung von
Facelets modular aufgebaut werden.30

Ein View bzw. eine Ansicht wird in JSF aus Komponenten zusammengesetzt. Kom-
ponenten sind eigenständige und wiederverwendbare Bausteine. Beim Erzeugen
eines Views wird in JSF ein Komponentenbaum erzeugt. Durch den Komponen-
tenbaum werden die einzelnen Komponenten einer Ansicht miteinander verknüpft.
Das Wurzelelement des Baums wird dabei durch ein Objekt der Klasse UIViewRoot
repräsentiert. Die Komponenten einer Ansicht werden als Kindelemente an das
Wurzelelement gehängt. Die Bearbeitung einer Anfrage, die sich in JSF in meh-
rere Phasen unterteilt, wie Abbildung 2.4 zeigt, beginnt immer mit einem Aufruf
einer Methode des UIViewRoot-Elements, das den Methodenaufruf rekursiv an die
Kindelemente weiterleitet. Über diesen Mechanismus kann jede Komponente einer
Ansicht auf eine Anfrage reagieren.31




              Abb. 2.4: JSF Standard Request-Response-Zyklus aus [EJ10]



30
     siehe [MM10, S. 157 f.]
31
     Vgl. [MM10, S. 20 ff.]




                                                                            13
2.2 Java EE


Ein weiteres wichtiges Konzept stellen die Managed Beans dar, auch Backing Beans
genannt, über die das Model in JSF implementiert wird. Managed Beans sind
normale POJOs. Sie liefern die Werte für die im View definierten Komponenten.
Managed Beans können dabei verschiedene Gültigkeitsbereiche haben, die sich
in der Dauer der Lebenszeit eines Managed Bean Objekts unterscheiden. In JSF
1.2 ist dafür die Dauer der Requestbearbeitung, einer HTTP Session oder auch
die gesamte Dauer der Applikationsausführung möglich. Bevor ein normales Java
Objekt als Managed Bean gilt, muss ein Eintrag in der Konfiguration von JSF
erfolgen.32

Die Konfiguration von JSF wird in der faces-config.xml Datei formuliert. Außerdem
muss JSF in der web.xml Konfigurationsdatei eingerichtet werden. Damit eine
JSF Anwendung funktioniert, muss ein Servlet Container (auch Webcontainer
genannt) als Laufzeitumgebung genutzt werden.33 Ein solcher Servlet Container
nutzt die Informationen aus der web.xml Datei, um z.B. Servlets zu starten. Die
web.xml Datei ist ein Deployment Deskriptor für einen Servlet Container, eine
Bereitstellungsbeschreibung einer Anwendung. Das Faces-Servlet muss dort über
einen Eintrag hinterlegt werden.

§                  Listing 2.1: Eintragung des Faces-Servlet in der web.xml                         ¤
< s e r v l e t>
      <s e r v l e t −name>Faces S e r v l e t</ s e r v l e t −name>
      <s e r v l e t −c l a s s>
              j a v a x . f a c e s . webapp . F a c e s S e r v l e t
      </ s e r v l e t −c l a s s>
      <load−on−s t a r t u p>1</ load−on−s t a r t u p>
</ s e r v l e t>
¦                                                                                                   ¥

Eine JSF-Anwendung wird in Form einer WAR-Datei bereitgestellt. Mit dem
Web Application Archive (WAR) wird eine standardisierte Verzeichnisstruktur für
32
   Das gilt für JSF 1.2. Im neueren JSF 2.0 Standard ist die Definition von Managed Beans über
    Annotationen möglich.
33
   Der Servlet Container war bereits in Abbildung 2.3 in Form der Servlet Engine dargestellt, die
    ein Teil eines Servlet Containers ist.




                                                                                              14
2.2 Java EE


Webanwendungen in Java EE definiert. So enthält beispielsweise das Verzeichnis
WEB-INF in einer WAR-Datei die Konfiguration und Seitenbeschreibungen ei-
ner Web-Anwendung. Als Archivierungsformat wird das bekannte JAR-Format
verwendet.


Unified Expression Language

Mit der Unified Expression Language werden die Komponenten der Ansicht und
die dahinterliegenden Managed Beans miteinander verbunden. Darüber können
im View Daten aus den Managed Beans gelesen und in diese geschrieben werden.
Weiterhin werden über Expression-Language-Ausdrücke (kurz EL-Ausdruck) Me-
thoden für die Ereignisbehandlung von Komponenten im View angegeben. Ein
EL-Ausdruck beginnt mit einer Raute und wird von geschweiften Klammern um-
schlossen. Zwischen den Klammern kann der Name einer Managed Bean stehen und
durch Punkte getrennt die Attribute der Managed Bean. Mit dem Ausdruck #{per-
son.vorname} wird beispielsweise auf das Attribut vorname der Managed Bean
person zugegriffen. Ebenfalls können einfache Operationen in einem EL-Ausdruck
untergebracht werden.34


Standard-Komponenten

JSF bietet eine Palette an Standard-Komponenten. Das sind bereits fertige JSF
Komponenten, die die Grundlage für die Entwicklung von JSF Anwendungen bilden.
Die Standard-Komponenten von JSF werden in den beiden Tag Libraries HTML-
Custom-Tag-Library und Core-Tag-Library implementiert und können durch das
Einbinden des jeweiligen XML Namespaces in einer View-Beschreibung genutzt
werden.35

Die HTML-Custom-Tag-Library im XML-Namensraum h stellt Komponenten zur
HTML-Ausgabe zur Verfügung. Die Core-Tag-Library mit dem XML-Namensraum
f vereint wiederum alle Basis-Komponenten, die für die Nutzung von JSF benötigt
34
     Vgl. [MM10, S. 36 ff.]
35
     Vgl. [MM10, S. 109]




                                                                            15
2.3 Programmiersprache Scala


werden. So wird beispielsweise mit dem f:view Tag der Core-Tag-Library der
Wurzelknoten eines Komponentenbaums in der Ansicht definiert.

Das Einbinden der Namensräume erfolgt bei der Deklaration des HTML-Tags in
der Seitenbeschreibung.

§    Listing 2.2: Einbinden der Namensräume der beiden Standard-Tag-Libraries                     ¤
<html xmlns=" h t t p : / /www. w3 . o r g /1999/ xhtml "
        xmlns : h=" h t t p : / / j a v a . sun . com/ j s f / html "
        xmlns : f=" h t t p : / / j a v a . sun . com/ j s f / c o r e ">
¦                                                                                                 ¥



RichFaces Komponentenbibliothek

Die RichFaces Bibliothek erweitert die JSF Standard-Komponenten um viele
Zusatzkomponenten. Außerdem implementiert RichFaces einige Komponenten mit
Unterstützung für Ajax, was in JSF 1.2 noch nicht vorhanden ist. Zusätzlich dazu
besteht die Möglichkeit, RichFaces Komponenten über einen Theming Mechanismus
durch eine Einstellung in der faces-config.xml im Aussehen anzupassen.



2.3 Programmiersprache Scala

An der École polytechnique fédérale de Lausanne (EPFL) in der Schweiz begann
2001 eine Projektgruppe unter Leitung von Martin Odersky mit dem Entwurf
einer neuen Sprache, die objektorientierte und funktionale Programmierparadigmen
vereinen sollte. Das Ergebnis dieser Arbeit wurde im Jahr 2003 mit der ersten
Version der Programmiersprache Scala veröffentlicht.36

Die Namensgebung soll ausdrücken, dass Scala (aus dem Englischen scalable,
skalierbar) an den Anforderungen des Entwicklers wächst.

Die Programmiersprache Scala setzt auf die Java SE Plattform auf. Scala Code
wird in Java Bytecode kompiliert und durch eine JVM ausgeführt. Außerdem kann
36
     Vgl. [Bra11, Kapitel 1]




                                                                                            16
2.3 Programmiersprache Scala


Scala interpretiert ausgeführt werden. Dazu liegt der Scala Laufzeitumgebung ein
interaktiver Interpreter bei, eine so genannte REPL.37

Im Gegensatz zu Java ist Scala vollständig objektorientiert. Alles ist ein Objekt,
auch primitive Datentypen. Dadurch dass Scala in Java-Bytecode kompiliert wird,
kann von Scala aus Java Code genutzt werden. Scala ist interoperabel mit Java. In
Scala steht also die gesamte Java Standardbibliothek zur Verfügung und sämtliche
andere Java Bibliotheken.

In den nächsten Abschnitten werden die in dieser Arbeit eingesetzten Sprachfeatures
von Scala erläutert.


2.3.1 Klassen und Objekte

Scala ist objektorientiert und unterstützt daher das Konzept der Klassen und
Objekte. Wie in Java wird das Schlüsselwort class zum Definieren einer Klasse
verwendet. Methoden bzw. Funktionen werden mit dem Schlüsselwort def eingeleitet.
Das folgende Listing zeigt eine einfach Scala Klasse, die ein typisches Hello-World-
Beispiel umsetzt.

§                                Listing 2.3: Einfache Scala Klasse                                   ¤
c l a s s HelloWorld ( val g r e e t i n g : S t r i n g ) {


     def s a y H e l l o ( ) = p r i n t l n ( g r e e t i n g )
}


new HelloWorld ( " H a l l o ! " ) . s a y H e l l o ( ) // Ausgabe : H a l l o !
¦                                                                                                     ¥

Mit dem new-Operator wird wie in Java eine Instanz von HelloWorld erzeugt und
anschließend die Methode sayHello ausgeführt.

Anders als bei Java wird in Scala der Konstruktor direkt in Form einer Parame-
terliste hinter dem Klassennamen angegeben. Die HelloWorld Klasse hat einen
37
     Die Read-Execute-Print-Loop beschreibt einen Interpreter, der einen Befehl einliest, ausführt,
      das Ergebnis ausgibt und anschließend auf die nächste Befehlseingabe wartet.




                                                                                               17
2.3 Programmiersprache Scala


Parameter vom Typ String, greeting. Die Typangabe erfolgt in Scala nach der An-
gabe des Bezeichners und mit einem Doppelpunkt getrennt. Mit dem Schlüsselwort
val wird greeting als unveränderbares Feld definiert. Das ist mit der Verwendung
von final in Java vergleichbar. Soll greeting veränderbar sein, wird das Schlüsselwort
var anstalle von val verwendet.

Die Sichtbarkeit von sayHello ist automatisch public. Anders als in Java haben
Methoden und Felder standardmäßig nicht die Sichtbarkeit friendly, sondern public.
Mit den Zugriffsmodifizierern private und protected kann die Sichtbarkeit wie in
Java eingestellt werden.

Die Methode sayHello hat nur eine Aufgabe: den mit greeting übergebenen Wert
auf dem Standardausgabestrom ausgeben. Dazu wird die Methode println des
Predef -Objektes aufgerufen. Das Predef -Objekt wird automatisch vom Compiler
in jede Scala-Datei importiert und stellt oft benötigte Funktionen zur Verfügung.38

Obwohl Scala statisch typisiert ist, muss der Rückgabetyp von sayHello nicht
angegeben werden, da Scala über einen Typinferenz-Mechanismus verfügt. Darüber
kann der Compiler feststellen, welchen Typ ein Wert im Aufrufkontext hat. In
diesem Fall, wird der Typ Unit hergeleitet, vergleichbar mit dem void Typ in Java.
Da println lediglich eine Zeichenkette auf dem Standardausgabestrom ausgibt, wird
der Typ Unit zurückgegeben.

Aufgrund der funktionalen Natur von Scala hat alles in Scala einen Wert. Anders
als in Java muss zum Zurückgeben eines Wertes nicht return verwendet werden, es
gilt der Wert des letzten Ausdrucks eines Programmblocks als Rückgabewert.

Neben der Typinferenz verfügt Scala ebenfalls über eine Semikoloninferenz. Semi-
kolons sind in Scala nicht notwendig, um das Ende eines Befehls zu signalisieren
und werden größtenteils weggelassen.

Ein Scala eigenes Sprachmittel sind Singleton Objekte.39 Die Idee des Singletons
entstammt einem Entwurfsmuster, bei dem von einer Klasse genau eine Instanz

38
     Außerdem werden dort auch wichtige Typ-Synonyme und Implicit Conversions definiert.
39
     Die Begriffe Objekt und Singleton werden in dieser Arbeit als Synonyme für den Begriff der
      Singleton Objekte verwendet.




                                                                                          18
2.3 Programmiersprache Scala


existiert und ein globaler Zugriff darauf.40 Scala verallgemeinert dieses Muster mit
der Nutzung des Schlüsselworts object und unterstützt es direkt in der Sprache.
In Singleton Objekten werden in Scala statische Werte und Methoden implemen-
tiert. Statische Methoden mit dem Schlüsselwort static wie in Java zu definieren,
ist nicht möglich. Hierbei trennt Scala zwischen nicht-statischen und statischen
Programmcode-Teilen. Sollen einer Klasse statische Felder oder Methoden hinzuge-
fügt werden, existiert in Scala dafür das Companion Objekt, welches im folgenden
Listing für das Hello-World-Beispiel implementiert ist. An der Implementierung
der HelloWorld-Klasse ändert sich dabei nichts.

§                Listing 2.4: Klasse mit dazugehörigem Companion Objekt                           ¤
c l a s s HelloWorld ( val g r e e t i n g : S t r i n g ) {


     def s a y H e l l o ( ) = p r i n t l n ( g r e e t i n g )
}


object HelloWorld {


     def apply ( ) = new HelloWorld ( " Standard Meldung " )


     def sayHi ( ) = p r i n t l n ( " Hi ! " )
}


HelloWorld ( ) . s a y H e l l o ( ) // Ausgabe : Standard Meldung
HelloWorld . sayHi ( ) // Ausgabe : Hi !
¦                                                                                                 ¥

Ein Companion Objekt ist ein spezielles Singleton Objekt, das den gleichen Na-
men wie eine Klasse hat und sich in der selben Quellcode-Datei befindet. Im
Companion Objekt HelloWorld werden zwei Methoden definiert, apply und say-
Hi. Die sayHi Methode stellt eine normale statische Methode dar, die über den
Namen des Companion Objekts aufgerufen werden kann. Die abgebildete apply-
Methode ist eine Besonderheit bei der Nutzung von Companion Objekten. Mit
40
     Vgl. [EG95, S. 127]




                                                                                            19
2.3 Programmiersprache Scala


der apply-Methode existiert eine eingebaute Fabrik-Methode in Scala. In einer
apply-Methode wird eine Instanz der Klasse des Companion Objektes erzeugt und
zurückgegeben. Der Vorteil dabei ist, Scala erlaubt das Weglassen des Aufrufs der
apply-Methode. So kann HelloWorld().sayHello() geschrieben werden, was vom
Compiler zu HelloWorld.apply().sayHello() erweitert wird. Die apply-Methode kann
natürlich beliebige Parameter aufnehmen.


2.3.2 Traits

Ein neues Sprachmittel, dass mit Scala eingeführt wird, sind Traits, die die aus Java
bekannten Interfaces ersetzen. Ein Trait ist mit einem Java Interface vergleichbar.
Allerdings mit dem Unterschied, dass Traits neben der Deklaration von Methoden
auch Implementierungen beinhalten können. Ein Trait wird mit dem Schlüsselwort
trait definiert, wie im folgenden Listing zu sehen ist.

§                        Listing 2.5: Beispiel der Nutzung von Traits                   ¤
t r a i t HasName {


    val name = "Name von etwas "
}


t r a i t HasAge {


    def c a l c u l a t e A g e : I n t
}


c l a s s Person extends HasName with HasAge {


    def c a l c u l a t e A g e = 18
    override val name = "Name e i n e r Person "
}
¦                                                                                       ¥




                                                                                  20
2.3 Programmiersprache Scala


Wie bei der Klasse Person zu sehen ist, können Klassen mehrere Traits implemen-
tieren. Der erste Trait wird immer mit extends hinzugefügt, alle folgenden mit
dem Schlüsselwort with. Scala unterstützt allerdings keine Mehrfachvererbung. Es
handelt sich dabei um einen so genannten Mixin-Mechnismus. Ein Mixin ist eine
wiederverwendbare Einheit, die zusammengehörige Funktionen bündelt.41 In diesem
Zusammenhang wird auch vom Einmixen eines Traits gesprochen. Mögliche Proble-
me, die bei Mehrfachvererbung auftreten, wie z.B. das Diamond Problem, werden
bei Traits mit Hilfe von Linearisierung umgangen. Dabei werden die eingemixten
Traits und Klassen der Vererbungshierarchie in der Reihenfolge des Einmixen in
Form einer Liste aufeinander gelegt, wodurch Methoden, die in unterschiedlichen
Typen mehrfach definiert sind, für den Compiler auflösbar bleiben.42

Im Listing 2.5 ist außerdem zu erkennen, dass in Scala mit override ein spezielles
Schlüsselwort für das Überschreiben von Methoden und Feldern existiert. Da
calculateAge noch keine Implementierung in HasAge hat, ist override bei dieser
Methode nicht notwendig. Es kann jedoch angegeben werden.


2.3.3 Funktionen

Da Scala neben den objektorientierten Programmierparadigmen ebenfalls funktio-
nale Paradigmen einschließt, sind Funktionen einer der wichtigsten Bestandteile
der Sprache. Funktionen sind in Scala so genannte First Class Values, auch First
Class Citizens genannt, was bedeutet, sie werden als Werte behandelt und können
als solche Variablen zugewiesen werden oder als Parameter anderen Funktionen
übergeben werden. Ebenso ist es möglich, dass Funktionen andere Funktionen als
Rückgabewert zurückgeben.43

Eine Funktion wird mit dem Schlüsselwort def definiert, was bereits in den voran-
gegangenen Abschnitten gezeigt wurde. Alternativ dazu besteht die Möglichkeit,
Funktionen über Funktionsliterale zu definieren Das folgende Listing zeigt die

41
   Vgl. [Bra11, S. 84]
42
   siehe [MO08, Kapitel 12.6]
43
   Vgl. [Bra11, Kapitel 5.2]




                                                                               21
2.3 Programmiersprache Scala


Funktion dec, die über def angelegt wird und anschließend alternativ als Funkti-
onsliteral.

§                      Listing 2.6: Beispiel einer einfachen Funktion                         ¤
def dec ( i : I n t ) = i − 1


// F u n k t i o n s l i t e r a l f ü r dec
( i : Int ) = i − 1
             >
¦                                                                                             ¥

Ein Funktionsliteral wird dabei mit einem Doppelpfeil angegeben.44 Links davon
steht die Parameterliste der Funktion und rechts davon die Befehle der Funktion.

Beide Schreibweisen erzeugen das gleiche Ergebnis. Der Vorteil des Funktionsliterals
ist, dass eine Funktion darüber sehr einfach als Wert zugewiesen werden kann,
was im Listing 2.7 zu sehen ist. Ebenfalls wird durch Funktionsliterale die Angabe
anonymer Funktionen erleichtert.

§               Listing 2.7: Beispiel der Zuweisung eines Funktionswertes                     ¤
val d e c F u n c t i o n = ( i : I n t ) = i − 1
                                           >


p r i n t l n ( d e c F u n c t i o n ( 4 ) ) // Ausgabe : 3
¦                                                                                             ¥



Funktionen höherer Ordnung

Mit dem Begriff der Funktionen höherer Ordnung werden Funktionen bezeichnet,
bei denen Parameter oder der Rückgabewert aus einer Funktion bestehen. Das ist
ein hilfreiches Mittel zur Abstraktion von allgemeinem Verhalten, wie das folgende
Listing zeigt.45

§               Listing 2.8: Anwendung einer Funktion höherer Ordnung                         ¤
def dec ( i : I n t ) = i − 1
def d e c L i s t ( l i s t : L i s t [ I n t ] ) = l i s t map dec
44
     Der Doppelpfeil setzt sich aus einem Gleichheitszeichen und einem Pfeil zusammen.
45
     siehe [Bra11, Kapitel 5.3]




                                                                                         22
2.3 Programmiersprache Scala



p r i n t l n ( d e c L i s t ( L i s t ( 1 , 2 , 3 ) ) ) // Ausgabe : L i s t ( 0 , 1 , 2 )
¦                                                                                                   ¥

In der Funktion decList wird die Dekrementierungsfunktion dec auf alle Elemente
der übergebenen Liste angewendet. Dazu wird die Funktion höherer Ordnung
namens map verwendet. Die map Funktion gehört zur Collections API von Scala.
map wendet die übergebene Funktion dec auf alle Elemente der Liste an und gibt
die dadurch neu enstandene Liste als Ergebnis zurück. In der decList Funktion
kommen gleich mehrere Scala-Besonderheiten zum Einsatz, die den Aufruf von
map verkürzen. In der vollen Länge wird map hier wie folgt aufgerufen.

§               Listing 2.9: Vollständig ausgeschriebener Aufruf von map                            ¤
l i s t . map ( ( i : I n t ) = dec ( i ) )
                               >
¦                                                                                                   ¥

In dieser Form macht das Funktionsliteral, das map als Parameter übergeben
wird, deutlich, dass es sich um eine Funktion höherer Ordnung handelt. Durch die
Typinferenz kann Int in der Parameterliste des Funktionsliterals weggelassen werden.
Da dec ledigleich einen Parameter erwartet, kann die Angabe des Parameters i
ebenfalls entfallen. Der Scala Compiler setzt dann einen automatisch generierten
Platzhalter an der Stelle für i ein. Dieser Platzhalter hätte auch explizit mit einem
Unterstrich angegeben werden können.

§             Listing 2.10: Aufruf der map Funktion mit einem Platzhalter                           ¤
l i s t . map( dec (_) )
¦                                                                                                   ¥

Als weitere Möglichkeit der Vereinfachung wird abschließend die Infix-Operator-
Schreibweise46 für Funktionen verwendet, wodurch der in Listing 2.8 gezeigte Aufruf
der map Funktion zustandekommt. Da Operatoren in Scala auch nur Methoden
von Klassen sind, kann die Infix-Operator-Schreibweise bei Funktionen verwendet
werden.47


46
     Dabei steht ein Operator zwischen seinen zwei Operanden.
47
     Vgl. [MO08, Kapitel 5.3]




                                                                                               23
2.3 Programmiersprache Scala


Beim Aufruf von decList in der println Methode wird das Companion Objekt von
List genutzt und intern die apply-Methode aufgerufen. Denn der Aufruf List(1, 2,
3) wird vom Compiler zu List.apply(1, 2, 3) erweitert.


Currying

Unter Currying wird das Abbilden einer Funktion mit mehreren Parametern, auf
mehrere Funktionen mit je einem Parameter verstanden. In Scala gilt dies ebenso
für Funktionen mit Parameterlisten. Dadurch können Funktionen mit mehreren
Parameterlisten definiert werden, wie das folgende Listing zeigt.48

§          Listing 2.11: Beispiel einer Funktion mit mehreren Parameterlisten           ¤
def sub ( x : I n t ) ( y : I n t ) = x − y


p r i n t l n ( sub ( 2 ) ( 3 ) ) // Ausgabe : −1
¦                                                                                       ¥

Die Auflösung einer solchen Funktion durch den Compiler kann wie folgt veran-
schaulicht werden.

§          Listing 2.12: Abbildung der sub Funktion auf mehrere Funktionen              ¤
def sub ( x : I n t ) = ( y : I n t ) = x − y
                                       >
¦                                                                                       ¥

Die sub Funktion hat nur noch eine Parameterliste und in der Funktion selbst wird
ein Funktionsliteral mit der zweiten Parameterliste definiert. Der Aufruf dieser
Funktion gestaltet sich genauso, wie von der in Listing 2.11 gezeigten Funktion.


Partielle Funktionen

Bei den partiellen Funktionen muss zwischen den partiellen und den partiell ange-
wandten Funktionen unterschieden werden.
Eine partielle Funktion ist eine Funktion, die nicht für alle Werte ihres Definitions-
bereichs definiert ist.49 Anwendungen solcher Funktionen werden im nachfolgenden
48
     siehe [Bra11, Kapitel 5.5]
49
     Vgl. [Bra11, S. 124]




                                                                                  24
2.3 Programmiersprache Scala


Kapitel über Pattern Matching gezeigt. Mit dem Trait PartialFunction existieren
außerdem Hilfsfunktionen, um beispielsweise zu bestimmen, ob eine Funktion für
einen bestimmten Wert ihres Definitionsbereichs definiert ist.50

Eine partiell angewandte Funktion hingegen ist eine Funktion, die auf einen Teil
ihrer Parameter bereits angewendet ist.51 Es ist häufig der Fall, dass partiell
angewandte Funktionen zusammen mit Currying eingesetzt werden, indem eine
Parameterliste bereits angewendet wird und eine weitere zur Aufnahme zusätzlicher
Parameter dient. Im folgenden Beispiel wird die sub Funktion aus dem Listing 2.11
partiell angewendet und einem Wert zugewiesen.

§               Listing 2.13: Beispiel einer partiell angewandten Funktion            ¤
val subTwoWith = sub ( 2 ) _


p r i n t l n ( subTwoWith ( 3 ) ) // Ausgabe : −1
¦                                                                                     ¥

Der Unterstrich dient hierbei als Platzhalter für die zweite Parameterliste. Die
Signatur der in subTwoWith gespeicherten Funktion lautet Int => Int. Es wird
dabei also eine neue Funktion mit nur einer Parameterliste erzeugt, die intern auf
die sub Funktion zugreift.

Die wirkliche Stärke dieses Sprachmittels wird deutlich, wenn anstatt des einfachen
Parameters mit dem Zahlenwert 3 eine Funktion verwendet wird, wie im folgenden
Listing.

§         Listing 2.14: Kontrollstruktur-ähnliche Konstrukte mit subTwoWith           ¤
p r i n t l n ( subTwoWith {
     val n i n e = 4 + 5
     val s i x = 2 + 4
     nine − s i x
})
¦                                                                                     ¥


50
     Die Funktion dafür lautet isDefinedAt.
51
     Vgl. [MO08, S. 147]




                                                                                25
2.3 Programmiersprache Scala


Das Ergebnis dieses Aufrufs von subToWith ist das gleiche wie im vorangegangenen
Listing. Durch die Verwendung der geschweiften Klammern und der Formulierung
eines Funktionsblocks wirkt die Verwendung von subTwoWith wie eine Scala-eigene
Kontrollstruktur. Solche Konstrukte sind bei der Verwendung von Scala häufig
anzutreffen.


2.3.4 Pattern Matching

Pattern Matching kann für einen Java Entwickler als Erweiterung der Switch-
Case-Kontrollstruktur erklärt werden. Beim Pattern Matching wird ein Wert mit
Mustern verglichen. Die Besonderheit bei Scala ist, dass nicht nur Werte als Muster
angegeben werden können, sondern auch Typen.52 Eine einfache Anwendung von
Pattern Matching zeigt das folgende Beispiel.53

§                 Listing 2.15: Bespiel von Pattern Matching in printInt                      ¤
def p r i n t I n t ( i : I n t ) = i match {
     case 1 = p r i n t l n ( " Eins " )
             >
     case 2 = p r i n t l n ( " Zwei " )
             >
     case _ = p r i n t l n ( " e i n e a n d e r e Zahl " )
             >
}


p r i n t I n t ( 2 ) // Ausgabe : Zwei
¦                                                                                             ¥

Mit dem Schlüsselwort match wird ein Pattern-Matching-Ausdruck eingeleitet und
in diesem Fall auf den Parameter i angewendet. Mit case werden die einzelnen Mus-
ter definiert, gegen die i verglichen wird. Der Doppelpfeil leitet den Codeblock ein,
der ausgeführt wird, sollte das jeweilige Muster passt. Nachdem ein Muster gepasst
hat, kehrt die Ausführung aus dem Match-Ausdruck zurück. Der Rückgabewert
entspricht dem des ausgeführten Codeblocks.
Mit dem Unterstrich wird das Wildcard-Pattern definiert, das auf jeden Wert und
Typen passt. Wird das Wildcard-Pattern weggelassen, ist der Match-Ausdruck
52
     siehe [Bra11, Kapitel 5.4]
53
     in Anlehnung an [Bra11, S. 115]




                                                                                        26
2.3 Programmiersprache Scala


mitunter nicht für alle Werte des Definitionsbereichs definiert. Ist ein solcher Match-
Ausdruck die einzige Anweisung einer Funktion, wird die Funktion zur partiellen
Funktion, wie das folgende Listing zeigt.54

§          Listing 2.16: Pattern Matching in Form einer partiellen Funktion              ¤
def printType ( v a l u e : Any) = v a l u e match {
     case i : I n t = p r i n t l n ( " I n t : " + i )
                     >
     case d : Double = p r i n t l n ( " Double : " + d )
                      >
}


printType ( 2 ) // Ausgabe : I n t : 2
¦                                                                                        ¥

Die printType Funktion verwendet für den Mustervergleich Typen. Außerdem
ist diese Funktion eine partielle Funktion, da sie nur für Int und Double Typen
definiert ist, obwohl der Definitionsbereich Any ist. Any ist der Basistyp des Scala-
Typsystems. Wird printType beispielsweise mit einer Zeichenkette aufgerufen, wird
zur Laufzeit ein MatchError erzeugt, da die Funktion für den String-Typ nicht
definiert ist.


2.3.5 Self-Type Annotationen

Self-Type-Annotationen ermöglichen es, den Typ des this Wertes explizit zu dekla-
rieren. Dadurch können Funktionalitäten einer Klasse modular verteilt in mehreren
Traits implementiert werden oder aber ein Trait kann Abhängigkeiten festlegen,
die seine Funktionen benötigen und durch das Einmixen in die richtigen Klassen
aufgelöst werden.55 Ein Beispiel für den Einsatz einer Self-Type Annotation wird
im folgenden Listing gezeigt.56




54
   in Anlehnung an [Bra11, S. 116]
55
   siehe [Bra11, S. 160 ff.]
56
   entnommen aus [Bra11, S. 161]




                                                                                   27
2.3 Programmiersprache Scala


§                    Listing 2.17: Beispiel einer Self-Type Annotation                             ¤
trait Noise {
     def makeNoise : Unit
}


t r a i t Food {
     def e a t : Unit
}


t r a i t Animal {


     t h i s : N o i s e with Food =>


     def run = {
         makeNoise
         eat
         makeNoise
     }
}
¦                                                                                                  ¥

Eine Self-Type-Annotation wird zu Beginn einer Typ-Definition formuliert. Sie
besteht dabei aus dem Schlüsselwort this,57 der Typangabe, die gewohnt mit einem
Doppelpunkt vom Bezeichner getrennt wird und einem Doppelpfeil. Dadurch
dass der Animal Trait die Self-Type Annotation Noise with Food hat, kann er
nur in Klassen eingemixt werden, die diese beiden Traits ebenfalls einmixen und
implementieren. Animal kann außerdem auf die Methoden (und Felder) von Noise
und Food zugreifen.




57
     Alternativ kann auch self verwendet werden. Da this jedoch deutlicher aussagt, dass der Typ
      des this Wertes überschrieben wird, ist diese Variante zu bevorzugen.




                                                                                             28
2.3 Programmiersprache Scala


2.3.6 Implicit Conversions

Mit Implicit Conversions können in Scala Typumwandlungen in Form von Methoden
definiert werden. Wird eine Methode mit dem vorangestellten Schlüsselwort implicit
definiert, gilt sie als Implicit Conversion.

Erwartet der Compiler ein Objekt eines bestimmten Typs, findet jedoch ein Objekt
eines inkompatiblen Typen vor, sucht er nach einer Implicit Conversion. Findet
der Compiler eine passende Umwandlung, führt er die Methode aus. Durch dieses
Sprachmittel können in Scala bestehende Klassen um zusätzliche Funktionen
erweitert werden. Das wird auch als Pimp-my-Library-Pattern bezeichnet.58 Wie
einfach die Nutzung von Implicit Conversions ist, zeigt das nachfolgende Listing.

§                        Listing 2.18: Beispiel einer Implicit Conversion                               ¤
c l a s s F a n c y S t r i n g ( val s t r : S t r i n g ) {


     def d o F a n c y S t u f f = s t r + " f a n c y "
}


object F a n c y S t r i n g {


     i m p l i c i t def s t r i n g T o F a n c y S t r i n g ( s t r : S t r i n g )
        : F a n c y S t r i n g = new F a n c y S t r i n g ( s t r )
}


import F a n c y S t r i n g ._
p r i n t l n ( " H a l l o " . d o F a n c y S t u f f ) // Ausgabe : H a l l o f a n c y
¦                                                                                                       ¥

Die Klasse String der Java Standardbibliothek wird hierbei durch FancyString
und die im Companion Objekt implementiere Typumwandlung um die Methode
doFancyStuff erweitert. Obwohl diese Methode nicht in der String Klasse definiert
ist, kann sie dadurch an einem String Objekt aufgerufen werden. Vor dem Aufruf
von doFancyStuff wird der Compiler das String-Objekt „Hallo“ dafür mit Hilfe
58
     siehe http://www.artima.com/weblogs/viewpost.jsp?thread=179766




                                                                                                  29
2.4 Lift Web-Framework


von stringToFancyString in ein Objekt des Typs FancyString umwandeln. Damit
die Implicit Conversion vom Compiler gefunden wird, importiert die Anweisung
import FancyString._ die Felder und Methoden von FancyString.



2.4 Lift Web-Framework

Im Jahr 2007 startete die Entwicklung von Lift. Das Lift Framework ist ein in
Scala entwickeltes Framework zur Entwicklung von Web-Anwendungen. Es ist
ein so genanntes Full-Stack Web-Framework. Das bedeutet, neben Funktionen
zur Erzeugung von Webseiten werden z.B. auch Funktionalitäten zum Speichern
der Anwendungsdaten in einer Datenbank angeboten oder für die Validierung
der Nutzereingaben. Ohne die Nutzung anderer Bibliotheken kann mit Lift eine
komplette Web-Anwendung entwickelt werden.

Lift baut auf bewährte Konzepte anderer Web-Frameworks auf und versucht diese
zu vereinen. So wird beispielsweise der Ansatz der Convention over Configuration
befolgt, der vom Web-Framework Ruby on Rails59 inspiriert wurde. Mit Convention
over Configuration soll der Aufwand und die Komplexität der Konfiguration und
Nutzung des Frameworks gesenkt werden, indem sinnvolle Vorgaben und Annahmen
vom Framework über die Nutzung getroffen werden, wie z.B. eine vorgegebene
Verzeichnisstuktur.

Lift ist allerdings kein MVC-Framework wie JSF.60 In Lift wird ein selbstdefiniertes
Entwurfsmuster verwendet. Die Lift-Entwickler verfolgen den View-First-Ansatz
für den Entwurf von Web-Anwendungen, wobei ein als View-ViewModel-Model
beschreibbares Entwurfsmuster eingesetzt wird, das in Abbildung 2.5 zu sehen ist.61

Der View-First-Ansatz besagt, dass in der Beschreibung der Seitendarstellung
ausschließlich valide Standard XHTML-Tags verwendet werden und wurde durch


59
   siehe http://rubyonrails.org
60
   Wobei MVC mit Lift sehr wohl umsetzbar ist. Das hat der Hauptentwickler von Lift, David
    Pollak, exemplarisch gezeigt. (siehe dazu [Pol, Kapitel 12 und 13])
61
   Vgl. [Per11, S. 7 f.]




                                                                                       30
2.4 Lift Web-Framework




            Abb. 2.5: Kontrollfluss im View-First-Ansatz von Lift aus [Per11]


das Java Web-Framework Wicket62 inspiriert. In Lift wird ein View daher in Form
von XML-Dokumenten beschrieben, die bestenfalls ausschließlich Standard XHTML
Tags enthalten.

Snippets sind das wichtigste Konzept von Lift. Als Snippet wird eine Funktion
bezeichnet, die XML-Knoten transformiert.63 Snippets sind das ViewModel im
View-First-Ansatz und sorgen für die Generierung von dynamischen Seiteninhalten.
Dabei verbinden sie den View mit dem Model, das die Fachentitäten der Anwendung
darstellt. Dabei kann ein View durchaus mehrere Snippets nutzen. Im Gegensatz
zum View können Snippets zustandsbehaftet sein. Auch wenn das Snippet in der
Abbildung 2.5 wie ein Controller gemäß dem MVC-Muster aussieht, ist es das nicht.
Ein Snippet übernimmt nicht die Steuerung des Kontrollflusses.

Außerdem baut das Lift Framework auf der Java EE Plattform auf. Über die Servlet
Technologie integriert sich Lift in Java EE Webcontainer, was unteranderem in
Abbildung 2.6 dargestellt wird. Wie eine JSF-Anwendung werden Lift-Anwendungen
in Form von WAR-Dateien bereitgestellt.

62
     siehe http://wicket.apache.org
63
     In der Arbeit werden teilweise auch die Klassen als Snippet bezeichnet, die eine solche Funktion
      enthalten.




                                                                                                  31
2.4 Lift Web-Framework




                         Abb. 2.6: Architektur von Lift aus [DCB11]


Lift implementiert mehrere Persistenzlösungen. Die Standard-Persistenzlösung
nennt sich Mapper. Die Mapper Bibliothek implementiert unter Nutzung des Active
Record Patterns die Abbildung von Objekten in einer relationalen Datenbank.
Beim Active Record Pattern befindet sich die Logik für den Datenbankzugriff im
Domänenobjekt. Außerdem repräsentiert ein Domänenobjekt bei Active Record
einen Datenbankeintrag.64 Gleichzeitig ist Mapper, wie es der Name bereits andeutet,
ein objektrelationaler Mapper. Die Doppeldeutigkeit von Mapper als Umsetzung des
Active Record Patterns und objektrelationaler Mapper ist auf die Art und Weise der
Implementierung zurückzuführen. Lift Mapper Funktionalitäten werden mit Traits
in die Domänenobjekte eingemixt. Dadurch ist die Logik für den Datenbankzugriff
zwar in den Domänenobjekten, aber implementiert wird sie separiert in den Mapper

64
     Vgl. [Fow03, S. 160 f.]




                                                                                 32
2.4 Lift Web-Framework


Traits. Intern nutzt Mapper die Java SE Datenbankschnittstelle JDBC (Java
Database Connectivity).65

Zusätzlich bietet Lift eine Abstraktionsschicht für Ajax und JavaScript, wodurch
JavaScript-Befehle und Ajax Aufrufe in reinem Scala-Code formuliert werden
können. Dabei wird intern die JavaScript-Bibliothek JQuery66 eingesetzt. Alternativ
kann YUI67 verwendet werden.




65
   Vgl. [Per11, S. 13]
66
   siehe http://jquery.com
67
   siehe http://developer.yahoo.com/yui




                                                                                33
3 Methodik der Evaluation

3.1 Beschreibung der Evaluation

Für die Evaluation der beiden Technologiestacks werden folgende zwei Methoden
eingesetzt:

  • Literaturstudium

  • Umsetzung einer prototypischen Beispielanwendung

Durch das Literaturstudium wird der Blick in die Interna der jeweiligen Frameworks
ermöglicht. Dieser wäre ohne ein solches Studium nicht möglich. Die alleinige Im-
plementierung einer prototypischen Anwendung führt zwar zur Auseinandersetzung
mit der API der jeweiligen Technologie. Jedoch sind dadurch nicht zwangsläufig
die internen Mechanismen geklärt. Mögliche Stärken und Schwächen, die sich nicht
durch die Nutzung der API zeigen, würden somit auch nicht in die Evaluation
einfließen.

Die Ergebnisse aus dem Literaturstudium werden beim Vergleich der beiden imple-
mentierten Lösungen eingebracht.

Die wichtigste Grundlage für die Evaluation ist die Entwicklung einer prototypischen
Beispielanwendung. Für jeden Technologiestack wird ein Prototyp für die im
Abschnitt 4.1.2 formulierten Anwendungsfälle entwickelt. Der Fokus liegt dabei auf
dem Einsatz der jeweiligen Frameworkspezifika und nicht auf der bestmöglichen
Umsetzung der Anforderungen. Die implementierten Prototypen sind nicht für den
produktiven Einsatz vorgesehen.




                                                                                 34
3.2 Evaluationskriterien


3.2 Evaluationskriterien

Die Evaluation wird anhand von Evaluationskriterien durchgeführt, um das Ergebnis
möglichst objektiv und für den Leser transparent zu gestalten.

Die Auswahl der Evaluationskriterien für diese Arbeit orientiert sich an gängigen
Standards und Erkenntnissen der Softwareentwicklung sowie den Erfahrungswerten
des Autors. Dabei spielen ebenso einfache Faktoren wie die reine Funktionalität
eine Rolle als auch Faktoren, die die Struktur und den Aufbau des Programmcodes
betreffen.


3.2.1 Allgemeines

Beim Vergleich von Technologien und Frameworks gibt es allgemeingültige Kriterien
wie z.B. die Integration in die Entwicklungswerkzeuge, die bei jedem Vergleich
anwendbar sind.


Dokumentation

Beschäftigt sich ein Entwickler mit Technologien, so wird eine gute Dokumentation
erwartet. Die Dokumentation sollte dabei eine Spezifikation der API enthalten,
als auch beschreibende Anleitungen zu Anwendungsfällen. Ebenso zählt zur Doku-
mentation das Vorhandensein von Büchern zur Einführung und Vertiefung in die
Technologie.

Im Verlauf der Entwicklung der Prototypen hat sich gezeigt, dass es sehr wohl Unter-
schiede in der Qualität und Quantität der Dokumentationsmaterialien gibt. Daher
wird bei diesem Kriterium die Dokumentation der Technologiestacks beurteilt.


Lernkurve

Eignen sich Softwareentwickler Kenntnisse über neue Sprachen und Frameworks
an, gibt es eine so genannte Lernkurve. Unter der Lernkurve wird der nötige



                                                                                 35
3.2 Evaluationskriterien


Lernaufwand verstanden, der zum Erreichen eines bestimmten Ergebnisses nötig
ist.

Der Autor hat Java EE im November 2010 kennengelernt. Für diese Arbeit hat er
Scala und Lift gelernt. Daher sind die Ergebnisse zur Lernkurve reine Erfahrungs-
werte, die einen Eindruck vermitteln sollen, in welchem Verhältnis die Lernaufwände
für die beiden Technologiestacks stehen.


Toolchain

Die Toolchain bezeichnet umgangssprachlich die Werkzeugkiste eines jeden Soft-
wareentwicklers. Damit sind die Programme gemeint, die der Entwickler für seine
Arbeiten einsetzt. Im heutigen Entwicklungsgeschäft ist es wichtig, dass sich die
eingesetzen Techniken reibungslos in die Toolchain integrieren lassen. Dies steigert
die Produktivität und ist somit von großer Bedeutung.

Es gilt bei der Toolchain zu untersuchen, in welchem Maße sich die jeweiligen
Frameworks in die eingesetzten Programme integrieren lassen und welche Vor- und
Nachteile durch diese Integration entstehen.


3.2.2 Funktionalität

Bei der Entwicklung von Web-Anwendungen treten oft ähnliche Anforderungen
an die verwendeten Frameworks und Technologien auf. Daher werden die beiden
entwickelten Lösungen auf die Unterstützung der im folgenden Abschnitt beschrie-
benen Funktionalitäten untersucht und bewertet. Die Auswahl dieser Kriterien
wurde maßgeblich durch [Wan08] beeinflusst.


Persistenzmechanismen

Heutzutage kommt keine Web-Anwendung ohne einen entsprechenden Persistenz-
mechanismus aus. Die Daten der Anwendung und des Nutzers müssen für die Dauer
einer Sitzung und über die Laufzeit der Anwendung hinweg gespeichert werden.



                                                                                 36
3.2 Evaluationskriterien


Es wird untersucht, welche Persistenztechnologien die Frameworks unterstützen
und gezeigt, wie der so genannte objektrelationale Mismatch gelöst wird. Aufgrund
der Verschiedenheit Daten objektorientiert und relational abzubilden, gibt es bei
der Persistierung eines objektorientierten Domänenmodells in eine releationale
Datenbank eine Unverträglichkeit; einen Mismatch, den es zu lösen gilt.1 Weiterhin
wird die Umsetzung in den jeweiligen Lösungen aufgrund der Integration in das
bestehende Domänenmodell und der Funktionalität bewertet.


Darstellungskonzept

Jede Anwendung stellt die Daten für den Nutzer auf dem Bildschirm in irgend-
einer Form dar. Frameworks bieten unterschiedliche Konzepte, wie diese Ansicht
aufzubauen und mit dem Rest der Anwendung zu verbinden ist.

Hier gilt es zu untersuchen, wie naht- und reibungslos sich die unterschiedlichen Dar-
stellungskonzepte mit den anderen Anwendungsteilen verbinden lassen. Ebenfalls
wird aufgezeigt, welche Vor- und Nachteile die unterschiedlichen Ansätze bieten.


Ajax-Unterstützung

In den letzten Jahren hat sich Ajax als Technologie für hochgradig interaktive
Anwendungen durchgesetzt. Dabei werden Inhalte vom Server asynchron in Form
von XML durch den Client nachgeladen. Dies geschieht für den Nutzer transparent
im Hintergrund. Ein Neuladen der Seite ist nicht erforderlich.

Die eingesetzten Frameworks werden daraufhin untersucht und bewertet, inwiefern
Ajax unterstützt wird und welche Qualität die Ajax-Integration aufweist.


Validierung

Die Validierung von Nutzereingaben ist in jeder Anwendung wichtig. Die Eingaben
müssen auf bewusst falsche Angaben und fachliche Inkonsistenzen geprüft werden.
 1
     Vgl. [Röd10, Kapitel 1]




                                                                                   37
3.2 Evaluationskriterien


Für die Validierung wird bewertet, wie sich die formulierten Validierungsregeln
in das Domänenmodell einpflegen lassen, welche Möglichkeiten zur Validierung
durch das Framework bereits angeboten werden und wie sich die Validierung in die
anderen Frameworkteile integriert.


Internationalisierung

Web-Anwendungen werden nicht ausschließlich in der Muttersprache des Kunden
ausgeliefert. Da diese Anwendungen in den meisten Fällen von Nutzern unterschied-
licher Sprachen genutzt werden, sind die Beschriftungen und Texte so zu gestalten,
dass sie dynamisch ladbar sind. Abhängig von der Spracheinstellung des Nutzers
wird die Anwendung in einer anderen Sprache dargestellt.

Es gilt zu untersuchen, welche Mechanismen die Technologiestacks für diese Form
der Internationalisierung von Anwendungen zur Verfügung stellen und wie sich
diese in die Anwendung integrieren.


3.2.3 Architektur

Laut [Bal01] kann Softwarearchitektur als „eine strukturierte oder hierarchische
Anordnung der Systemkomponenten sowie Beschreibung ihrer Beziehungen“ defi-
niert werden. Dem zugrundeliegend werden die beiden Technologiestacks aufgrund
architekturspezifischer Funktionalitäten bewertet. Dabei wird bewertet, welche
Funktionen existieren, um Enterprise-Anwendungen strukturiert und lose gekoppelt
zu entwickeln.


Lose Kopplung

Bei der Komplexität heutiger Anwendungen ist es von großer Bedeutung, Objekt-
netze flexibel aufzubauen. Dabei steht die lose Kopplung einzelner Komponenten
und einfache Konfiguration dieser im Vordergrund. Unteranderem soll dadurch die
Testbarkeit eines Systems verbessert werden.



                                                                               38
3.2 Evaluationskriterien


Es gilt zu untersuchen, welche Möglichkeiten und Funktionalitäten die Frameworks
für die lose Kopplung eines Anwendungssystems anbieten.


Cross Cutting Concerns

In Softwaresystemen gibt es so genannte Querschnittsbelange (engl. Cross Cutting
Concerns), die mit herkömmlicher objektorientierter Programmierung ohne Verlet-
zung des DRY-Prinzips nicht umsetzbar sind.2 Querschnittsbelange werden auch
orthogonale Belange genannt. Dies sind z.B. Funktionalitäten wie Tracing,3 Trans-
aktionssteuerung oder Exception Handling. Solche Funktionen sind in irgendeiner
Form in jeder Anwendungsschicht vorhanden. Sie befinden sich orthogonal zu den
Anwendungsschichten. So finden sich z.B. in vielen Methoden eines Anwendungs-
systems Programmzeilen, die für das Tracing verantwortlich sind. Dadurch wird
Code mit gleicher Funktionalität regelmäßig in den einzelnen Methoden dupliziert.
Dies widerspricht dem DRY-Prinzip. Dieses besagt „Don’t Repeat Yourself“ und
ist ein Grundprinzip guter Softwareentwicklunng.

Es wird untersucht, ob es Möglichkeiten gibt, diese Querschnittsbelange separat
vom Anwendungscode zu formulieren. Wenn dies nicht möglich ist, wird diskutiert,
welche anderen Arten der Implementierung existieren und wie gehaltvoll diese sind.




 2
     Vgl. [Wol10, S. 100 f.]
 3
     Tracing bezeichnet das detaillierte Loggen von Methoden. In den allermeisten Fällen wird dabei
      der Methodeneintritt mit den übergebenen Parameter sowie der Austritt geloggt.




                                                                                                39
4 Entwicklung der
     Beispielanwendung

4.1 Entwurf der Anwendung

Für den Vergleich des Scala/Lift Technologiestacks mit dem Java EE Programmier-
modell wird eine prototypische Raumverwaltungssoftware entwickelt. Der Nutzer
ist mit dieser Software in der Lage, Gebäude mit Räumen zu verwalten. Dabei gilt
die Vorgabe, dass für die Verwaltung der Gebäude und Räume so wenige Seiten
wie möglich aufzurufen sind. Bestenfalls existiert eine Seite pro Anwendungsfall.


4.1.1 Domänenmodell

Das Domänenmodell einer Anwendung beschreibt die fachlichen Entitäten einer
Problemlösung und die Beziehungen dieser untereinander. Bei der zu entwickeln-
den Raumverwaltungsanwendung besteht das Domänenmodell aus vier Entitäten:
Gebäuden, Räumen, Ausstattungen der Räume und Ausstattungsmerkmalen. Die
Abbildung 4.1 zeigt das Domänenmodell der Beispielanwendung. Zusätzlich existie-
ren Regeln für die zulässigen Werte einiger Attribute.

Sämtliche Bezeichnungen dürfen nicht leer sein. Das heißt, die Zeichenketten
müssen mindestens ein Zeichen enthalten und Null ist ebenfalls nicht als Wert
zulässig. Des Weiteren sind sämtliche Zahlen als positive ganze Zahlen abzubilden,
Primärschlüssel ausgeschlossen.




                                                                               40
4.1 Entwurf der Anwendung




Abb. 4.1: Domänenmodell der Beispielanwendung




                                                        41
4.1 Entwurf der Anwendung


4.1.2 Anwendungsfälle

Ein Anwendungsfall beschreibt ein mögliches Szenario für die Nutzung eines An-
wendungssystems. Die Beispielanwendung behandelt drei Anwendungsfälle: die
Verwaltung von Gebäuden, die Suche nach Räumen und das Verwalten von Aus-
stattungsmerkmalen.


Gebäude verwalten

Der Hauptanwendungsfall ist das Verwalten von Gebäuden. Dabei soll der Nutzer
neue Gebäude anlegen, Veränderungen an Gebäudedaten speichern und existierende
Gebäude löschen können. Dies gilt natürlich ebenfalls für die Räume der Gebäude
und Ausstattungen der Räume.


Räume suchen

Der Nutzer soll die Möglichkeit haben, nach Räumen mit einem bestimmten
Ausstattungsmerkmal zu suchen. Dabei kann der Benutzer die Wahl treffen zwischen
allen vorhandenen Ausstattungsmerkmalen.


Ausstattungsmerkmale verwalten

Ein Raum kann mehrere Raumaustattungen besitzen. Eine Raumaustattung ist
dabei die Zuordnung eines Ausstattungsmerkmals mit einer Menge zu einem Raum.
Diese Ausstattungsmerkmale soll der Nutzer ebenfalls verwalten können. Dabei
gilt die Vorgabe, dass Ausstattungsmerkmale nur gelöscht werden dürfen, wenn
diese bei keinem Raum in einer Raumausstattung verwendet werden. Andernfalls
würden bestehende Daten fehlerhaft. Das Hinzufügen und Verändern bestehender
Ausstattungsmerkmale soll ebenso möglich sein.




                                                                            42
4.2 Umsetzung mit Java EE


4.2 Umsetzung mit Java EE

Die Java EE Implementierung der Beispielanwendung setzt JSF 1.2 mit Facelets
als View-Technologie ein. Für die Persistenzschicht wird JPA 2.0 mit Hibernate als
JPA Provider verwendet.


4.2.1 Domänenmodell

Das Domänenmodell wird im Paket de.htw.berlin.jroomyweb.domain entwickelt.
Dabei wird für jede fachliche Entität eine Klasse implementiert. Ein Gebäude wird
also durch die Klasse Gebaeude repräsentiert, wie das folgende Listing zeigt.

§          Listing 4.1: JPA Grundgerüst der Java Gebäude Fachklasse                  ¤
@Entity
public c l a s s Gebaeude implements S e r i a l i z a b l e {


     @Id
     @GeneratedValue
     private Long i d ;


     protected Gebaeude ( ) {
           // f ü r JPA
     }


     public Long g e t I d ( ) {
           return i d ;
     }


     public void s e t I d ( Long i d ) {
           this . id = id ;
     }
}
¦                                                                                    ¥




                                                                                43
4.2 Umsetzung mit Java EE


Da die Objekte der Domänenschicht mittels JPA in einer relationalen Datenbank
persistiert werden, hat jede Fachklasse die Entity-Annotation. Diese Annotation
kennzeichnet für JPA eine Klasse, die auf eine Datenbank abzubilden ist. Weiterhin
fällt auf, dass Gebaeude das Interface Serializable implementiert. Das Serializable
Interface kennzeichnet Klassen, die serialisierbar sind. Damit ist das Abbilden eines
Objektes der Klasse auf einen Bytestrom oder anderes Übetragungsformat (z.B.
XML) gemeint. Für die reine Persistierung über JPA ist das nicht notwendig. Jedoch
ist es eine Best-Practice, im Java EE Kontext die JPA Fachklassen serialisierbar zu
machen. Sollte die Anwendung in einem verteilten System eingesetzt werden, kann
es vorkommen, dass Objekte der Domänenschicht zwischen verschiedenen Servern
hin- und hergeschickt werden. Dafür müssen die Objekte serialisiert werden. Das
Speichern von Domänenobjekten in der HTTP Session eines Nutzers kann ebenfalls
das Serialisieren für die Zwischenspeicherung auf der Festplatte des Application
Servers zur Folge haben.

Alle Domänenobjekte werden mit einer eindeutigen Identifikationsnummer gespei-
chert. Diese entspricht dem Primärschlüssel in der Datenbank. Daher hat die
Gebaeude Fachklasse ein id Attribut. Dieses ist mit einer Id-Annotation versehen,
die den Primärschlüssel der Objekte für die Abbildung in der Datenbank kennzeich-
net. Außerdem wird mit der GeneratedValue-Annotation festgelegt, dass der Wert
von id automatisch durch JPA generiert wird. In den meisten Konfigurationen be-
wirkt dies das Anlegen einer automatisch hochzählenden Datenbankspalte.1 Damit
ein JPA Provider auf das id Attribut von Gebaeude zugreifen kann, muss ein so
genanntes Getter-Setter-Methodenpaar implementiert werden. Diese Vorgabe der
Getter-Setter-Zugriffsmethoden gilt für alle Attribute, die durch JPA persistiert
werden.

Die Verwendung von JPA in der Gebaeude Klasse verlangt des Weiteren die Imple-
mentierung eines Konstruktors mit einer leeren Parameterliste. Das ist notwendig,
da ein JPA Provider Objekte von Gebaeude über die Java Reflections API erzeugt,
indem dieser leere Konstruktor aufgerufen wird, und die Gebaeude Objekte z.B.
anschließend über die Setter-Methoden mit den Daten aus der Datenbank befüllt.
 1
     Oftmals wird dafür der Terminus AUTO_INCREMENT verwenden.




                                                                                  44
4.2 Umsetzung mit Java EE


Da die Gebaeude Klasse einen Konstruktor mit einer nicht leeren Parameterliste hat,
der den Default-Konstruktor von Java überdeckt, musste dieser leere Konstruktor
zusätzlich fomuliert werden.2 Um zu verhindern, dass ein Gebaeude Objekt uner-
laubter Wise im Programmcode über diesen leeren Konstruktor erzeugt wird, hat
er die Sichtbarkeit protected und ist damit nur im Paket der Fachklassen sichtbar.
Alle Attribute von Gebaeude werden durch die Nutzung von JPA automatisch in
der Datenbank abgebildet.3 So auch die vier String-Attribute der Gebäude Entität
aus dem Domänenmodell, wie das folgende Listing zeigt. Nicht abgebildet, sind die
obligatorischen Getter- und Setter-Methoden.

§                    Listing 4.2: String Attribute der Gebäude Klasse                                ¤
@NotEmpty ( message=
         " Der Name e i n e s Gebäudes d a r f n i c h t l e e r s e i n . " )
private S t r i n g b e z e i c h n u n g ;


private S t r i n g s t r a s s e ;
private S t r i n g p l z ;
private S t r i n g o r t ;
¦                                                                                                    ¥

Das Domänenmodell verlangt, dass sämtliche Bezeichnungen nicht leer sein dürfen.
Daher wurde das Attribut bezeichnung mit NotEmpty annotiert. Die NotEm-
pty-Annotation ist eine Erweiterung des Bean Validation Standards und steht
durch die Nutzung der Hibernate Validator Bibliothek zur Verfügung. Durch die
Annotation wird festgelegt, dass bezeichnung weder den Wert Null noch eine Zei-
chenkette einer Länge kleiner 1 aufnehmen kann. Mit dem message Attribut der
NotEmpty-Annotation wird die Fehlernachricht angegeben, die bei Verletzung der
Validierungsregel ausgegeben wird.
Die Fehlernachrichten von Bean-Validation-Annotationen sind zusätzlich über
Ressourcendateien lokalisierbar. Dazu muss mindestens eine ValidationMessa-
ges.properties Datei im Klassenpfad abgelegt werden, die in Schlüssel-Wert-Paaren
    2
      Der Konstruktor mit der nicht leeren Parameterliste ist in dem Listing aus Gründen der
       Übersicht nicht dargestellt ist.
    3
      Sollen einzelne Attribute nicht persistiert werden, sind diese mit @Transient zu annotieren.




                                                                                               45
4.2 Umsetzung mit Java EE


Variablen und ihren Wert enthält. Mit dem Ausdruck {Variablenbezeichner} kann
ein Wert im message Attribut einer Bean-Validation-Annotation geladen werden.
Über Länder- und Sprachkürzel als Suffix des Dateinamen können einzelne Valida-
tionMessages_xx_XX.properties Dateien für bestimmte Sprachen definiert werden.
Das wurde im Prototypen jedoch nicht implementiert.

Die 1-n Beziehung zwischen Gebäuden und Räumen wird in der Gebaeude Klasse
durch ein Set implementiert. Ein Raum wird in der Java EE Lösung durch die
gleichnamige Klasse Raum repräsentiert.

§   Listing 4.3: Implementierung der Beziehung zwischen Räumen und Gebäuden            ¤
@OneToMany( c a s c a d e=CascadeType . ALL, mappedBy=" gebaeude " )
private Set<Raum> raeume = new HashSet<Raum>() ;
¦                                                                                      ¥

Durch das Annotieren des raeume Sets mit OneToMany wird die Art der Beziehung
definiert. Die zwei Attribute, cascade und mappedBy, konfigurieren diese Beziehung.
Über das cascade Attribut der OneToMany-Annotation werden kaskadierende
Operationen eingestellt. Das heißt, ist das umgebene Gebaeude Objekt durch
eine JPA Operation, wie z.B. das Speichern oder Löschen in der Datenbank,
betroffen, wird diese Operation auf alle Raum Objekte in raeume angewendet.
In diesem Fall werden durch die Angabe von CascadeType.ALL alle Operationen
kaskadierend auf das Set raeume angewendet. Das zweite Attribut, mappedBy,
betrifft die Abbildung der Beziehung in der Datenbank. Darüber wird definiert, dass
die Beziehung in der Datenbank durch die Spalte des gebaeude Attributs der Raum
Klasse abgebildet wird. Dies entspricht der Speicherung eines Fremdschlüssels in der
Raum Tabelle auf die ID Spalte der Gebäude Tabelle. Damit diese Konfiguration
über mappedBy funktioniert, wird das gebaeude Attribut der Raum Klasse mit
ManyToOne annotiert.

§           Listing 4.4: gebaeude Attribut in der Java Raum Fachklasse                 ¤
@ManyToOne( o p t i o n a l=f a l s e )
private Gebaeude gebaeude ;
¦                                                                                      ¥




                                                                                 46
4.2 Umsetzung mit Java EE


Das Setzen des optional Attributs auf den Wert false, bewirkt das Generieren eines
NotNull Constraints für die gebaeude Spalte in der Datenbank. Ein Raum kann
demnach nicht ohne ein dazugehöriges Gebäude existieren.
Neben der Beziehung zu einem Gebäude hat ein Raum mehrere Attribute, wie im
folgenden Listing exemplarisch anhand der Fensteranzahl gezeigt wird.

§                    Listing 4.5: Anzahl der Fenster eines Raumes                          ¤
@Min( v a l u e =1, message=
      " Die Anzahl d e r F e n s t e r kann n i c h t k l e i n e r 0 s e i n . " )
private int a n z a h l F e n s t e r ;
¦                                                                                          ¥

In der Beschreibung des Domänenmodells wurde festgelegt, dass sämtliche Zahlen
als positive Ganzzahlen abzubilden sind. Dies wird durch die Validierungsregel der
Min-Annotation umgesetzt. Durch das value Attribut wird der kleinste zulässige
Wert von anzahlFenster festgelegt. Die Min-Annotation ist eine Annotation des
Bean Validation Standards.
Wie bereits die 1-n Beziehung zwischen Gebäuden und Räumen wird auch die
Beziehung zwischen einem Raum und mehreren Raumausstattungen über ein
Set implementiert. Eine Raumausstattung wird durch die Klasse Ausstattung
implementiert.

§                Listing 4.6: Raumausstattungen in der Raum Klasse                         ¤
@OneToMany( c a s c a d e=CascadeType . ALL,
      f e t c h=FetchType .EAGER, mappedBy=" raum " )
private Set<Ausstattung > a u s s t a t t u n g e n =
                                          new HashSet<Ausstattung >() ;
¦                                                                                          ¥

Das fetch Attribut legt in diesem Fall fest, dass alle Raumausstattungen beim
Laden eines Raumes aus der Datenbank sofort mitgeladen werden. Andernfalls
geschieht dies verzögert (engl. lazy), was bei der Umsetzung des Prototypen zu
Ladefehlern geführt hat.
Die Implementierungen der Klassen Ausstattung und Merkmal, die das Ausstattungs-
merkmal des Domänenmodells repräsentiert, verwenden keine neuen Annotation



                                                                                      47
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell
Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell

Weitere ähnliche Inhalte

Was ist angesagt?

agorum core-benutzer-handbuch-6 4-0
agorum core-benutzer-handbuch-6 4-0agorum core-benutzer-handbuch-6 4-0
agorum core-benutzer-handbuch-6 4-0agorum Software GmbH
 
Visualisierung von Algorithmen und Datenstrukturen
Visualisierung von Algorithmen und DatenstrukturenVisualisierung von Algorithmen und Datenstrukturen
Visualisierung von Algorithmen und DatenstrukturenRoland Bruggmann
 
User-centered Design für Telemedizin-App
User-centered Design für Telemedizin-AppUser-centered Design für Telemedizin-App
User-centered Design für Telemedizin-AppRoland Bruggmann
 
Algorithmen und Applikationen zur interaktiven Visualisierung und Analyse ch...
Algorithmen und Applikationen zur interaktiven  Visualisierung und Analyse ch...Algorithmen und Applikationen zur interaktiven  Visualisierung und Analyse ch...
Algorithmen und Applikationen zur interaktiven Visualisierung und Analyse ch...Frank Oellien
 
Numerische Methoden: Approximation und Integration
Numerische Methoden: Approximation und IntegrationNumerische Methoden: Approximation und Integration
Numerische Methoden: Approximation und IntegrationRoland Bruggmann
 
Agiles Projektmanagement – Projektentwicklung mit Scrum, Kanb an & Co.
Agiles Projektmanagement – Projektentwicklung mit Scrum, Kanb an & Co.Agiles Projektmanagement – Projektentwicklung mit Scrum, Kanb an & Co.
Agiles Projektmanagement – Projektentwicklung mit Scrum, Kanb an & Co.TechDivision GmbH
 
Maven Definitive Guide De
Maven Definitive Guide DeMaven Definitive Guide De
Maven Definitive Guide Debouchri
 
Large Scale Multilayer Perceptron
Large Scale Multilayer PerceptronLarge Scale Multilayer Perceptron
Large Scale Multilayer PerceptronSascha Jonas
 
Praxisworkshop GIMP 2 - Die wichtigsten Werkzeuge
Praxisworkshop GIMP 2 - Die wichtigsten WerkzeugePraxisworkshop GIMP 2 - Die wichtigsten Werkzeuge
Praxisworkshop GIMP 2 - Die wichtigsten Werkzeugeguestadcc8ae
 
Masterarbeit / Fakultät für Mathematik und Informatik / Lehrgebiet Datenverar...
Masterarbeit / Fakultät für Mathematik und Informatik / Lehrgebiet Datenverar...Masterarbeit / Fakultät für Mathematik und Informatik / Lehrgebiet Datenverar...
Masterarbeit / Fakultät für Mathematik und Informatik / Lehrgebiet Datenverar...Melanie Eibl
 
Allgemeine betriebsdokumentation-kolab server22-20080103_1.0
Allgemeine betriebsdokumentation-kolab server22-20080103_1.0Allgemeine betriebsdokumentation-kolab server22-20080103_1.0
Allgemeine betriebsdokumentation-kolab server22-20080103_1.0Daniel Ward
 

Was ist angesagt? (14)

Da Hanno Rabe
Da Hanno RabeDa Hanno Rabe
Da Hanno Rabe
 
agorum core-benutzer-handbuch-6 4-0
agorum core-benutzer-handbuch-6 4-0agorum core-benutzer-handbuch-6 4-0
agorum core-benutzer-handbuch-6 4-0
 
Visualisierung von Algorithmen und Datenstrukturen
Visualisierung von Algorithmen und DatenstrukturenVisualisierung von Algorithmen und Datenstrukturen
Visualisierung von Algorithmen und Datenstrukturen
 
User-centered Design für Telemedizin-App
User-centered Design für Telemedizin-AppUser-centered Design für Telemedizin-App
User-centered Design für Telemedizin-App
 
Algorithmen und Applikationen zur interaktiven Visualisierung und Analyse ch...
Algorithmen und Applikationen zur interaktiven  Visualisierung und Analyse ch...Algorithmen und Applikationen zur interaktiven  Visualisierung und Analyse ch...
Algorithmen und Applikationen zur interaktiven Visualisierung und Analyse ch...
 
Numerische Methoden: Approximation und Integration
Numerische Methoden: Approximation und IntegrationNumerische Methoden: Approximation und Integration
Numerische Methoden: Approximation und Integration
 
Dsvdoc
DsvdocDsvdoc
Dsvdoc
 
Agiles Projektmanagement – Projektentwicklung mit Scrum, Kanb an & Co.
Agiles Projektmanagement – Projektentwicklung mit Scrum, Kanb an & Co.Agiles Projektmanagement – Projektentwicklung mit Scrum, Kanb an & Co.
Agiles Projektmanagement – Projektentwicklung mit Scrum, Kanb an & Co.
 
Mocek Thesis
Mocek ThesisMocek Thesis
Mocek Thesis
 
Maven Definitive Guide De
Maven Definitive Guide DeMaven Definitive Guide De
Maven Definitive Guide De
 
Large Scale Multilayer Perceptron
Large Scale Multilayer PerceptronLarge Scale Multilayer Perceptron
Large Scale Multilayer Perceptron
 
Praxisworkshop GIMP 2 - Die wichtigsten Werkzeuge
Praxisworkshop GIMP 2 - Die wichtigsten WerkzeugePraxisworkshop GIMP 2 - Die wichtigsten Werkzeuge
Praxisworkshop GIMP 2 - Die wichtigsten Werkzeuge
 
Masterarbeit / Fakultät für Mathematik und Informatik / Lehrgebiet Datenverar...
Masterarbeit / Fakultät für Mathematik und Informatik / Lehrgebiet Datenverar...Masterarbeit / Fakultät für Mathematik und Informatik / Lehrgebiet Datenverar...
Masterarbeit / Fakultät für Mathematik und Informatik / Lehrgebiet Datenverar...
 
Allgemeine betriebsdokumentation-kolab server22-20080103_1.0
Allgemeine betriebsdokumentation-kolab server22-20080103_1.0Allgemeine betriebsdokumentation-kolab server22-20080103_1.0
Allgemeine betriebsdokumentation-kolab server22-20080103_1.0
 

Andere mochten auch

Erforschung von Social Media - wissenschaftliche Erkenntnisse
Erforschung von Social Media - wissenschaftliche ErkenntnisseErforschung von Social Media - wissenschaftliche Erkenntnisse
Erforschung von Social Media - wissenschaftliche ErkenntnisseProf. Dr. Marco Hardiman
 
CRACKS DE LA HISTORIA DEL FUTBOL
CRACKS DE LA HISTORIA DEL FUTBOLCRACKS DE LA HISTORIA DEL FUTBOL
CRACKS DE LA HISTORIA DEL FUTBOLramirosarria
 
FMK2013: FileMaker und Kerio Connect by Bernhard Schulz - schubec GmbH und Ca...
FMK2013: FileMaker und Kerio Connect by Bernhard Schulz - schubec GmbH und Ca...FMK2013: FileMaker und Kerio Connect by Bernhard Schulz - schubec GmbH und Ca...
FMK2013: FileMaker und Kerio Connect by Bernhard Schulz - schubec GmbH und Ca...Verein FM Konferenz
 
Risikomanagement und Kreativität - Vergessen Sie Standardlösungen!
Risikomanagement und Kreativität - Vergessen Sie Standardlösungen!Risikomanagement und Kreativität - Vergessen Sie Standardlösungen!
Risikomanagement und Kreativität - Vergessen Sie Standardlösungen!Solid_Deutschland
 
Die raupe, die nicht fliegen wollte - The Caterpillar that Didn't Want to Fly
Die raupe, die nicht fliegen wollte - The Caterpillar that Didn't Want to FlyDie raupe, die nicht fliegen wollte - The Caterpillar that Didn't Want to Fly
Die raupe, die nicht fliegen wollte - The Caterpillar that Didn't Want to FlyFreekidstories
 
Social-Media-Frust: Die größten Probleme der Pressestellen im Social Web
Social-Media-Frust: Die größten Probleme der Pressestellen im Social WebSocial-Media-Frust: Die größten Probleme der Pressestellen im Social Web
Social-Media-Frust: Die größten Probleme der Pressestellen im Social WebFaktenkontor
 
Digital Happy Hour 06 12
Digital Happy Hour 06 12Digital Happy Hour 06 12
Digital Happy Hour 06 12Marcel Vogt
 
Jugendkriminalität in frankfurt
Jugendkriminalität in frankfurtJugendkriminalität in frankfurt
Jugendkriminalität in frankfurtNeshiino
 

Andere mochten auch (16)

Erfolg nach Rolf Berth
Erfolg nach Rolf BerthErfolg nach Rolf Berth
Erfolg nach Rolf Berth
 
Erforschung von Social Media - wissenschaftliche Erkenntnisse
Erforschung von Social Media - wissenschaftliche ErkenntnisseErforschung von Social Media - wissenschaftliche Erkenntnisse
Erforschung von Social Media - wissenschaftliche Erkenntnisse
 
CRACKS DE LA HISTORIA DEL FUTBOL
CRACKS DE LA HISTORIA DEL FUTBOLCRACKS DE LA HISTORIA DEL FUTBOL
CRACKS DE LA HISTORIA DEL FUTBOL
 
Die empirische Erfassung von Medienframes
Die empirische Erfassung von MedienframesDie empirische Erfassung von Medienframes
Die empirische Erfassung von Medienframes
 
FMK2013: FileMaker und Kerio Connect by Bernhard Schulz - schubec GmbH und Ca...
FMK2013: FileMaker und Kerio Connect by Bernhard Schulz - schubec GmbH und Ca...FMK2013: FileMaker und Kerio Connect by Bernhard Schulz - schubec GmbH und Ca...
FMK2013: FileMaker und Kerio Connect by Bernhard Schulz - schubec GmbH und Ca...
 
Risikomanagement und Kreativität - Vergessen Sie Standardlösungen!
Risikomanagement und Kreativität - Vergessen Sie Standardlösungen!Risikomanagement und Kreativität - Vergessen Sie Standardlösungen!
Risikomanagement und Kreativität - Vergessen Sie Standardlösungen!
 
V kegel
V kegelV kegel
V kegel
 
Die raupe, die nicht fliegen wollte - The Caterpillar that Didn't Want to Fly
Die raupe, die nicht fliegen wollte - The Caterpillar that Didn't Want to FlyDie raupe, die nicht fliegen wollte - The Caterpillar that Didn't Want to Fly
Die raupe, die nicht fliegen wollte - The Caterpillar that Didn't Want to Fly
 
10 gebote
10 gebote10 gebote
10 gebote
 
FORUM SERVICE & INSTANDHALTUNG
FORUM SERVICE & INSTANDHALTUNG FORUM SERVICE & INSTANDHALTUNG
FORUM SERVICE & INSTANDHALTUNG
 
Social-Media-Frust: Die größten Probleme der Pressestellen im Social Web
Social-Media-Frust: Die größten Probleme der Pressestellen im Social WebSocial-Media-Frust: Die größten Probleme der Pressestellen im Social Web
Social-Media-Frust: Die größten Probleme der Pressestellen im Social Web
 
Saber 9
Saber 9Saber 9
Saber 9
 
Digital Happy Hour 06 12
Digital Happy Hour 06 12Digital Happy Hour 06 12
Digital Happy Hour 06 12
 
Jugendkriminalität in frankfurt
Jugendkriminalität in frankfurtJugendkriminalität in frankfurt
Jugendkriminalität in frankfurt
 
Gott ist - God is
Gott ist - God isGott ist - God is
Gott ist - God is
 
Unternehmensfolder dankl+partner consulting gmbh
Unternehmensfolder dankl+partner consulting gmbhUnternehmensfolder dankl+partner consulting gmbh
Unternehmensfolder dankl+partner consulting gmbh
 

Ähnlich wie Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell

Bachelorarbeit paul gerber.pdf
Bachelorarbeit paul gerber.pdfBachelorarbeit paul gerber.pdf
Bachelorarbeit paul gerber.pdfwissem hammouda
 
Master thesis pascal_mueller01
Master thesis pascal_mueller01Master thesis pascal_mueller01
Master thesis pascal_mueller01guest39ce4e
 
Sappres Netweaver Identity Management
Sappres Netweaver Identity ManagementSappres Netweaver Identity Management
Sappres Netweaver Identity Managementgueste2a899
 
Entwicklung eines Frameworks zum automatisierten Handel eines Multi-Broker-PA...
Entwicklung eines Frameworks zum automatisierten Handel eines Multi-Broker-PA...Entwicklung eines Frameworks zum automatisierten Handel eines Multi-Broker-PA...
Entwicklung eines Frameworks zum automatisierten Handel eines Multi-Broker-PA...Sascha Jonas
 
Team Oldenburger Robo-Fußball – Abschlussbericht der Projektgruppe 2010
Team Oldenburger Robo-Fußball – Abschlussbericht  der Projektgruppe  2010Team Oldenburger Robo-Fußball – Abschlussbericht  der Projektgruppe  2010
Team Oldenburger Robo-Fußball – Abschlussbericht der Projektgruppe 2010Johannes Diemke
 
Bachelor%20thesis%20Willi%20Tscheschner
Bachelor%20thesis%20Willi%20TscheschnerBachelor%20thesis%20Willi%20Tscheschner
Bachelor%20thesis%20Willi%20Tscheschnertutorialsruby
 
Bachelor%20thesis%20Willi%20Tscheschner
Bachelor%20thesis%20Willi%20TscheschnerBachelor%20thesis%20Willi%20Tscheschner
Bachelor%20thesis%20Willi%20Tscheschnertutorialsruby
 
Handbuch de
Handbuch deHandbuch de
Handbuch degordem
 
Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista
Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista
Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista Johannes Hohenbichler
 
Mhb info bsc_ws1011_de_lang
Mhb info bsc_ws1011_de_langMhb info bsc_ws1011_de_lang
Mhb info bsc_ws1011_de_langGodlyEngi
 
Web-Entwicklung mit Spring, Hibernate und Facelets in Eclipse
Web-Entwicklung mit Spring, Hibernate und Facelets in EclipseWeb-Entwicklung mit Spring, Hibernate und Facelets in Eclipse
Web-Entwicklung mit Spring, Hibernate und Facelets in EclipseSarah Steffen
 
Sdv 0405 design-pattern_thc_jps_skript
Sdv 0405 design-pattern_thc_jps_skriptSdv 0405 design-pattern_thc_jps_skript
Sdv 0405 design-pattern_thc_jps_skriptTomasz Waszczyk
 

Ähnlich wie Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell (20)

Bachelorarbeit paul gerber.pdf
Bachelorarbeit paul gerber.pdfBachelorarbeit paul gerber.pdf
Bachelorarbeit paul gerber.pdf
 
Dsvdoc
DsvdocDsvdoc
Dsvdoc
 
Dsvdoc
DsvdocDsvdoc
Dsvdoc
 
Dsvdoc
DsvdocDsvdoc
Dsvdoc
 
Dsvdoc
DsvdocDsvdoc
Dsvdoc
 
Dsvdoc
DsvdocDsvdoc
Dsvdoc
 
Dsvdoc
DsvdocDsvdoc
Dsvdoc
 
Dsvdoc
DsvdocDsvdoc
Dsvdoc
 
Master thesis pascal_mueller01
Master thesis pascal_mueller01Master thesis pascal_mueller01
Master thesis pascal_mueller01
 
Sappres Netweaver Identity Management
Sappres Netweaver Identity ManagementSappres Netweaver Identity Management
Sappres Netweaver Identity Management
 
Entwicklung eines Frameworks zum automatisierten Handel eines Multi-Broker-PA...
Entwicklung eines Frameworks zum automatisierten Handel eines Multi-Broker-PA...Entwicklung eines Frameworks zum automatisierten Handel eines Multi-Broker-PA...
Entwicklung eines Frameworks zum automatisierten Handel eines Multi-Broker-PA...
 
Team Oldenburger Robo-Fußball – Abschlussbericht der Projektgruppe 2010
Team Oldenburger Robo-Fußball – Abschlussbericht  der Projektgruppe  2010Team Oldenburger Robo-Fußball – Abschlussbericht  der Projektgruppe  2010
Team Oldenburger Robo-Fußball – Abschlussbericht der Projektgruppe 2010
 
Bachelor%20thesis%20Willi%20Tscheschner
Bachelor%20thesis%20Willi%20TscheschnerBachelor%20thesis%20Willi%20Tscheschner
Bachelor%20thesis%20Willi%20Tscheschner
 
Bachelor%20thesis%20Willi%20Tscheschner
Bachelor%20thesis%20Willi%20TscheschnerBachelor%20thesis%20Willi%20Tscheschner
Bachelor%20thesis%20Willi%20Tscheschner
 
Handbuch de
Handbuch deHandbuch de
Handbuch de
 
Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista
Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista
Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista
 
Mhb info bsc_ws1011_de_lang
Mhb info bsc_ws1011_de_langMhb info bsc_ws1011_de_lang
Mhb info bsc_ws1011_de_lang
 
Web-Entwicklung mit Spring, Hibernate und Facelets in Eclipse
Web-Entwicklung mit Spring, Hibernate und Facelets in EclipseWeb-Entwicklung mit Spring, Hibernate und Facelets in Eclipse
Web-Entwicklung mit Spring, Hibernate und Facelets in Eclipse
 
Msrbas
MsrbasMsrbas
Msrbas
 
Sdv 0405 design-pattern_thc_jps_skript
Sdv 0405 design-pattern_thc_jps_skriptSdv 0405 design-pattern_thc_jps_skript
Sdv 0405 design-pattern_thc_jps_skript
 

Mehr von adesso AG

SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP (Kurzversion)
SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP (Kurzversion)SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP (Kurzversion)
SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP (Kurzversion)adesso AG
 
SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP
SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMPSNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP
SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMPadesso AG
 
Mythos High Performance Teams
Mythos High Performance TeamsMythos High Performance Teams
Mythos High Performance Teamsadesso AG
 
A Business-Critical SharePoint Solution From adesso AG
A Business-CriticalSharePoint SolutionFrom adesso AGA Business-CriticalSharePoint SolutionFrom adesso AG
A Business-Critical SharePoint Solution From adesso AGadesso AG
 
Was Sie über NoSQL Datenbanken wissen sollten!
Was Sie über NoSQL Datenbanken wissen sollten!Was Sie über NoSQL Datenbanken wissen sollten!
Was Sie über NoSQL Datenbanken wissen sollten!adesso AG
 
Continuous Delivery praktisch
Continuous Delivery praktischContinuous Delivery praktisch
Continuous Delivery praktischadesso AG
 
Agilität, Snapshots und Continuous Delivery
Agilität, Snapshots und Continuous DeliveryAgilität, Snapshots und Continuous Delivery
Agilität, Snapshots und Continuous Deliveryadesso AG
 
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?adesso AG
 
Getriebene Anwendungslandschaften
Getriebene AnwendungslandschaftenGetriebene Anwendungslandschaften
Getriebene Anwendungslandschaftenadesso AG
 
Google App Engine JAX PaaS Parade 2013
Google App Engine JAX PaaS Parade 2013Google App Engine JAX PaaS Parade 2013
Google App Engine JAX PaaS Parade 2013adesso AG
 
Wartbare Web-Anwendungen mit Knockout.js und Model-View-ViewModel (MVVM)
Wartbare Web-Anwendungen mit Knockout.js und Model-View-ViewModel (MVVM)Wartbare Web-Anwendungen mit Knockout.js und Model-View-ViewModel (MVVM)
Wartbare Web-Anwendungen mit Knockout.js und Model-View-ViewModel (MVVM)adesso AG
 
OOP 2013 NoSQL Suche
OOP 2013 NoSQL SucheOOP 2013 NoSQL Suche
OOP 2013 NoSQL Sucheadesso AG
 
NoSQL in der Cloud - Why?
NoSQL in der Cloud -  Why?NoSQL in der Cloud -  Why?
NoSQL in der Cloud - Why?adesso AG
 
Lean web architecture mit jsf 2.0, cdi & co.
Lean web architecture mit jsf 2.0, cdi & co.Lean web architecture mit jsf 2.0, cdi & co.
Lean web architecture mit jsf 2.0, cdi & co.adesso AG
 
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDISchlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDIadesso AG
 
Zehn Hinweise für Architekten
Zehn Hinweise für ArchitektenZehn Hinweise für Architekten
Zehn Hinweise für Architektenadesso AG
 
Agile Praktiken
Agile PraktikenAgile Praktiken
Agile Praktikenadesso AG
 
Java und Cloud - nicht nur mit PaaS
Java und Cloud - nicht nur mit PaaS Java und Cloud - nicht nur mit PaaS
Java und Cloud - nicht nur mit PaaS adesso AG
 
Neue EBusiness Perspektiven durch HTML5
Neue EBusiness Perspektiven durch HTML5Neue EBusiness Perspektiven durch HTML5
Neue EBusiness Perspektiven durch HTML5adesso AG
 
CloudConf2011 Introduction to Google App Engine
CloudConf2011 Introduction to Google App EngineCloudConf2011 Introduction to Google App Engine
CloudConf2011 Introduction to Google App Engineadesso AG
 

Mehr von adesso AG (20)

SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP (Kurzversion)
SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP (Kurzversion)SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP (Kurzversion)
SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP (Kurzversion)
 
SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP
SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMPSNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP
SNMP Applied - Sicheres Anwendungs-Monitoring mit SNMP
 
Mythos High Performance Teams
Mythos High Performance TeamsMythos High Performance Teams
Mythos High Performance Teams
 
A Business-Critical SharePoint Solution From adesso AG
A Business-CriticalSharePoint SolutionFrom adesso AGA Business-CriticalSharePoint SolutionFrom adesso AG
A Business-Critical SharePoint Solution From adesso AG
 
Was Sie über NoSQL Datenbanken wissen sollten!
Was Sie über NoSQL Datenbanken wissen sollten!Was Sie über NoSQL Datenbanken wissen sollten!
Was Sie über NoSQL Datenbanken wissen sollten!
 
Continuous Delivery praktisch
Continuous Delivery praktischContinuous Delivery praktisch
Continuous Delivery praktisch
 
Agilität, Snapshots und Continuous Delivery
Agilität, Snapshots und Continuous DeliveryAgilität, Snapshots und Continuous Delivery
Agilität, Snapshots und Continuous Delivery
 
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
 
Getriebene Anwendungslandschaften
Getriebene AnwendungslandschaftenGetriebene Anwendungslandschaften
Getriebene Anwendungslandschaften
 
Google App Engine JAX PaaS Parade 2013
Google App Engine JAX PaaS Parade 2013Google App Engine JAX PaaS Parade 2013
Google App Engine JAX PaaS Parade 2013
 
Wartbare Web-Anwendungen mit Knockout.js und Model-View-ViewModel (MVVM)
Wartbare Web-Anwendungen mit Knockout.js und Model-View-ViewModel (MVVM)Wartbare Web-Anwendungen mit Knockout.js und Model-View-ViewModel (MVVM)
Wartbare Web-Anwendungen mit Knockout.js und Model-View-ViewModel (MVVM)
 
OOP 2013 NoSQL Suche
OOP 2013 NoSQL SucheOOP 2013 NoSQL Suche
OOP 2013 NoSQL Suche
 
NoSQL in der Cloud - Why?
NoSQL in der Cloud -  Why?NoSQL in der Cloud -  Why?
NoSQL in der Cloud - Why?
 
Lean web architecture mit jsf 2.0, cdi & co.
Lean web architecture mit jsf 2.0, cdi & co.Lean web architecture mit jsf 2.0, cdi & co.
Lean web architecture mit jsf 2.0, cdi & co.
 
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDISchlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
 
Zehn Hinweise für Architekten
Zehn Hinweise für ArchitektenZehn Hinweise für Architekten
Zehn Hinweise für Architekten
 
Agile Praktiken
Agile PraktikenAgile Praktiken
Agile Praktiken
 
Java und Cloud - nicht nur mit PaaS
Java und Cloud - nicht nur mit PaaS Java und Cloud - nicht nur mit PaaS
Java und Cloud - nicht nur mit PaaS
 
Neue EBusiness Perspektiven durch HTML5
Neue EBusiness Perspektiven durch HTML5Neue EBusiness Perspektiven durch HTML5
Neue EBusiness Perspektiven durch HTML5
 
CloudConf2011 Introduction to Google App Engine
CloudConf2011 Introduction to Google App EngineCloudConf2011 Introduction to Google App Engine
CloudConf2011 Introduction to Google App Engine
 

Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell

  • 1. Bachelorthesis zur Erlangung des akademischen Grades Bachelor of Science in Wirtschaftsinformatik Vergleich des Scala Web-Frameworks Lift mit dem Java EE Programmiermodell Bachelorthesis im Fachbereich Wirtschaftswissenschaften II im Studiengang Wirtschaftsinformatik der Hochschule für Technik und Wirtschaft Berlin in Zusammenarbeit mit der adesso AG vorgelegt von: Felix Müller Matrikelnummer: 524063 eingereicht am: 9. Juni 2011 Erstbetreuer: Prof. Dr. Ingo Claßen Zweitbetreuer: Prof. Dr. Harald Brandenburg Betrieblicher Betreuer: Eberhard Wolff
  • 2. Inhaltsverzeichnis Abbildungsverzeichnis III Listingsverzeichnis IV Abkürzungsverzeichnis VIII 1 Einleitung 1 1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Zielsetzung der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.3 Abgrenzung zu anderen Arbeiten . . . . . . . . . . . . . . . . . . . 2 1.4 Aufbau der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 Grundlagen 4 2.1 Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.2 Java EE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2.1 Java Persistence API . . . . . . . . . . . . . . . . . . . . . . 7 2.2.2 Bean Validation . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.2.3 Dependency Injection for Java . . . . . . . . . . . . . . . . . 10 2.2.4 JavaServer Faces . . . . . . . . . . . . . . . . . . . . . . . . 11 2.3 Programmiersprache Scala . . . . . . . . . . . . . . . . . . . . . . . 16 2.3.1 Klassen und Objekte . . . . . . . . . . . . . . . . . . . . . . 17 2.3.2 Traits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.3.3 Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.3.4 Pattern Matching . . . . . . . . . . . . . . . . . . . . . . . . 26 2.3.5 Self-Type Annotationen . . . . . . . . . . . . . . . . . . . . 27 I
  • 3. Inhaltsverzeichnis 2.3.6 Implicit Conversions . . . . . . . . . . . . . . . . . . . . . . 29 2.4 Lift Web-Framework . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3 Methodik der Evaluation 34 3.1 Beschreibung der Evaluation . . . . . . . . . . . . . . . . . . . . . . 34 3.2 Evaluationskriterien . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3.2.1 Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3.2.2 Funktionalität . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.2.3 Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 4 Entwicklung der Beispielanwendung 40 4.1 Entwurf der Anwendung . . . . . . . . . . . . . . . . . . . . . . . . 40 4.1.1 Domänenmodell . . . . . . . . . . . . . . . . . . . . . . . . . 40 4.1.2 Anwendungsfälle . . . . . . . . . . . . . . . . . . . . . . . . 42 4.2 Umsetzung mit Java EE . . . . . . . . . . . . . . . . . . . . . . . . 43 4.2.1 Domänenmodell . . . . . . . . . . . . . . . . . . . . . . . . . 43 4.2.2 Anwendungsfälle . . . . . . . . . . . . . . . . . . . . . . . . 48 4.3 Umsetzung mit Scala und Lift . . . . . . . . . . . . . . . . . . . . . 68 4.3.1 Domänenmodell . . . . . . . . . . . . . . . . . . . . . . . . . 68 4.3.2 Anwendungsfälle . . . . . . . . . . . . . . . . . . . . . . . . 77 5 Durchführung der Evaluation 99 5.1 Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 5.2 Funktionalität . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 5.3 Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 6 Fazit 122 6.1 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 6.2 Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Literaturverzeichnis IX A Inhalt der CD XII II
  • 4. Abbildungsverzeichnis 2.1 Prozessfluss des Ajax Modells von [Wik] . . . . . . . . . . . . . . . 5 2.2 Lebenszyklus einer Persistent Entity aus [Obj] . . . . . . . . . . . . 8 2.3 MVC-Architektur von JSF aus [MM10] . . . . . . . . . . . . . . . . 12 2.4 JSF Standard Request-Response-Zyklus aus [EJ10] . . . . . . . . . 13 2.5 Kontrollfluss im View-First-Ansatz von Lift aus [Per11] . . . . . . . 31 2.6 Architektur von Lift aus [DCB11] . . . . . . . . . . . . . . . . . . . 32 4.1 Domänenmodell der Beispielanwendung . . . . . . . . . . . . . . . . 41 III
  • 5. Listingsverzeichnis 2.1 Eintragung des Faces-Servlet in der web.xml . . . . . . . . . . . . . 14 2.2 Einbinden der Namensräume der beiden Standard-Tag-Libraries . . 16 2.3 Einfache Scala Klasse . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.4 Klasse mit dazugehörigem Companion Objekt . . . . . . . . . . . . 19 2.5 Beispiel der Nutzung von Traits . . . . . . . . . . . . . . . . . . . . 20 2.6 Beispiel einer einfachen Funktion . . . . . . . . . . . . . . . . . . . 22 2.7 Beispiel der Zuweisung eines Funktionswertes . . . . . . . . . . . . 22 2.8 Anwendung einer Funktion höherer Ordnung . . . . . . . . . . . . . 22 2.9 Vollständig ausgeschriebener Aufruf von map . . . . . . . . . . . . . 23 2.10 Aufruf der map Funktion mit einem Platzhalter . . . . . . . . . . . 23 2.11 Beispiel einer Funktion mit mehreren Parameterlisten . . . . . . . . 24 2.12 Abbildung der sub Funktion auf mehrere Funktionen . . . . . . . . 24 2.13 Beispiel einer partiell angewandten Funktion . . . . . . . . . . . . . 25 2.14 Kontrollstruktur-ähnliche Konstrukte mit subTwoWith . . . . . . . 25 2.15 Bespiel von Pattern Matching in printInt . . . . . . . . . . . . . . . 26 2.16 Pattern Matching in Form einer partiellen Funktion . . . . . . . . . 27 2.17 Beispiel einer Self-Type Annotation . . . . . . . . . . . . . . . . . . 28 2.18 Beispiel einer Implicit Conversion . . . . . . . . . . . . . . . . . . . 29 4.1 JPA Grundgerüst der Java Gebäude Fachklasse . . . . . . . . . . . 43 4.2 String Attribute der Gebäude Klasse . . . . . . . . . . . . . . . . . 45 4.3 Implementierung der Beziehung zwischen Räumen und Gebäuden . 46 4.4 gebaeude Attribut in der Java Raum Fachklasse . . . . . . . . . . . 46 4.5 Anzahl der Fenster eines Raumes . . . . . . . . . . . . . . . . . . . 47 IV
  • 6. Listingsverzeichnis 4.6 Raumausstattungen in der Raum Klasse . . . . . . . . . . . . . . . 47 4.7 Dao Interface für den Datenbankzugriff . . . . . . . . . . . . . . . . 48 4.8 Spezifisches Dao Interface für die Raum Klasse . . . . . . . . . . . . 49 4.9 EntityManager und findById Methode des AbstractJpaDao . . . . . 49 4.10 configure Methode des PersistenceModule . . . . . . . . . . . . . . 50 4.11 Erzeugung und Konfiguration des PersistenceModules . . . . . . . . 51 4.12 warp-persist Servlet Filter Eintrag in der web.xml . . . . . . . . . . 51 4.13 Bindung der DAO Interfaces an ihre Implementierungen . . . . . . 52 4.14 Ablegen des Injectors im ServletContext . . . . . . . . . . . . . . . 53 4.15 Injection durch Guice in AbstractController . . . . . . . . . . . . . 53 4.16 XHTML Grundgerüst in layout.xhtml . . . . . . . . . . . . . . . . . 55 4.17 Auszug aus messages Datei für das de Länderkürzel . . . . . . . . . 56 4.18 Anzeige aller Gebäude in gebaeude.xhtml . . . . . . . . . . . . . . . 56 4.19 GebaeudeTableModel Eintrag in faces-config.xml . . . . . . . . . . . 57 4.20 TableModel Interface für die Abbildung von Tabellen . . . . . . . . 58 4.21 Laden aller Gebäude im GebaeudeTableController . . . . . . . . . . 59 4.22 Ajax Support zum Nachladen des ausgewählten Gebäudes . . . . . 59 4.23 GebaeudeTableSelectionHandler Eintrag in faces-config.xml . . . . . 60 4.24 Ereignisbehandlung in onSelectionChange . . . . . . . . . . . . . . 61 4.25 Anzeige der Bezeichnung des ausgewählten Gebäudes . . . . . . . . 62 4.26 Button Tag zum Speichern eines Gebäudes in gebaeude.xml . . . . 63 4.27 GebaeudeTableService Eintrag in faces-config.xml . . . . . . . . . . 63 4.28 Speichern des selektierten Gebäudes in AbstractTableController . . 64 4.29 Auszug des Tags für die Anzeige der Suchergebnisse . . . . . . . . . 65 4.30 Tag für den Suchbutton . . . . . . . . . . . . . . . . . . . . . . . . 66 4.31 Suchlogik in sucheRaeume Methode . . . . . . . . . . . . . . . . . . 66 4.32 Finder Methode für die Raumsuche . . . . . . . . . . . . . . . . . . 66 4.33 Auszug des Tags für das Löschen von Ausstattungsmerkmalen . . . 67 4.34 Abfragelogik, ob ein Ausstattungsmerkmal löschbar ist . . . . . . . 68 4.35 Finder Annotation von getAusstattungenByMerkmal . . . . . . . . 68 4.36 Deklaration der Scala/Lift Gebäude Fachklasse . . . . . . . . . . . 69 V
  • 7. Listingsverzeichnis 4.37 Attribute der Building Klasse . . . . . . . . . . . . . . . . . . . . . 70 4.38 name Attribut der Building Klasse . . . . . . . . . . . . . . . . . . 70 4.39 Generische Signatur einer Mapper Validierungsfunktion . . . . . . . 71 4.40 Signatur von valMinLen . . . . . . . . . . . . . . . . . . . . . . . . 71 4.41 rooms Objekt der Building Klasse . . . . . . . . . . . . . . . . . . . 72 4.42 Überschriebene Löschfunktion der Building Klasse . . . . . . . . . . 73 4.43 Companion Objekt der Building Klasse . . . . . . . . . . . . . . . . 73 4.44 Rückgabe des Companion Objekts in getSingleton . . . . . . . . . . 74 4.45 Deklaration der Scala/Lift Raum Fachklasse . . . . . . . . . . . . . 74 4.46 Abbildung der Referenz auf ein Gebäude in Room . . . . . . . . . . 75 4.47 Anzahl der Fenster in der Scala/Lift Room Klasse . . . . . . . . . . 75 4.48 Erweiterter Validator für Ganzzahlen vom Typ Integer . . . . . . . 75 4.49 Raumausstattungen in der Room Klasse . . . . . . . . . . . . . . . 76 4.50 isDeletable Funktion der Attribute Klasse . . . . . . . . . . . . . . 77 4.51 Datenbankabfrage in der findByAttribute Funktion . . . . . . . . . 77 4.52 Verbindungseinstellungen für die Datenbank . . . . . . . . . . . . . 78 4.53 Datenbanksetup der Lift Anwendung . . . . . . . . . . . . . . . . . 79 4.54 Initialisieren der Datenbank . . . . . . . . . . . . . . . . . . . . . . 80 4.55 Snippet Konfiguration und Aufbau der SiteMap . . . . . . . . . . . 80 4.56 Ressourceneinträge für die Sitemap . . . . . . . . . . . . . . . . . . 81 4.57 Lift Servlet Filter Eintrag in web.xml . . . . . . . . . . . . . . . . . 81 4.58 Ausschnitt des allgemeinen Templates in default.html . . . . . . . . 83 4.59 Ausschnitt der Tabelle zum Anzeigen von Gebäuden . . . . . . . . . 84 4.60 Aufbau einer Tabelle im BaseTableSnippet . . . . . . . . . . . . . . 85 4.61 Generierung einer Tabellenzeile zur Anzeige eines Gebäudes . . . . 86 4.62 Erzeugung von selektierbaren Tabellenzeilen in SelectableTableRows 88 4.63 Ereignisbehandlung in Buildings für einen Klick auf eine Tabellenzeile 90 4.64 Speichern des ausgewählten Gebäudes in der Session . . . . . . . . 90 4.65 Anzeige der Gebäudesbezeichnung und des Speichern Buttons . . . 91 4.66 Validierung der Eingaben für ein Gebäude . . . . . . . . . . . . . . 92 4.67 Anzeige von Fehlern durch Lift . . . . . . . . . . . . . . . . . . . . 93 VI
  • 8. Listingsverzeichnis 4.68 Speichern des ausgewählten Gebäudes . . . . . . . . . . . . . . . . . 94 4.69 Snippet-Funktionen für den Such-Button . . . . . . . . . . . . . . . 95 4.70 Snippet-Funktion für die Ausgabe der Suchergebnisse . . . . . . . . 96 4.71 Finder-Funktion für die Suche nach Räumen . . . . . . . . . . . . . 96 4.72 Tags für die Buttons zum Verwalten von Ausstattungsmerkmalen . 97 4.73 Bedingtes Rendern des Lösch-Button . . . . . . . . . . . . . . . . . 98 5.1 Exemplarische Gebäude Fachklasse mit CouchDB Anbindung . . . . 107 5.2 Injector Trait von Lift für Dependency Injection . . . . . . . . . . . 114 5.3 Deklaration der registerInjection Funktion . . . . . . . . . . . . . . 115 5.4 Lift Dependency Injection Beispiel . . . . . . . . . . . . . . . . . . 116 5.5 Dekoration mit withTransaction . . . . . . . . . . . . . . . . . . . . 118 5.6 Service Trait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 5.7 Mögliche Dynamic Proxy Integration in Scala . . . . . . . . . . . . 120 VII
  • 9. Abkürzungsverzeichnis AOP Aspektorientierte Programmierung API Application Programming Interface CRUD Create, Read, Update, Delete DAO Data Access Object DI Dependency Injection DSL Domain Specific Language HTML HyperText Markup Language IDE Integrated Development Environment JCP Java Community Process JSON JavaScript Object Notation JSR Java Specification Request XHTML eXtensible HyperText Markup Language XML Extensible Markup Language VIII
  • 10. 1 Einleitung 1.1 Motivation Das Entwickeln von Anwendungen für das World Wide Web gewinnt stetig an Bedeutung. Bereits heutzutage verdrängen Web-Anwendungen (z.B. Google Docs) einzelne Desktop-Anwendungen. Auf mobilen Geräten sind Web-Anwendungen bereits eine wirkliche Konkurrenz zu den nativen Applikationen. Daher ist es interessant und wichtig, Frameworks, die das Entwickeln von Web-Anwendungen erleichtern und verallgemeinern, auf die tatsächliche Einsatztauglichkeit zu prüfen und zu testen. Auf der Hauptseite des Lift Web-Frameworks wird Lift als das derzeit mächtigs- te Framework für die Entwicklung von Web-Anwendungen bezeichnet.1 Mit der Programmiersprache Scala setzt Lift zudem eine neue Sprache für die JVM ein und zeigt damit gleichzeitig den Einsatz dieser neuen Sprache in einem größeren Projekt. Aufgrunddessen wird das Lift Web-Framework in dieser Arbeit mit dem etablierten Java EE Programmiermodell verglichen. 1.2 Zielsetzung der Arbeit Ziel der Arbeit ist es, durch den Vergleich des Lift Web-Frameworks mit dem Java EE Programmiermodell Antworten auf mehrere Fragestellungen zu erhalten, die folgend zusammengefasst dargelegt werden. 1 siehe http://liftweb.net 1
  • 11. 1.3 Abgrenzung zu anderen Arbeiten Lift soll aus möglichst vielen Blickwinkeln betrachtet werden, damit zum Ende der Arbeit die Vor- und Nachteile des Frameworks herausgearbeitet sind. Es gilt außerdem zu untersuchen, was die besten Einsatzbereiche des Lift Frameworks sind. Das Hauptziel ist dabei, Lift im Vergleich zum Java EE Programmiermodell zu bewerten, da dieses einen der am häufigsten eingesetzten Standards in der Web-Entwicklung darstellt. Außerdem setzt Lift auf die Java EE Plattform auf, wie später noch erklärt wird, und tritt damit in mögliche Konkurrenz zum Java EE Programmiermodell. 1.3 Abgrenzung zu anderen Arbeiten Anders als in bisherigen Arbeiten wird Scala in dieser Arbeit nicht auf die Integration mit bestehenden Java Anwendungen geprüft ([Kal10]) oder die Entwicklung einer Web-Anwendung mit Scala und Lift ([TF11]) gezeigt. Im Mittelpunkt dieser Arbeit steht der Vergleich von Scala und Lift als Technologiestack mit dem Java EE Programmiermodell. Natürlich wurde dafür eine Beispielanwendung jeweils mit Scala/Lift und Java EE entwickelt, was auch entsprechend ausführlich erläutert wird. Ebenso wird an einigen Stellen kurz die Integration mit Java angesprochen. Aber dies geschieht dann zwecks des Vergleichs und der Bewertung. 1.4 Aufbau der Arbeit Zu Beginn der Arbeit werden die Grundlagen der verwendeten Konzepte und eingesetzten Technologien erklärt. Dabei erfolgt eine Einführung in die Program- miersprache Scala. Allerdings kann keine vollständige Sprachdefinition gegeben werden. Alle Sprachmittel, die zum Verständnis der Arbeit nötig sind, werden gezeigt und erläutert. Außerdem wird davon ausgegangen, dass der Leser dieser Arbeit bereits mit der Sprache Java entwickelt, sodass eine Einführung in die eingesetzten Java EE Techniken für das Verständnis ausreicht. 2
  • 12. 1.4 Aufbau der Arbeit Danach wird die Methodik der Evaluation beschrieben. Dabei werden die ver- wendeten Methoden erläutert und die Evaluationskriterien vorgestellt. Da für den Vergleich der beiden Technologiestacks jeweils eine Beispielanwendung ent- wickelt wurde, folgt im Kapitel 4 die Darstellung der Entwicklung. Dabei wird die Umsetzung der Prototypen anhand von Programmcodeauszügen erläutert. An- schließend wird die Evaluation durchgeführt. Dafür werden die zuvor festgelegten Evaluationskriterien verwendet. Zum Abschluss wird das Ergebnis der Arbeit im Fazit zusammengefasst und ein Ausblick gegeben, indem weitere untersuchenswerte Themen benannt werden, die durch die Arbeit entstanden sind. Die entwickelten Beispielanwendungen liegen dieser Arbeit auf einer CD bei, deren Inhalt im Anhang kurz beschrieben wird. 3
  • 13. 2 Grundlagen 2.1 Ajax Die Begrifflichkeit Ajax ist heutzutage ein gängiges Schlagwort bei der Entwicklung von Web-Anwendungen. Damit wird ein Konzept bezeichnet, dass unter Verwendung gängiger Technologien die asynchrone Übertragung von Daten zwischen Server und Client, meistens dem Browser, ermöglicht. Ajax steht dabei für „Asynchronous JavaScript and XML“.1 Web-Anwendungen, in denen Ajax eingesetzt wird, verhalten sich oftmals ähnlich einer Desktop-Anwendung. Die Webseiten reagieren auf Interaktionen des Nut- zers flüssiger. Dies liegt daran, dass die Webseiten beim Einsatz von Ajax nicht komplett neu geladen werden. Vielmehr werden sukzessive einzelne Seitenbereiche nachgeladen. Damit dies funktioniert, wird auf Seiten des Clients eine Zwischen- schicht eingebaut, die Ajax Engine. Diese Engine ist üblicherweise eine existierende JavaScript-Bibliothek, die die asynchrone Datenübetragung steuert. Eine Anfrage des Clients wird dabei nicht direkt an den Server gesendet, sondern über eine Ajax Engine mittels XML, wie in Abbildung 2.1 zu sehen ist.2 Während der Anfragebearbeitung auf dem Server kann der Client somit noch auf Nutzerin- teraktionen reagieren. Durch die Ajax Engine muss die Server-Antwort nur die notwendigen Daten zur Änderung der Webseite enthalten, die anschließend von der Ajax Engine zur Seitenaktualisierung genutzt werden.3 1 Vgl. [Wik] 2 Neben XML ist auch die Verwendung von HTML oder JSON häufig anzutreffen. 3 siehe [MM10, S. 230 ff.] 4
  • 14. 2.2 Java EE Abb. 2.1: Prozessfluss des Ajax Modells von [Wik] 2.2 Java EE Die Java Platform Enterprise Edition (Java EE) gilt umgangssprachlich als das Java für Geschäftsanwendungen. Da in diesem Zusammenhang oft unklar ist, was Java EE wirklich ist und wie es sich in das bestehende Java Ökosystem eingliedert, erfolgt eine Einordnung von Java EE. Oftmals wird nicht zwischen Java als Sprache und Java als Plattform unterschie- den. Wobei mit Java SE, der Java Platform Standard Edition, durchaus diese Unterscheidung vorliegt. Java SE definiert eine Plattform, die sich aus der Java Standardbibliothek, der Java Virtual Machine und den Entwicklungstools (z.B. der Java Compiler) zusammensetzt. Hinzu kommen viele Bibliotheken von Drittanbie- tern. Die Java Standardbibliothek implementiert dabei die Kernfunktionalitäten der Programmiersprache Java und liefert eine Fülle an bereits implementierten Klassen. Darunter sind zum Beispiel Klassen für die Entwicklung grafischer Benut- zeroberflächen, für die Kommunikation über das Netzwerk oder auch Klassen zum 5
  • 15. 2.2 Java EE Parsen von XML-Dokumenten.4 „Die Java Platform, Enterprise Edition (Java EE) ist ein Aufsatz für die Java SE und integriert Pakete, die zur Entwicklung von Geschäftsanwendungen (Enterprise- Applikationen genannt) nötig sind.“5 Diese Beschreibung fasst es gut zusammen. Zusätzlich ist bei Java EE zwischen der Plattform und dem Programmiermodell zu unterscheiden. Unter Java EE als Plattform werden in dieser Arbeit die Komponen- ten der Laufzeitumgebung für Java Enterprise-Applikationen und die dafür nötigen Technologien verstanden. So werden z.B. Anwendungen, die mit Java EE entwickelt wurden, üblicherweise in einem Application Server oder Webcontainer installiert, die als Laufzeitumgebung dienen. Java EE als Programmiermodell definiert Pro- grammierschnittstellen (APIs) und Frameworks, mit deren Nutzung mehrschichtige, lose gekoppelte und skalierbare Geschäftsanwendungen entwickelt werden. Java EE besteht dabei aus einer Vielzahl an Spezifikationen bzw. Standards, die durch den JCP erarbeitet werden. JCP steht für den Java Community Process und bezeichnet einen Zusammenschluss von mehreren Firmen, Vereinigungen und Einzelpersonen, die in einem vorgeschriebenen Verfahren Spezifikationen für die Java Technologie erarbeiten. Diese Spezifikationen werden Java Specification Re- quests (JSR) genannt. Dabei ist es üblich, dass durch eine Spezifikation lediglich die abstrakte Programmierschnittstelle definiert wird und die konkreten Implemen- tierungen dafür durch mehrere Anbieter zur Verfügung gestellt werden. Dadurch ist der Entwickler nicht von einem Hersteller abhängig und kann die Implementierung jederzeit austauschen.6 In den folgenden Abschnitten wird auf die in der Arbeit verwendeten Spezifikationen des Java EE Programmiermodells eingegangen. 4 Vgl. [EJ10, Kapitel 2] 5 [Ull11, Kapitel 1.4.4] 6 siehe [Sta06, S. 22] 6
  • 16. 2.2 Java EE 2.2.1 Java Persistence API Der Standard für die Persistenzabbildung in Java EE wurde mit JPA im JSR 317 spezifiziert. Die Java Persistence API ist dabei zusammen mit EJB 3.0 im JSR 220 entstanden.7 Zwar ist JPA eine Java EE Spezifikation, es kann aber genauso in Java SE Anwendungen eingesetzt werden.8 JPA definiert unter Nutzung eines objektrelationalen Mappers das Persistieren von Java Objekten in einer relationalen Datenbank. Dabei wird das Data Mapper Pattern umgesetzt. Das Data Mapper Pattern ist ein Entwurfsmuster zur Separie- rung von Objekten und der Abbildung dieser in Datenbanktabellen. Die Objekte haben im Data Mapper Pattern keine direkte Kenntniss von der Datenbank. Die Abbildung in den Tabellen wird durch einen korrespondierenden Mapper geregelt.9 Die Grundkonzepte von JPA sind Persistent Entities, der Entity Manager, der Persistence Context, die Persistence Unit und der JPA Provider. Der zentrale Bestandteil von JPA sind die Persistent Entities.10 Damit werden einfache Java-Objekte (Plain Old Java Objects, abgekürzt POJOs) bezeichnet, die über die Entity-Annotation durch JPA persistierbar werden.11 Als POJO wird ein Java Objekt bezeichnet, dass keine externen Abhängigkeiten zu anderen Schnitt- stellen oder Frameworks hat und somit keiner Konvention, z.B. hinsichtlich der Benennung von Klassen oder Methoden, unterworfen ist.12 Sämtliche Informationen für die Abbildung in der relationalen Datenbank werden in der Persistent Entity über Annotationen angegeben. Alternativ können diese Informationen in Form von Deployment Deskriptoren beschrieben werden, was dem Vorgehen vor der Nutzung von Annotationen entspricht. Ein Deployment Deskriptor ist ein XML Dokument, 7 EJB (Enterprise Java Beans) beschreibt ein Programmiermodell zur Entwicklung von Java Komponenten, wobei dem Entwickler die Implementierung von infrastrukturellen Code, z.B. zur Transaktionssteuerung oder Lastverteilung, abgenommen wird. (Vgl. [OI07, S. 32]) 8 siehe [Wol10, S. 189] 9 Vgl. [Fow03, S. 165 ff.] 10 In der Arbeit werden für die Persistent Entities auch Synonyme wie JPA Fachklassen oder JPA Entity verwendet. 11 Vgl. [OI07, S. 187 f.] 12 siehe [Fow] 7
  • 17. 2.2 Java EE das unteranderem Meta-Informationen für Persistent Entities enthalten kann.13 Das Speichern, Löschen, Laden und Suchen von Persistent Entities in einer Daten- bank übernimmt ein so genannter Entity Manager. Dabei werden die Persistent Entities von einem Entity Manager verwaltet. Mit dem Begriff Persistent Unit werden dabei alle vom Entity Manager verwalteten Klassen bezeichnet. Im Ge- gensatz dazu werden alle vom Manager verwalteten Entities, also die Objekte der Klassen einer Persistent Unit, unter dem Begriff Persistence Context zusammenge- fasst. Dabei unterliegen die Persistent Entities einem Lebenszyklus, der durch die Verwendung des Entity Managers bestimmt wird, wie Abbildung 2.2 zeigt.14 Abb. 2.2: Lebenszyklus einer Persistent Entity aus [Obj] Wurde eine Persistent Entity mit dem new-Operator instanziiert, befindet sie sich im Zustand New. Zu dem Zeitpunkt ist die Entity nicht in der Datenbank abgebildet. Durch die persist- oder merge-Operation des Entity Managers kann die Persistent Entity dem Persistence Context hinzugefügt werden. Dann wird die Entity vom Entity Manager verwaltet und ist im so genannten Managed Zustand. Gleichzeitig wird die Persistent Entity dabei in der Datenbank abgebildet. Entweder werden neue Datenbankeinträge angelegt oder bestehende aktualisiert. Je nach Konfiguration kann das auch erst beim Commit einer Transaktion oder durch den expliziten Aufruf der flush-Methode erfolgen. Dadurch dass die Persistent Entities 13 siehe [OI07, S. 189 f.] 14 Vgl. [OI07, S. 194 ff.] 8
  • 18. 2.2 Java EE im Zustand Managed sind, werden Änderungen der Attributswerte vom Entity Manager registriert und mit der Datenbank synchronisiert. Mit der find-Methode des Entity Managers können Persistent Entities aus der Datenbank geladen werden. Diese sind dann ebenfalls im Managed Zustand. Sollen Entities in der Datenbank gelöscht werden, genügt es, die remove-Methode vom Entity Manager aufzurufen. Dafür müssen die Entities jedoch im Managed Zustand sein. Wird der Entity Manager geschlossen, werden sämtliche Persistent Entities entkoppelt und gelangen in den Detached Zustand. Für die Abfrage von Persistent Entities aus der Datenbank wird in JPA eine Abfragesprache definiert, die Java Persistence Query Language (JPQL). Die JPQL ist unabhängig von der Persistenzschicht. Das bedeutet, die Abfragen werden nicht in SQL formuliert, sondern auf Ebene der Objekte. Diese Abfragesprache ist jedoch SQL-ähnlich bei der Formulierung von Abfragen. Die formulierten JPQL Abfragen werden über den Entity Manager ausgeführt.15 Da JPA lediglich eine Programmierschnittstelle spezifiziert, muss für die Ver- wendung eine Implementierung der Schnittstellen eingebunden werden. Solche Implementierungen werden JPA Provider genannt. Für JPA in der Version 2.0 ist das Projekt EclipseLink16 die Referenzimplementierung eines JPA Providers.17 In dieser Arbeit wird jedoch Hibernate als JPA Provider eingesetzt.18 Konfiguriert wird ein JPA Provider über den Deployment Deskriptor in der Datei persistence.xml. In der persistence.xml werden die Persistence Units definiert und der Entity Manager konfiguriert. So wird dort z.B. eingestellt, zu welchem Zeitpunkt Persistent Entities in die Datenbank geschrieben werden oder welche Caching Methode verwendet wird, um die Performance der Persistenzschicht zu verbessern.19 15 Vgl. [OI07, S. 300 ff.] 16 siehe http://www.eclipse.org/eclipselink 17 siehe dazu http://www.eclipse.org/org/press-release/20080317_Eclipselink.php 18 siehe http://www.hibernate.org 19 Vgl. [OI07, S. 200 ff.] 9
  • 19. 2.2 Java EE 2.2.2 Bean Validation Der JSR 303 (Bean Validation) definiert für Java einen Standard zur Validierung von Objekten. Dabei werden Klassen und deren Attribute mit Annotationen versehen, die die Informationen zur Validierung enthalten. Einige Annotationen werden durch den Bean Validation Standard bereits vorgegeben. Mit der Size-Annotation kann beispielsweise die minimale und maximale Größe von Zeichenketten, Arrays und Listen festgelegt werden. Möglichkeiten zur Formulierung eigener Annotationen sind ebenso gegeben.20 Dadurch dass die Validierungsregeln deklarativ mit Annotationen hinterlegt wer- den, ist die Ausführung der Validierung entkoppelt. Diese kann somit an mehreren Stellen in der Anwendung durchgeführt werden, z.B. im Webframework bei der Eingabe von Daten in Formularen oder in der Persistenzschicht beim Speichern von Anwendungsdaten. Der JPA Provider Hibernate bietet mit der Referenzim- plementierung des JSR 303, Hibernate Validator, unteranderem die Möglichkeit, die mit Bean-Validation-Annotationen hinterlegten Validierungsregeln im Entity Manager einzusetzen und somit mit JPA zu vereinen.21 2.2.3 Dependency Injection for Java Wenn Anwendungen in Java entwickelt werden, bestehen diese aus vielen Klassen, die sich gegenseitig nutzen, um die erforderten Funktionalitäten umzusetzen. Die Klassen haben dadurch häufig mehrere Abhängigkeiten zu anderen Klassen. Diese müssen aufgelöst werden. Das geschieht, indem Objekte von abhängigen Klassen am Ort ihrer Nutzung erzeugt werden oder bestenfalls bei der Erzeugung von Klassen über den Konstruktor reingereicht werden. Das Problem bei diesem Vorgehen ist die enge Kopplung der Klassen untereinander und die Unflexibilität bei Änderungen, z.B. beim Austausch einzelner Klassen für Testzwecke. Soll die Implementierung einer Klasse ausgetauscht werden, müssen überall im Programmcode Änderungen erfolgen. Eine Lösung für dieses Problem ist Dependency Injection. Dabei werden 20 Vgl. [Wol10, S. 250 ff.] 21 siehe http://www.hibernate.org/subprojects/validator.html 10
  • 20. 2.2 Java EE abhängige Objekte zur Laufzeit injiziert. Das Objekt, dessen Abhängigkeiten aufgelöst werden, ist passiv bei diesem Vorgang. Das hat den Vorteil, dass zum einen große Objektnetze einfach erzeugt werden können, da die Objekte ihre Abhängigkeiten injiziert bekommen, und zum anderen ist der Austausch von Implementierungen darüber sehr leicht möglich.22 Mit dem JSR 330, Dependency Injection for Java, werden im Paket javax.inject Annotationen zur Verfügung gestellt, die die Nutzung und Implementierung von DI in Java standardisieren. Das Versehen von Attributen, Konstruktoren oder Methoden mit der Inject-Annotation sorgt dafür, dass die abhängigen Objekte an dieser Stelle injiziert werden. Um die Dependency Injection feiner zu steuern, können die Qualifier- und Named-Annotationen verwendet werden.23 In der Arbeit wird ausschließlich die Inject-Annotation genutzt. Genau genommen zählt der JSR 330 nicht zu den Java EE Spezifikationen. Aller- dings ermöglicht die Spezifikation das Bauen von lose gekoppelten Systemen in der gesamten Java Technologie, wovon Java EE eine Teilmenge ist. 2.2.4 JavaServer Faces JavaServer Faces (JSF) ist ein komponentenbasiertes Framework für die Entwicklung von Web-Anwendungen.24 Die in der Arbeit verwendete Version 1.2 wird durch den JSR 252 spezifiziert.25 Die Referenzimplementierung von JSF ist das Mojarra Projekt, welches ebenfalls in dieser Arbeit eingesetzt wird.26 Das zugrundeliegende Entwurfsmuster von JSF ist das Model-View-Controller- Muster (MVC). Durch das MVC-Entwurfsmuster sollen Anwendungen mit einer grafischen Oberfläche besser strukturiert werden. Ziel ist es, die Bestandteile der Anwendung wiederverwendbarer, erweiterbarer und wartbarer zu gestalten, indem 22 Vgl. [Wol10, S. 20] 23 Vgl. [Wol10, S. 81 ff.] 24 Vgl. [MM10, S. 6] 25 siehe http://www.jcp.org/en/jsr/detail?id=252 26 siehe http://javaserverfaces.java.net 11
  • 21. 2.2 Java EE die Daten (Model), die Darstellung (View) und das Verhalten (Controller) vonein- ander getrennt implementiert werden.27 Der Einsatz des MVC-Entwurfsmusters in JSF wird in Abbildung 2.3 gezeigt. Abb. 2.3: MVC-Architektur von JSF aus [MM10] Der Controller wird in JSF durch das Faces-Servlet implementiert. Dabei wird die Servlet Technologie der Java EE Plattform verwendet. Servlets werden durch den JSR 154 beschrieben.28 Für diese Arbeit genügt es zu wissen, dass Servlets den ersten Versuch darstellten, dynamische Webseiten mit Java zu erzeugen. Servlet Klassen können auf HTTP Anfragen reagieren und diese beantworten, indem sie im Java Code z.B. über Streams HTML schreiben.29 In JSF wird die Servlet Technologie nur intern verwendet. Das Faces-Servlet enthält die Steuerungslogik einer JSF Anwendung. Dieses Servlet steuert aufgrund einer Anfrage des Clients den Aufruf des benötigten Views und erzeugt die korrespondierenden Models. JSF unterstützt bisher zwei verschiedene View-Technologien: Facelets und JSP (JavaServer Pages). In dieser Arbeit wird Facelets verwendet. Der View wird bei der Nutzung von Facelets durch XHTML-Dokumente implementiert, die spezifische Tags aus der Facelets Tag Library enthalten. Eine Tag Library ist eine Sammlung von XHTML-Tags, die über einen eigenen XML Namensraum (engl. Namespace) 27 Vgl. [Bos04, S. 45 ff.] 28 sieh http://www.jcp.org/en/jsr/detail?id=154 29 Vgl. [MM10, S. 2 ff.] 12
  • 22. 2.2 Java EE eindeutig identifizierbar sind. Außerdem kann die Darstellung bei Verwendung von Facelets modular aufgebaut werden.30 Ein View bzw. eine Ansicht wird in JSF aus Komponenten zusammengesetzt. Kom- ponenten sind eigenständige und wiederverwendbare Bausteine. Beim Erzeugen eines Views wird in JSF ein Komponentenbaum erzeugt. Durch den Komponen- tenbaum werden die einzelnen Komponenten einer Ansicht miteinander verknüpft. Das Wurzelelement des Baums wird dabei durch ein Objekt der Klasse UIViewRoot repräsentiert. Die Komponenten einer Ansicht werden als Kindelemente an das Wurzelelement gehängt. Die Bearbeitung einer Anfrage, die sich in JSF in meh- rere Phasen unterteilt, wie Abbildung 2.4 zeigt, beginnt immer mit einem Aufruf einer Methode des UIViewRoot-Elements, das den Methodenaufruf rekursiv an die Kindelemente weiterleitet. Über diesen Mechanismus kann jede Komponente einer Ansicht auf eine Anfrage reagieren.31 Abb. 2.4: JSF Standard Request-Response-Zyklus aus [EJ10] 30 siehe [MM10, S. 157 f.] 31 Vgl. [MM10, S. 20 ff.] 13
  • 23. 2.2 Java EE Ein weiteres wichtiges Konzept stellen die Managed Beans dar, auch Backing Beans genannt, über die das Model in JSF implementiert wird. Managed Beans sind normale POJOs. Sie liefern die Werte für die im View definierten Komponenten. Managed Beans können dabei verschiedene Gültigkeitsbereiche haben, die sich in der Dauer der Lebenszeit eines Managed Bean Objekts unterscheiden. In JSF 1.2 ist dafür die Dauer der Requestbearbeitung, einer HTTP Session oder auch die gesamte Dauer der Applikationsausführung möglich. Bevor ein normales Java Objekt als Managed Bean gilt, muss ein Eintrag in der Konfiguration von JSF erfolgen.32 Die Konfiguration von JSF wird in der faces-config.xml Datei formuliert. Außerdem muss JSF in der web.xml Konfigurationsdatei eingerichtet werden. Damit eine JSF Anwendung funktioniert, muss ein Servlet Container (auch Webcontainer genannt) als Laufzeitumgebung genutzt werden.33 Ein solcher Servlet Container nutzt die Informationen aus der web.xml Datei, um z.B. Servlets zu starten. Die web.xml Datei ist ein Deployment Deskriptor für einen Servlet Container, eine Bereitstellungsbeschreibung einer Anwendung. Das Faces-Servlet muss dort über einen Eintrag hinterlegt werden. § Listing 2.1: Eintragung des Faces-Servlet in der web.xml ¤ < s e r v l e t> <s e r v l e t −name>Faces S e r v l e t</ s e r v l e t −name> <s e r v l e t −c l a s s> j a v a x . f a c e s . webapp . F a c e s S e r v l e t </ s e r v l e t −c l a s s> <load−on−s t a r t u p>1</ load−on−s t a r t u p> </ s e r v l e t> ¦ ¥ Eine JSF-Anwendung wird in Form einer WAR-Datei bereitgestellt. Mit dem Web Application Archive (WAR) wird eine standardisierte Verzeichnisstruktur für 32 Das gilt für JSF 1.2. Im neueren JSF 2.0 Standard ist die Definition von Managed Beans über Annotationen möglich. 33 Der Servlet Container war bereits in Abbildung 2.3 in Form der Servlet Engine dargestellt, die ein Teil eines Servlet Containers ist. 14
  • 24. 2.2 Java EE Webanwendungen in Java EE definiert. So enthält beispielsweise das Verzeichnis WEB-INF in einer WAR-Datei die Konfiguration und Seitenbeschreibungen ei- ner Web-Anwendung. Als Archivierungsformat wird das bekannte JAR-Format verwendet. Unified Expression Language Mit der Unified Expression Language werden die Komponenten der Ansicht und die dahinterliegenden Managed Beans miteinander verbunden. Darüber können im View Daten aus den Managed Beans gelesen und in diese geschrieben werden. Weiterhin werden über Expression-Language-Ausdrücke (kurz EL-Ausdruck) Me- thoden für die Ereignisbehandlung von Komponenten im View angegeben. Ein EL-Ausdruck beginnt mit einer Raute und wird von geschweiften Klammern um- schlossen. Zwischen den Klammern kann der Name einer Managed Bean stehen und durch Punkte getrennt die Attribute der Managed Bean. Mit dem Ausdruck #{per- son.vorname} wird beispielsweise auf das Attribut vorname der Managed Bean person zugegriffen. Ebenfalls können einfache Operationen in einem EL-Ausdruck untergebracht werden.34 Standard-Komponenten JSF bietet eine Palette an Standard-Komponenten. Das sind bereits fertige JSF Komponenten, die die Grundlage für die Entwicklung von JSF Anwendungen bilden. Die Standard-Komponenten von JSF werden in den beiden Tag Libraries HTML- Custom-Tag-Library und Core-Tag-Library implementiert und können durch das Einbinden des jeweiligen XML Namespaces in einer View-Beschreibung genutzt werden.35 Die HTML-Custom-Tag-Library im XML-Namensraum h stellt Komponenten zur HTML-Ausgabe zur Verfügung. Die Core-Tag-Library mit dem XML-Namensraum f vereint wiederum alle Basis-Komponenten, die für die Nutzung von JSF benötigt 34 Vgl. [MM10, S. 36 ff.] 35 Vgl. [MM10, S. 109] 15
  • 25. 2.3 Programmiersprache Scala werden. So wird beispielsweise mit dem f:view Tag der Core-Tag-Library der Wurzelknoten eines Komponentenbaums in der Ansicht definiert. Das Einbinden der Namensräume erfolgt bei der Deklaration des HTML-Tags in der Seitenbeschreibung. § Listing 2.2: Einbinden der Namensräume der beiden Standard-Tag-Libraries ¤ <html xmlns=" h t t p : / /www. w3 . o r g /1999/ xhtml " xmlns : h=" h t t p : / / j a v a . sun . com/ j s f / html " xmlns : f=" h t t p : / / j a v a . sun . com/ j s f / c o r e "> ¦ ¥ RichFaces Komponentenbibliothek Die RichFaces Bibliothek erweitert die JSF Standard-Komponenten um viele Zusatzkomponenten. Außerdem implementiert RichFaces einige Komponenten mit Unterstützung für Ajax, was in JSF 1.2 noch nicht vorhanden ist. Zusätzlich dazu besteht die Möglichkeit, RichFaces Komponenten über einen Theming Mechanismus durch eine Einstellung in der faces-config.xml im Aussehen anzupassen. 2.3 Programmiersprache Scala An der École polytechnique fédérale de Lausanne (EPFL) in der Schweiz begann 2001 eine Projektgruppe unter Leitung von Martin Odersky mit dem Entwurf einer neuen Sprache, die objektorientierte und funktionale Programmierparadigmen vereinen sollte. Das Ergebnis dieser Arbeit wurde im Jahr 2003 mit der ersten Version der Programmiersprache Scala veröffentlicht.36 Die Namensgebung soll ausdrücken, dass Scala (aus dem Englischen scalable, skalierbar) an den Anforderungen des Entwicklers wächst. Die Programmiersprache Scala setzt auf die Java SE Plattform auf. Scala Code wird in Java Bytecode kompiliert und durch eine JVM ausgeführt. Außerdem kann 36 Vgl. [Bra11, Kapitel 1] 16
  • 26. 2.3 Programmiersprache Scala Scala interpretiert ausgeführt werden. Dazu liegt der Scala Laufzeitumgebung ein interaktiver Interpreter bei, eine so genannte REPL.37 Im Gegensatz zu Java ist Scala vollständig objektorientiert. Alles ist ein Objekt, auch primitive Datentypen. Dadurch dass Scala in Java-Bytecode kompiliert wird, kann von Scala aus Java Code genutzt werden. Scala ist interoperabel mit Java. In Scala steht also die gesamte Java Standardbibliothek zur Verfügung und sämtliche andere Java Bibliotheken. In den nächsten Abschnitten werden die in dieser Arbeit eingesetzten Sprachfeatures von Scala erläutert. 2.3.1 Klassen und Objekte Scala ist objektorientiert und unterstützt daher das Konzept der Klassen und Objekte. Wie in Java wird das Schlüsselwort class zum Definieren einer Klasse verwendet. Methoden bzw. Funktionen werden mit dem Schlüsselwort def eingeleitet. Das folgende Listing zeigt eine einfach Scala Klasse, die ein typisches Hello-World- Beispiel umsetzt. § Listing 2.3: Einfache Scala Klasse ¤ c l a s s HelloWorld ( val g r e e t i n g : S t r i n g ) { def s a y H e l l o ( ) = p r i n t l n ( g r e e t i n g ) } new HelloWorld ( " H a l l o ! " ) . s a y H e l l o ( ) // Ausgabe : H a l l o ! ¦ ¥ Mit dem new-Operator wird wie in Java eine Instanz von HelloWorld erzeugt und anschließend die Methode sayHello ausgeführt. Anders als bei Java wird in Scala der Konstruktor direkt in Form einer Parame- terliste hinter dem Klassennamen angegeben. Die HelloWorld Klasse hat einen 37 Die Read-Execute-Print-Loop beschreibt einen Interpreter, der einen Befehl einliest, ausführt, das Ergebnis ausgibt und anschließend auf die nächste Befehlseingabe wartet. 17
  • 27. 2.3 Programmiersprache Scala Parameter vom Typ String, greeting. Die Typangabe erfolgt in Scala nach der An- gabe des Bezeichners und mit einem Doppelpunkt getrennt. Mit dem Schlüsselwort val wird greeting als unveränderbares Feld definiert. Das ist mit der Verwendung von final in Java vergleichbar. Soll greeting veränderbar sein, wird das Schlüsselwort var anstalle von val verwendet. Die Sichtbarkeit von sayHello ist automatisch public. Anders als in Java haben Methoden und Felder standardmäßig nicht die Sichtbarkeit friendly, sondern public. Mit den Zugriffsmodifizierern private und protected kann die Sichtbarkeit wie in Java eingestellt werden. Die Methode sayHello hat nur eine Aufgabe: den mit greeting übergebenen Wert auf dem Standardausgabestrom ausgeben. Dazu wird die Methode println des Predef -Objektes aufgerufen. Das Predef -Objekt wird automatisch vom Compiler in jede Scala-Datei importiert und stellt oft benötigte Funktionen zur Verfügung.38 Obwohl Scala statisch typisiert ist, muss der Rückgabetyp von sayHello nicht angegeben werden, da Scala über einen Typinferenz-Mechanismus verfügt. Darüber kann der Compiler feststellen, welchen Typ ein Wert im Aufrufkontext hat. In diesem Fall, wird der Typ Unit hergeleitet, vergleichbar mit dem void Typ in Java. Da println lediglich eine Zeichenkette auf dem Standardausgabestrom ausgibt, wird der Typ Unit zurückgegeben. Aufgrund der funktionalen Natur von Scala hat alles in Scala einen Wert. Anders als in Java muss zum Zurückgeben eines Wertes nicht return verwendet werden, es gilt der Wert des letzten Ausdrucks eines Programmblocks als Rückgabewert. Neben der Typinferenz verfügt Scala ebenfalls über eine Semikoloninferenz. Semi- kolons sind in Scala nicht notwendig, um das Ende eines Befehls zu signalisieren und werden größtenteils weggelassen. Ein Scala eigenes Sprachmittel sind Singleton Objekte.39 Die Idee des Singletons entstammt einem Entwurfsmuster, bei dem von einer Klasse genau eine Instanz 38 Außerdem werden dort auch wichtige Typ-Synonyme und Implicit Conversions definiert. 39 Die Begriffe Objekt und Singleton werden in dieser Arbeit als Synonyme für den Begriff der Singleton Objekte verwendet. 18
  • 28. 2.3 Programmiersprache Scala existiert und ein globaler Zugriff darauf.40 Scala verallgemeinert dieses Muster mit der Nutzung des Schlüsselworts object und unterstützt es direkt in der Sprache. In Singleton Objekten werden in Scala statische Werte und Methoden implemen- tiert. Statische Methoden mit dem Schlüsselwort static wie in Java zu definieren, ist nicht möglich. Hierbei trennt Scala zwischen nicht-statischen und statischen Programmcode-Teilen. Sollen einer Klasse statische Felder oder Methoden hinzuge- fügt werden, existiert in Scala dafür das Companion Objekt, welches im folgenden Listing für das Hello-World-Beispiel implementiert ist. An der Implementierung der HelloWorld-Klasse ändert sich dabei nichts. § Listing 2.4: Klasse mit dazugehörigem Companion Objekt ¤ c l a s s HelloWorld ( val g r e e t i n g : S t r i n g ) { def s a y H e l l o ( ) = p r i n t l n ( g r e e t i n g ) } object HelloWorld { def apply ( ) = new HelloWorld ( " Standard Meldung " ) def sayHi ( ) = p r i n t l n ( " Hi ! " ) } HelloWorld ( ) . s a y H e l l o ( ) // Ausgabe : Standard Meldung HelloWorld . sayHi ( ) // Ausgabe : Hi ! ¦ ¥ Ein Companion Objekt ist ein spezielles Singleton Objekt, das den gleichen Na- men wie eine Klasse hat und sich in der selben Quellcode-Datei befindet. Im Companion Objekt HelloWorld werden zwei Methoden definiert, apply und say- Hi. Die sayHi Methode stellt eine normale statische Methode dar, die über den Namen des Companion Objekts aufgerufen werden kann. Die abgebildete apply- Methode ist eine Besonderheit bei der Nutzung von Companion Objekten. Mit 40 Vgl. [EG95, S. 127] 19
  • 29. 2.3 Programmiersprache Scala der apply-Methode existiert eine eingebaute Fabrik-Methode in Scala. In einer apply-Methode wird eine Instanz der Klasse des Companion Objektes erzeugt und zurückgegeben. Der Vorteil dabei ist, Scala erlaubt das Weglassen des Aufrufs der apply-Methode. So kann HelloWorld().sayHello() geschrieben werden, was vom Compiler zu HelloWorld.apply().sayHello() erweitert wird. Die apply-Methode kann natürlich beliebige Parameter aufnehmen. 2.3.2 Traits Ein neues Sprachmittel, dass mit Scala eingeführt wird, sind Traits, die die aus Java bekannten Interfaces ersetzen. Ein Trait ist mit einem Java Interface vergleichbar. Allerdings mit dem Unterschied, dass Traits neben der Deklaration von Methoden auch Implementierungen beinhalten können. Ein Trait wird mit dem Schlüsselwort trait definiert, wie im folgenden Listing zu sehen ist. § Listing 2.5: Beispiel der Nutzung von Traits ¤ t r a i t HasName { val name = "Name von etwas " } t r a i t HasAge { def c a l c u l a t e A g e : I n t } c l a s s Person extends HasName with HasAge { def c a l c u l a t e A g e = 18 override val name = "Name e i n e r Person " } ¦ ¥ 20
  • 30. 2.3 Programmiersprache Scala Wie bei der Klasse Person zu sehen ist, können Klassen mehrere Traits implemen- tieren. Der erste Trait wird immer mit extends hinzugefügt, alle folgenden mit dem Schlüsselwort with. Scala unterstützt allerdings keine Mehrfachvererbung. Es handelt sich dabei um einen so genannten Mixin-Mechnismus. Ein Mixin ist eine wiederverwendbare Einheit, die zusammengehörige Funktionen bündelt.41 In diesem Zusammenhang wird auch vom Einmixen eines Traits gesprochen. Mögliche Proble- me, die bei Mehrfachvererbung auftreten, wie z.B. das Diamond Problem, werden bei Traits mit Hilfe von Linearisierung umgangen. Dabei werden die eingemixten Traits und Klassen der Vererbungshierarchie in der Reihenfolge des Einmixen in Form einer Liste aufeinander gelegt, wodurch Methoden, die in unterschiedlichen Typen mehrfach definiert sind, für den Compiler auflösbar bleiben.42 Im Listing 2.5 ist außerdem zu erkennen, dass in Scala mit override ein spezielles Schlüsselwort für das Überschreiben von Methoden und Feldern existiert. Da calculateAge noch keine Implementierung in HasAge hat, ist override bei dieser Methode nicht notwendig. Es kann jedoch angegeben werden. 2.3.3 Funktionen Da Scala neben den objektorientierten Programmierparadigmen ebenfalls funktio- nale Paradigmen einschließt, sind Funktionen einer der wichtigsten Bestandteile der Sprache. Funktionen sind in Scala so genannte First Class Values, auch First Class Citizens genannt, was bedeutet, sie werden als Werte behandelt und können als solche Variablen zugewiesen werden oder als Parameter anderen Funktionen übergeben werden. Ebenso ist es möglich, dass Funktionen andere Funktionen als Rückgabewert zurückgeben.43 Eine Funktion wird mit dem Schlüsselwort def definiert, was bereits in den voran- gegangenen Abschnitten gezeigt wurde. Alternativ dazu besteht die Möglichkeit, Funktionen über Funktionsliterale zu definieren Das folgende Listing zeigt die 41 Vgl. [Bra11, S. 84] 42 siehe [MO08, Kapitel 12.6] 43 Vgl. [Bra11, Kapitel 5.2] 21
  • 31. 2.3 Programmiersprache Scala Funktion dec, die über def angelegt wird und anschließend alternativ als Funkti- onsliteral. § Listing 2.6: Beispiel einer einfachen Funktion ¤ def dec ( i : I n t ) = i − 1 // F u n k t i o n s l i t e r a l f ü r dec ( i : Int ) = i − 1 > ¦ ¥ Ein Funktionsliteral wird dabei mit einem Doppelpfeil angegeben.44 Links davon steht die Parameterliste der Funktion und rechts davon die Befehle der Funktion. Beide Schreibweisen erzeugen das gleiche Ergebnis. Der Vorteil des Funktionsliterals ist, dass eine Funktion darüber sehr einfach als Wert zugewiesen werden kann, was im Listing 2.7 zu sehen ist. Ebenfalls wird durch Funktionsliterale die Angabe anonymer Funktionen erleichtert. § Listing 2.7: Beispiel der Zuweisung eines Funktionswertes ¤ val d e c F u n c t i o n = ( i : I n t ) = i − 1 > p r i n t l n ( d e c F u n c t i o n ( 4 ) ) // Ausgabe : 3 ¦ ¥ Funktionen höherer Ordnung Mit dem Begriff der Funktionen höherer Ordnung werden Funktionen bezeichnet, bei denen Parameter oder der Rückgabewert aus einer Funktion bestehen. Das ist ein hilfreiches Mittel zur Abstraktion von allgemeinem Verhalten, wie das folgende Listing zeigt.45 § Listing 2.8: Anwendung einer Funktion höherer Ordnung ¤ def dec ( i : I n t ) = i − 1 def d e c L i s t ( l i s t : L i s t [ I n t ] ) = l i s t map dec 44 Der Doppelpfeil setzt sich aus einem Gleichheitszeichen und einem Pfeil zusammen. 45 siehe [Bra11, Kapitel 5.3] 22
  • 32. 2.3 Programmiersprache Scala p r i n t l n ( d e c L i s t ( L i s t ( 1 , 2 , 3 ) ) ) // Ausgabe : L i s t ( 0 , 1 , 2 ) ¦ ¥ In der Funktion decList wird die Dekrementierungsfunktion dec auf alle Elemente der übergebenen Liste angewendet. Dazu wird die Funktion höherer Ordnung namens map verwendet. Die map Funktion gehört zur Collections API von Scala. map wendet die übergebene Funktion dec auf alle Elemente der Liste an und gibt die dadurch neu enstandene Liste als Ergebnis zurück. In der decList Funktion kommen gleich mehrere Scala-Besonderheiten zum Einsatz, die den Aufruf von map verkürzen. In der vollen Länge wird map hier wie folgt aufgerufen. § Listing 2.9: Vollständig ausgeschriebener Aufruf von map ¤ l i s t . map ( ( i : I n t ) = dec ( i ) ) > ¦ ¥ In dieser Form macht das Funktionsliteral, das map als Parameter übergeben wird, deutlich, dass es sich um eine Funktion höherer Ordnung handelt. Durch die Typinferenz kann Int in der Parameterliste des Funktionsliterals weggelassen werden. Da dec ledigleich einen Parameter erwartet, kann die Angabe des Parameters i ebenfalls entfallen. Der Scala Compiler setzt dann einen automatisch generierten Platzhalter an der Stelle für i ein. Dieser Platzhalter hätte auch explizit mit einem Unterstrich angegeben werden können. § Listing 2.10: Aufruf der map Funktion mit einem Platzhalter ¤ l i s t . map( dec (_) ) ¦ ¥ Als weitere Möglichkeit der Vereinfachung wird abschließend die Infix-Operator- Schreibweise46 für Funktionen verwendet, wodurch der in Listing 2.8 gezeigte Aufruf der map Funktion zustandekommt. Da Operatoren in Scala auch nur Methoden von Klassen sind, kann die Infix-Operator-Schreibweise bei Funktionen verwendet werden.47 46 Dabei steht ein Operator zwischen seinen zwei Operanden. 47 Vgl. [MO08, Kapitel 5.3] 23
  • 33. 2.3 Programmiersprache Scala Beim Aufruf von decList in der println Methode wird das Companion Objekt von List genutzt und intern die apply-Methode aufgerufen. Denn der Aufruf List(1, 2, 3) wird vom Compiler zu List.apply(1, 2, 3) erweitert. Currying Unter Currying wird das Abbilden einer Funktion mit mehreren Parametern, auf mehrere Funktionen mit je einem Parameter verstanden. In Scala gilt dies ebenso für Funktionen mit Parameterlisten. Dadurch können Funktionen mit mehreren Parameterlisten definiert werden, wie das folgende Listing zeigt.48 § Listing 2.11: Beispiel einer Funktion mit mehreren Parameterlisten ¤ def sub ( x : I n t ) ( y : I n t ) = x − y p r i n t l n ( sub ( 2 ) ( 3 ) ) // Ausgabe : −1 ¦ ¥ Die Auflösung einer solchen Funktion durch den Compiler kann wie folgt veran- schaulicht werden. § Listing 2.12: Abbildung der sub Funktion auf mehrere Funktionen ¤ def sub ( x : I n t ) = ( y : I n t ) = x − y > ¦ ¥ Die sub Funktion hat nur noch eine Parameterliste und in der Funktion selbst wird ein Funktionsliteral mit der zweiten Parameterliste definiert. Der Aufruf dieser Funktion gestaltet sich genauso, wie von der in Listing 2.11 gezeigten Funktion. Partielle Funktionen Bei den partiellen Funktionen muss zwischen den partiellen und den partiell ange- wandten Funktionen unterschieden werden. Eine partielle Funktion ist eine Funktion, die nicht für alle Werte ihres Definitions- bereichs definiert ist.49 Anwendungen solcher Funktionen werden im nachfolgenden 48 siehe [Bra11, Kapitel 5.5] 49 Vgl. [Bra11, S. 124] 24
  • 34. 2.3 Programmiersprache Scala Kapitel über Pattern Matching gezeigt. Mit dem Trait PartialFunction existieren außerdem Hilfsfunktionen, um beispielsweise zu bestimmen, ob eine Funktion für einen bestimmten Wert ihres Definitionsbereichs definiert ist.50 Eine partiell angewandte Funktion hingegen ist eine Funktion, die auf einen Teil ihrer Parameter bereits angewendet ist.51 Es ist häufig der Fall, dass partiell angewandte Funktionen zusammen mit Currying eingesetzt werden, indem eine Parameterliste bereits angewendet wird und eine weitere zur Aufnahme zusätzlicher Parameter dient. Im folgenden Beispiel wird die sub Funktion aus dem Listing 2.11 partiell angewendet und einem Wert zugewiesen. § Listing 2.13: Beispiel einer partiell angewandten Funktion ¤ val subTwoWith = sub ( 2 ) _ p r i n t l n ( subTwoWith ( 3 ) ) // Ausgabe : −1 ¦ ¥ Der Unterstrich dient hierbei als Platzhalter für die zweite Parameterliste. Die Signatur der in subTwoWith gespeicherten Funktion lautet Int => Int. Es wird dabei also eine neue Funktion mit nur einer Parameterliste erzeugt, die intern auf die sub Funktion zugreift. Die wirkliche Stärke dieses Sprachmittels wird deutlich, wenn anstatt des einfachen Parameters mit dem Zahlenwert 3 eine Funktion verwendet wird, wie im folgenden Listing. § Listing 2.14: Kontrollstruktur-ähnliche Konstrukte mit subTwoWith ¤ p r i n t l n ( subTwoWith { val n i n e = 4 + 5 val s i x = 2 + 4 nine − s i x }) ¦ ¥ 50 Die Funktion dafür lautet isDefinedAt. 51 Vgl. [MO08, S. 147] 25
  • 35. 2.3 Programmiersprache Scala Das Ergebnis dieses Aufrufs von subToWith ist das gleiche wie im vorangegangenen Listing. Durch die Verwendung der geschweiften Klammern und der Formulierung eines Funktionsblocks wirkt die Verwendung von subTwoWith wie eine Scala-eigene Kontrollstruktur. Solche Konstrukte sind bei der Verwendung von Scala häufig anzutreffen. 2.3.4 Pattern Matching Pattern Matching kann für einen Java Entwickler als Erweiterung der Switch- Case-Kontrollstruktur erklärt werden. Beim Pattern Matching wird ein Wert mit Mustern verglichen. Die Besonderheit bei Scala ist, dass nicht nur Werte als Muster angegeben werden können, sondern auch Typen.52 Eine einfache Anwendung von Pattern Matching zeigt das folgende Beispiel.53 § Listing 2.15: Bespiel von Pattern Matching in printInt ¤ def p r i n t I n t ( i : I n t ) = i match { case 1 = p r i n t l n ( " Eins " ) > case 2 = p r i n t l n ( " Zwei " ) > case _ = p r i n t l n ( " e i n e a n d e r e Zahl " ) > } p r i n t I n t ( 2 ) // Ausgabe : Zwei ¦ ¥ Mit dem Schlüsselwort match wird ein Pattern-Matching-Ausdruck eingeleitet und in diesem Fall auf den Parameter i angewendet. Mit case werden die einzelnen Mus- ter definiert, gegen die i verglichen wird. Der Doppelpfeil leitet den Codeblock ein, der ausgeführt wird, sollte das jeweilige Muster passt. Nachdem ein Muster gepasst hat, kehrt die Ausführung aus dem Match-Ausdruck zurück. Der Rückgabewert entspricht dem des ausgeführten Codeblocks. Mit dem Unterstrich wird das Wildcard-Pattern definiert, das auf jeden Wert und Typen passt. Wird das Wildcard-Pattern weggelassen, ist der Match-Ausdruck 52 siehe [Bra11, Kapitel 5.4] 53 in Anlehnung an [Bra11, S. 115] 26
  • 36. 2.3 Programmiersprache Scala mitunter nicht für alle Werte des Definitionsbereichs definiert. Ist ein solcher Match- Ausdruck die einzige Anweisung einer Funktion, wird die Funktion zur partiellen Funktion, wie das folgende Listing zeigt.54 § Listing 2.16: Pattern Matching in Form einer partiellen Funktion ¤ def printType ( v a l u e : Any) = v a l u e match { case i : I n t = p r i n t l n ( " I n t : " + i ) > case d : Double = p r i n t l n ( " Double : " + d ) > } printType ( 2 ) // Ausgabe : I n t : 2 ¦ ¥ Die printType Funktion verwendet für den Mustervergleich Typen. Außerdem ist diese Funktion eine partielle Funktion, da sie nur für Int und Double Typen definiert ist, obwohl der Definitionsbereich Any ist. Any ist der Basistyp des Scala- Typsystems. Wird printType beispielsweise mit einer Zeichenkette aufgerufen, wird zur Laufzeit ein MatchError erzeugt, da die Funktion für den String-Typ nicht definiert ist. 2.3.5 Self-Type Annotationen Self-Type-Annotationen ermöglichen es, den Typ des this Wertes explizit zu dekla- rieren. Dadurch können Funktionalitäten einer Klasse modular verteilt in mehreren Traits implementiert werden oder aber ein Trait kann Abhängigkeiten festlegen, die seine Funktionen benötigen und durch das Einmixen in die richtigen Klassen aufgelöst werden.55 Ein Beispiel für den Einsatz einer Self-Type Annotation wird im folgenden Listing gezeigt.56 54 in Anlehnung an [Bra11, S. 116] 55 siehe [Bra11, S. 160 ff.] 56 entnommen aus [Bra11, S. 161] 27
  • 37. 2.3 Programmiersprache Scala § Listing 2.17: Beispiel einer Self-Type Annotation ¤ trait Noise { def makeNoise : Unit } t r a i t Food { def e a t : Unit } t r a i t Animal { t h i s : N o i s e with Food => def run = { makeNoise eat makeNoise } } ¦ ¥ Eine Self-Type-Annotation wird zu Beginn einer Typ-Definition formuliert. Sie besteht dabei aus dem Schlüsselwort this,57 der Typangabe, die gewohnt mit einem Doppelpunkt vom Bezeichner getrennt wird und einem Doppelpfeil. Dadurch dass der Animal Trait die Self-Type Annotation Noise with Food hat, kann er nur in Klassen eingemixt werden, die diese beiden Traits ebenfalls einmixen und implementieren. Animal kann außerdem auf die Methoden (und Felder) von Noise und Food zugreifen. 57 Alternativ kann auch self verwendet werden. Da this jedoch deutlicher aussagt, dass der Typ des this Wertes überschrieben wird, ist diese Variante zu bevorzugen. 28
  • 38. 2.3 Programmiersprache Scala 2.3.6 Implicit Conversions Mit Implicit Conversions können in Scala Typumwandlungen in Form von Methoden definiert werden. Wird eine Methode mit dem vorangestellten Schlüsselwort implicit definiert, gilt sie als Implicit Conversion. Erwartet der Compiler ein Objekt eines bestimmten Typs, findet jedoch ein Objekt eines inkompatiblen Typen vor, sucht er nach einer Implicit Conversion. Findet der Compiler eine passende Umwandlung, führt er die Methode aus. Durch dieses Sprachmittel können in Scala bestehende Klassen um zusätzliche Funktionen erweitert werden. Das wird auch als Pimp-my-Library-Pattern bezeichnet.58 Wie einfach die Nutzung von Implicit Conversions ist, zeigt das nachfolgende Listing. § Listing 2.18: Beispiel einer Implicit Conversion ¤ c l a s s F a n c y S t r i n g ( val s t r : S t r i n g ) { def d o F a n c y S t u f f = s t r + " f a n c y " } object F a n c y S t r i n g { i m p l i c i t def s t r i n g T o F a n c y S t r i n g ( s t r : S t r i n g ) : F a n c y S t r i n g = new F a n c y S t r i n g ( s t r ) } import F a n c y S t r i n g ._ p r i n t l n ( " H a l l o " . d o F a n c y S t u f f ) // Ausgabe : H a l l o f a n c y ¦ ¥ Die Klasse String der Java Standardbibliothek wird hierbei durch FancyString und die im Companion Objekt implementiere Typumwandlung um die Methode doFancyStuff erweitert. Obwohl diese Methode nicht in der String Klasse definiert ist, kann sie dadurch an einem String Objekt aufgerufen werden. Vor dem Aufruf von doFancyStuff wird der Compiler das String-Objekt „Hallo“ dafür mit Hilfe 58 siehe http://www.artima.com/weblogs/viewpost.jsp?thread=179766 29
  • 39. 2.4 Lift Web-Framework von stringToFancyString in ein Objekt des Typs FancyString umwandeln. Damit die Implicit Conversion vom Compiler gefunden wird, importiert die Anweisung import FancyString._ die Felder und Methoden von FancyString. 2.4 Lift Web-Framework Im Jahr 2007 startete die Entwicklung von Lift. Das Lift Framework ist ein in Scala entwickeltes Framework zur Entwicklung von Web-Anwendungen. Es ist ein so genanntes Full-Stack Web-Framework. Das bedeutet, neben Funktionen zur Erzeugung von Webseiten werden z.B. auch Funktionalitäten zum Speichern der Anwendungsdaten in einer Datenbank angeboten oder für die Validierung der Nutzereingaben. Ohne die Nutzung anderer Bibliotheken kann mit Lift eine komplette Web-Anwendung entwickelt werden. Lift baut auf bewährte Konzepte anderer Web-Frameworks auf und versucht diese zu vereinen. So wird beispielsweise der Ansatz der Convention over Configuration befolgt, der vom Web-Framework Ruby on Rails59 inspiriert wurde. Mit Convention over Configuration soll der Aufwand und die Komplexität der Konfiguration und Nutzung des Frameworks gesenkt werden, indem sinnvolle Vorgaben und Annahmen vom Framework über die Nutzung getroffen werden, wie z.B. eine vorgegebene Verzeichnisstuktur. Lift ist allerdings kein MVC-Framework wie JSF.60 In Lift wird ein selbstdefiniertes Entwurfsmuster verwendet. Die Lift-Entwickler verfolgen den View-First-Ansatz für den Entwurf von Web-Anwendungen, wobei ein als View-ViewModel-Model beschreibbares Entwurfsmuster eingesetzt wird, das in Abbildung 2.5 zu sehen ist.61 Der View-First-Ansatz besagt, dass in der Beschreibung der Seitendarstellung ausschließlich valide Standard XHTML-Tags verwendet werden und wurde durch 59 siehe http://rubyonrails.org 60 Wobei MVC mit Lift sehr wohl umsetzbar ist. Das hat der Hauptentwickler von Lift, David Pollak, exemplarisch gezeigt. (siehe dazu [Pol, Kapitel 12 und 13]) 61 Vgl. [Per11, S. 7 f.] 30
  • 40. 2.4 Lift Web-Framework Abb. 2.5: Kontrollfluss im View-First-Ansatz von Lift aus [Per11] das Java Web-Framework Wicket62 inspiriert. In Lift wird ein View daher in Form von XML-Dokumenten beschrieben, die bestenfalls ausschließlich Standard XHTML Tags enthalten. Snippets sind das wichtigste Konzept von Lift. Als Snippet wird eine Funktion bezeichnet, die XML-Knoten transformiert.63 Snippets sind das ViewModel im View-First-Ansatz und sorgen für die Generierung von dynamischen Seiteninhalten. Dabei verbinden sie den View mit dem Model, das die Fachentitäten der Anwendung darstellt. Dabei kann ein View durchaus mehrere Snippets nutzen. Im Gegensatz zum View können Snippets zustandsbehaftet sein. Auch wenn das Snippet in der Abbildung 2.5 wie ein Controller gemäß dem MVC-Muster aussieht, ist es das nicht. Ein Snippet übernimmt nicht die Steuerung des Kontrollflusses. Außerdem baut das Lift Framework auf der Java EE Plattform auf. Über die Servlet Technologie integriert sich Lift in Java EE Webcontainer, was unteranderem in Abbildung 2.6 dargestellt wird. Wie eine JSF-Anwendung werden Lift-Anwendungen in Form von WAR-Dateien bereitgestellt. 62 siehe http://wicket.apache.org 63 In der Arbeit werden teilweise auch die Klassen als Snippet bezeichnet, die eine solche Funktion enthalten. 31
  • 41. 2.4 Lift Web-Framework Abb. 2.6: Architektur von Lift aus [DCB11] Lift implementiert mehrere Persistenzlösungen. Die Standard-Persistenzlösung nennt sich Mapper. Die Mapper Bibliothek implementiert unter Nutzung des Active Record Patterns die Abbildung von Objekten in einer relationalen Datenbank. Beim Active Record Pattern befindet sich die Logik für den Datenbankzugriff im Domänenobjekt. Außerdem repräsentiert ein Domänenobjekt bei Active Record einen Datenbankeintrag.64 Gleichzeitig ist Mapper, wie es der Name bereits andeutet, ein objektrelationaler Mapper. Die Doppeldeutigkeit von Mapper als Umsetzung des Active Record Patterns und objektrelationaler Mapper ist auf die Art und Weise der Implementierung zurückzuführen. Lift Mapper Funktionalitäten werden mit Traits in die Domänenobjekte eingemixt. Dadurch ist die Logik für den Datenbankzugriff zwar in den Domänenobjekten, aber implementiert wird sie separiert in den Mapper 64 Vgl. [Fow03, S. 160 f.] 32
  • 42. 2.4 Lift Web-Framework Traits. Intern nutzt Mapper die Java SE Datenbankschnittstelle JDBC (Java Database Connectivity).65 Zusätzlich bietet Lift eine Abstraktionsschicht für Ajax und JavaScript, wodurch JavaScript-Befehle und Ajax Aufrufe in reinem Scala-Code formuliert werden können. Dabei wird intern die JavaScript-Bibliothek JQuery66 eingesetzt. Alternativ kann YUI67 verwendet werden. 65 Vgl. [Per11, S. 13] 66 siehe http://jquery.com 67 siehe http://developer.yahoo.com/yui 33
  • 43. 3 Methodik der Evaluation 3.1 Beschreibung der Evaluation Für die Evaluation der beiden Technologiestacks werden folgende zwei Methoden eingesetzt: • Literaturstudium • Umsetzung einer prototypischen Beispielanwendung Durch das Literaturstudium wird der Blick in die Interna der jeweiligen Frameworks ermöglicht. Dieser wäre ohne ein solches Studium nicht möglich. Die alleinige Im- plementierung einer prototypischen Anwendung führt zwar zur Auseinandersetzung mit der API der jeweiligen Technologie. Jedoch sind dadurch nicht zwangsläufig die internen Mechanismen geklärt. Mögliche Stärken und Schwächen, die sich nicht durch die Nutzung der API zeigen, würden somit auch nicht in die Evaluation einfließen. Die Ergebnisse aus dem Literaturstudium werden beim Vergleich der beiden imple- mentierten Lösungen eingebracht. Die wichtigste Grundlage für die Evaluation ist die Entwicklung einer prototypischen Beispielanwendung. Für jeden Technologiestack wird ein Prototyp für die im Abschnitt 4.1.2 formulierten Anwendungsfälle entwickelt. Der Fokus liegt dabei auf dem Einsatz der jeweiligen Frameworkspezifika und nicht auf der bestmöglichen Umsetzung der Anforderungen. Die implementierten Prototypen sind nicht für den produktiven Einsatz vorgesehen. 34
  • 44. 3.2 Evaluationskriterien 3.2 Evaluationskriterien Die Evaluation wird anhand von Evaluationskriterien durchgeführt, um das Ergebnis möglichst objektiv und für den Leser transparent zu gestalten. Die Auswahl der Evaluationskriterien für diese Arbeit orientiert sich an gängigen Standards und Erkenntnissen der Softwareentwicklung sowie den Erfahrungswerten des Autors. Dabei spielen ebenso einfache Faktoren wie die reine Funktionalität eine Rolle als auch Faktoren, die die Struktur und den Aufbau des Programmcodes betreffen. 3.2.1 Allgemeines Beim Vergleich von Technologien und Frameworks gibt es allgemeingültige Kriterien wie z.B. die Integration in die Entwicklungswerkzeuge, die bei jedem Vergleich anwendbar sind. Dokumentation Beschäftigt sich ein Entwickler mit Technologien, so wird eine gute Dokumentation erwartet. Die Dokumentation sollte dabei eine Spezifikation der API enthalten, als auch beschreibende Anleitungen zu Anwendungsfällen. Ebenso zählt zur Doku- mentation das Vorhandensein von Büchern zur Einführung und Vertiefung in die Technologie. Im Verlauf der Entwicklung der Prototypen hat sich gezeigt, dass es sehr wohl Unter- schiede in der Qualität und Quantität der Dokumentationsmaterialien gibt. Daher wird bei diesem Kriterium die Dokumentation der Technologiestacks beurteilt. Lernkurve Eignen sich Softwareentwickler Kenntnisse über neue Sprachen und Frameworks an, gibt es eine so genannte Lernkurve. Unter der Lernkurve wird der nötige 35
  • 45. 3.2 Evaluationskriterien Lernaufwand verstanden, der zum Erreichen eines bestimmten Ergebnisses nötig ist. Der Autor hat Java EE im November 2010 kennengelernt. Für diese Arbeit hat er Scala und Lift gelernt. Daher sind die Ergebnisse zur Lernkurve reine Erfahrungs- werte, die einen Eindruck vermitteln sollen, in welchem Verhältnis die Lernaufwände für die beiden Technologiestacks stehen. Toolchain Die Toolchain bezeichnet umgangssprachlich die Werkzeugkiste eines jeden Soft- wareentwicklers. Damit sind die Programme gemeint, die der Entwickler für seine Arbeiten einsetzt. Im heutigen Entwicklungsgeschäft ist es wichtig, dass sich die eingesetzen Techniken reibungslos in die Toolchain integrieren lassen. Dies steigert die Produktivität und ist somit von großer Bedeutung. Es gilt bei der Toolchain zu untersuchen, in welchem Maße sich die jeweiligen Frameworks in die eingesetzten Programme integrieren lassen und welche Vor- und Nachteile durch diese Integration entstehen. 3.2.2 Funktionalität Bei der Entwicklung von Web-Anwendungen treten oft ähnliche Anforderungen an die verwendeten Frameworks und Technologien auf. Daher werden die beiden entwickelten Lösungen auf die Unterstützung der im folgenden Abschnitt beschrie- benen Funktionalitäten untersucht und bewertet. Die Auswahl dieser Kriterien wurde maßgeblich durch [Wan08] beeinflusst. Persistenzmechanismen Heutzutage kommt keine Web-Anwendung ohne einen entsprechenden Persistenz- mechanismus aus. Die Daten der Anwendung und des Nutzers müssen für die Dauer einer Sitzung und über die Laufzeit der Anwendung hinweg gespeichert werden. 36
  • 46. 3.2 Evaluationskriterien Es wird untersucht, welche Persistenztechnologien die Frameworks unterstützen und gezeigt, wie der so genannte objektrelationale Mismatch gelöst wird. Aufgrund der Verschiedenheit Daten objektorientiert und relational abzubilden, gibt es bei der Persistierung eines objektorientierten Domänenmodells in eine releationale Datenbank eine Unverträglichkeit; einen Mismatch, den es zu lösen gilt.1 Weiterhin wird die Umsetzung in den jeweiligen Lösungen aufgrund der Integration in das bestehende Domänenmodell und der Funktionalität bewertet. Darstellungskonzept Jede Anwendung stellt die Daten für den Nutzer auf dem Bildschirm in irgend- einer Form dar. Frameworks bieten unterschiedliche Konzepte, wie diese Ansicht aufzubauen und mit dem Rest der Anwendung zu verbinden ist. Hier gilt es zu untersuchen, wie naht- und reibungslos sich die unterschiedlichen Dar- stellungskonzepte mit den anderen Anwendungsteilen verbinden lassen. Ebenfalls wird aufgezeigt, welche Vor- und Nachteile die unterschiedlichen Ansätze bieten. Ajax-Unterstützung In den letzten Jahren hat sich Ajax als Technologie für hochgradig interaktive Anwendungen durchgesetzt. Dabei werden Inhalte vom Server asynchron in Form von XML durch den Client nachgeladen. Dies geschieht für den Nutzer transparent im Hintergrund. Ein Neuladen der Seite ist nicht erforderlich. Die eingesetzten Frameworks werden daraufhin untersucht und bewertet, inwiefern Ajax unterstützt wird und welche Qualität die Ajax-Integration aufweist. Validierung Die Validierung von Nutzereingaben ist in jeder Anwendung wichtig. Die Eingaben müssen auf bewusst falsche Angaben und fachliche Inkonsistenzen geprüft werden. 1 Vgl. [Röd10, Kapitel 1] 37
  • 47. 3.2 Evaluationskriterien Für die Validierung wird bewertet, wie sich die formulierten Validierungsregeln in das Domänenmodell einpflegen lassen, welche Möglichkeiten zur Validierung durch das Framework bereits angeboten werden und wie sich die Validierung in die anderen Frameworkteile integriert. Internationalisierung Web-Anwendungen werden nicht ausschließlich in der Muttersprache des Kunden ausgeliefert. Da diese Anwendungen in den meisten Fällen von Nutzern unterschied- licher Sprachen genutzt werden, sind die Beschriftungen und Texte so zu gestalten, dass sie dynamisch ladbar sind. Abhängig von der Spracheinstellung des Nutzers wird die Anwendung in einer anderen Sprache dargestellt. Es gilt zu untersuchen, welche Mechanismen die Technologiestacks für diese Form der Internationalisierung von Anwendungen zur Verfügung stellen und wie sich diese in die Anwendung integrieren. 3.2.3 Architektur Laut [Bal01] kann Softwarearchitektur als „eine strukturierte oder hierarchische Anordnung der Systemkomponenten sowie Beschreibung ihrer Beziehungen“ defi- niert werden. Dem zugrundeliegend werden die beiden Technologiestacks aufgrund architekturspezifischer Funktionalitäten bewertet. Dabei wird bewertet, welche Funktionen existieren, um Enterprise-Anwendungen strukturiert und lose gekoppelt zu entwickeln. Lose Kopplung Bei der Komplexität heutiger Anwendungen ist es von großer Bedeutung, Objekt- netze flexibel aufzubauen. Dabei steht die lose Kopplung einzelner Komponenten und einfache Konfiguration dieser im Vordergrund. Unteranderem soll dadurch die Testbarkeit eines Systems verbessert werden. 38
  • 48. 3.2 Evaluationskriterien Es gilt zu untersuchen, welche Möglichkeiten und Funktionalitäten die Frameworks für die lose Kopplung eines Anwendungssystems anbieten. Cross Cutting Concerns In Softwaresystemen gibt es so genannte Querschnittsbelange (engl. Cross Cutting Concerns), die mit herkömmlicher objektorientierter Programmierung ohne Verlet- zung des DRY-Prinzips nicht umsetzbar sind.2 Querschnittsbelange werden auch orthogonale Belange genannt. Dies sind z.B. Funktionalitäten wie Tracing,3 Trans- aktionssteuerung oder Exception Handling. Solche Funktionen sind in irgendeiner Form in jeder Anwendungsschicht vorhanden. Sie befinden sich orthogonal zu den Anwendungsschichten. So finden sich z.B. in vielen Methoden eines Anwendungs- systems Programmzeilen, die für das Tracing verantwortlich sind. Dadurch wird Code mit gleicher Funktionalität regelmäßig in den einzelnen Methoden dupliziert. Dies widerspricht dem DRY-Prinzip. Dieses besagt „Don’t Repeat Yourself“ und ist ein Grundprinzip guter Softwareentwicklunng. Es wird untersucht, ob es Möglichkeiten gibt, diese Querschnittsbelange separat vom Anwendungscode zu formulieren. Wenn dies nicht möglich ist, wird diskutiert, welche anderen Arten der Implementierung existieren und wie gehaltvoll diese sind. 2 Vgl. [Wol10, S. 100 f.] 3 Tracing bezeichnet das detaillierte Loggen von Methoden. In den allermeisten Fällen wird dabei der Methodeneintritt mit den übergebenen Parameter sowie der Austritt geloggt. 39
  • 49. 4 Entwicklung der Beispielanwendung 4.1 Entwurf der Anwendung Für den Vergleich des Scala/Lift Technologiestacks mit dem Java EE Programmier- modell wird eine prototypische Raumverwaltungssoftware entwickelt. Der Nutzer ist mit dieser Software in der Lage, Gebäude mit Räumen zu verwalten. Dabei gilt die Vorgabe, dass für die Verwaltung der Gebäude und Räume so wenige Seiten wie möglich aufzurufen sind. Bestenfalls existiert eine Seite pro Anwendungsfall. 4.1.1 Domänenmodell Das Domänenmodell einer Anwendung beschreibt die fachlichen Entitäten einer Problemlösung und die Beziehungen dieser untereinander. Bei der zu entwickeln- den Raumverwaltungsanwendung besteht das Domänenmodell aus vier Entitäten: Gebäuden, Räumen, Ausstattungen der Räume und Ausstattungsmerkmalen. Die Abbildung 4.1 zeigt das Domänenmodell der Beispielanwendung. Zusätzlich existie- ren Regeln für die zulässigen Werte einiger Attribute. Sämtliche Bezeichnungen dürfen nicht leer sein. Das heißt, die Zeichenketten müssen mindestens ein Zeichen enthalten und Null ist ebenfalls nicht als Wert zulässig. Des Weiteren sind sämtliche Zahlen als positive ganze Zahlen abzubilden, Primärschlüssel ausgeschlossen. 40
  • 50. 4.1 Entwurf der Anwendung Abb. 4.1: Domänenmodell der Beispielanwendung 41
  • 51. 4.1 Entwurf der Anwendung 4.1.2 Anwendungsfälle Ein Anwendungsfall beschreibt ein mögliches Szenario für die Nutzung eines An- wendungssystems. Die Beispielanwendung behandelt drei Anwendungsfälle: die Verwaltung von Gebäuden, die Suche nach Räumen und das Verwalten von Aus- stattungsmerkmalen. Gebäude verwalten Der Hauptanwendungsfall ist das Verwalten von Gebäuden. Dabei soll der Nutzer neue Gebäude anlegen, Veränderungen an Gebäudedaten speichern und existierende Gebäude löschen können. Dies gilt natürlich ebenfalls für die Räume der Gebäude und Ausstattungen der Räume. Räume suchen Der Nutzer soll die Möglichkeit haben, nach Räumen mit einem bestimmten Ausstattungsmerkmal zu suchen. Dabei kann der Benutzer die Wahl treffen zwischen allen vorhandenen Ausstattungsmerkmalen. Ausstattungsmerkmale verwalten Ein Raum kann mehrere Raumaustattungen besitzen. Eine Raumaustattung ist dabei die Zuordnung eines Ausstattungsmerkmals mit einer Menge zu einem Raum. Diese Ausstattungsmerkmale soll der Nutzer ebenfalls verwalten können. Dabei gilt die Vorgabe, dass Ausstattungsmerkmale nur gelöscht werden dürfen, wenn diese bei keinem Raum in einer Raumausstattung verwendet werden. Andernfalls würden bestehende Daten fehlerhaft. Das Hinzufügen und Verändern bestehender Ausstattungsmerkmale soll ebenso möglich sein. 42
  • 52. 4.2 Umsetzung mit Java EE 4.2 Umsetzung mit Java EE Die Java EE Implementierung der Beispielanwendung setzt JSF 1.2 mit Facelets als View-Technologie ein. Für die Persistenzschicht wird JPA 2.0 mit Hibernate als JPA Provider verwendet. 4.2.1 Domänenmodell Das Domänenmodell wird im Paket de.htw.berlin.jroomyweb.domain entwickelt. Dabei wird für jede fachliche Entität eine Klasse implementiert. Ein Gebäude wird also durch die Klasse Gebaeude repräsentiert, wie das folgende Listing zeigt. § Listing 4.1: JPA Grundgerüst der Java Gebäude Fachklasse ¤ @Entity public c l a s s Gebaeude implements S e r i a l i z a b l e { @Id @GeneratedValue private Long i d ; protected Gebaeude ( ) { // f ü r JPA } public Long g e t I d ( ) { return i d ; } public void s e t I d ( Long i d ) { this . id = id ; } } ¦ ¥ 43
  • 53. 4.2 Umsetzung mit Java EE Da die Objekte der Domänenschicht mittels JPA in einer relationalen Datenbank persistiert werden, hat jede Fachklasse die Entity-Annotation. Diese Annotation kennzeichnet für JPA eine Klasse, die auf eine Datenbank abzubilden ist. Weiterhin fällt auf, dass Gebaeude das Interface Serializable implementiert. Das Serializable Interface kennzeichnet Klassen, die serialisierbar sind. Damit ist das Abbilden eines Objektes der Klasse auf einen Bytestrom oder anderes Übetragungsformat (z.B. XML) gemeint. Für die reine Persistierung über JPA ist das nicht notwendig. Jedoch ist es eine Best-Practice, im Java EE Kontext die JPA Fachklassen serialisierbar zu machen. Sollte die Anwendung in einem verteilten System eingesetzt werden, kann es vorkommen, dass Objekte der Domänenschicht zwischen verschiedenen Servern hin- und hergeschickt werden. Dafür müssen die Objekte serialisiert werden. Das Speichern von Domänenobjekten in der HTTP Session eines Nutzers kann ebenfalls das Serialisieren für die Zwischenspeicherung auf der Festplatte des Application Servers zur Folge haben. Alle Domänenobjekte werden mit einer eindeutigen Identifikationsnummer gespei- chert. Diese entspricht dem Primärschlüssel in der Datenbank. Daher hat die Gebaeude Fachklasse ein id Attribut. Dieses ist mit einer Id-Annotation versehen, die den Primärschlüssel der Objekte für die Abbildung in der Datenbank kennzeich- net. Außerdem wird mit der GeneratedValue-Annotation festgelegt, dass der Wert von id automatisch durch JPA generiert wird. In den meisten Konfigurationen be- wirkt dies das Anlegen einer automatisch hochzählenden Datenbankspalte.1 Damit ein JPA Provider auf das id Attribut von Gebaeude zugreifen kann, muss ein so genanntes Getter-Setter-Methodenpaar implementiert werden. Diese Vorgabe der Getter-Setter-Zugriffsmethoden gilt für alle Attribute, die durch JPA persistiert werden. Die Verwendung von JPA in der Gebaeude Klasse verlangt des Weiteren die Imple- mentierung eines Konstruktors mit einer leeren Parameterliste. Das ist notwendig, da ein JPA Provider Objekte von Gebaeude über die Java Reflections API erzeugt, indem dieser leere Konstruktor aufgerufen wird, und die Gebaeude Objekte z.B. anschließend über die Setter-Methoden mit den Daten aus der Datenbank befüllt. 1 Oftmals wird dafür der Terminus AUTO_INCREMENT verwenden. 44
  • 54. 4.2 Umsetzung mit Java EE Da die Gebaeude Klasse einen Konstruktor mit einer nicht leeren Parameterliste hat, der den Default-Konstruktor von Java überdeckt, musste dieser leere Konstruktor zusätzlich fomuliert werden.2 Um zu verhindern, dass ein Gebaeude Objekt uner- laubter Wise im Programmcode über diesen leeren Konstruktor erzeugt wird, hat er die Sichtbarkeit protected und ist damit nur im Paket der Fachklassen sichtbar. Alle Attribute von Gebaeude werden durch die Nutzung von JPA automatisch in der Datenbank abgebildet.3 So auch die vier String-Attribute der Gebäude Entität aus dem Domänenmodell, wie das folgende Listing zeigt. Nicht abgebildet, sind die obligatorischen Getter- und Setter-Methoden. § Listing 4.2: String Attribute der Gebäude Klasse ¤ @NotEmpty ( message= " Der Name e i n e s Gebäudes d a r f n i c h t l e e r s e i n . " ) private S t r i n g b e z e i c h n u n g ; private S t r i n g s t r a s s e ; private S t r i n g p l z ; private S t r i n g o r t ; ¦ ¥ Das Domänenmodell verlangt, dass sämtliche Bezeichnungen nicht leer sein dürfen. Daher wurde das Attribut bezeichnung mit NotEmpty annotiert. Die NotEm- pty-Annotation ist eine Erweiterung des Bean Validation Standards und steht durch die Nutzung der Hibernate Validator Bibliothek zur Verfügung. Durch die Annotation wird festgelegt, dass bezeichnung weder den Wert Null noch eine Zei- chenkette einer Länge kleiner 1 aufnehmen kann. Mit dem message Attribut der NotEmpty-Annotation wird die Fehlernachricht angegeben, die bei Verletzung der Validierungsregel ausgegeben wird. Die Fehlernachrichten von Bean-Validation-Annotationen sind zusätzlich über Ressourcendateien lokalisierbar. Dazu muss mindestens eine ValidationMessa- ges.properties Datei im Klassenpfad abgelegt werden, die in Schlüssel-Wert-Paaren 2 Der Konstruktor mit der nicht leeren Parameterliste ist in dem Listing aus Gründen der Übersicht nicht dargestellt ist. 3 Sollen einzelne Attribute nicht persistiert werden, sind diese mit @Transient zu annotieren. 45
  • 55. 4.2 Umsetzung mit Java EE Variablen und ihren Wert enthält. Mit dem Ausdruck {Variablenbezeichner} kann ein Wert im message Attribut einer Bean-Validation-Annotation geladen werden. Über Länder- und Sprachkürzel als Suffix des Dateinamen können einzelne Valida- tionMessages_xx_XX.properties Dateien für bestimmte Sprachen definiert werden. Das wurde im Prototypen jedoch nicht implementiert. Die 1-n Beziehung zwischen Gebäuden und Räumen wird in der Gebaeude Klasse durch ein Set implementiert. Ein Raum wird in der Java EE Lösung durch die gleichnamige Klasse Raum repräsentiert. § Listing 4.3: Implementierung der Beziehung zwischen Räumen und Gebäuden ¤ @OneToMany( c a s c a d e=CascadeType . ALL, mappedBy=" gebaeude " ) private Set<Raum> raeume = new HashSet<Raum>() ; ¦ ¥ Durch das Annotieren des raeume Sets mit OneToMany wird die Art der Beziehung definiert. Die zwei Attribute, cascade und mappedBy, konfigurieren diese Beziehung. Über das cascade Attribut der OneToMany-Annotation werden kaskadierende Operationen eingestellt. Das heißt, ist das umgebene Gebaeude Objekt durch eine JPA Operation, wie z.B. das Speichern oder Löschen in der Datenbank, betroffen, wird diese Operation auf alle Raum Objekte in raeume angewendet. In diesem Fall werden durch die Angabe von CascadeType.ALL alle Operationen kaskadierend auf das Set raeume angewendet. Das zweite Attribut, mappedBy, betrifft die Abbildung der Beziehung in der Datenbank. Darüber wird definiert, dass die Beziehung in der Datenbank durch die Spalte des gebaeude Attributs der Raum Klasse abgebildet wird. Dies entspricht der Speicherung eines Fremdschlüssels in der Raum Tabelle auf die ID Spalte der Gebäude Tabelle. Damit diese Konfiguration über mappedBy funktioniert, wird das gebaeude Attribut der Raum Klasse mit ManyToOne annotiert. § Listing 4.4: gebaeude Attribut in der Java Raum Fachklasse ¤ @ManyToOne( o p t i o n a l=f a l s e ) private Gebaeude gebaeude ; ¦ ¥ 46
  • 56. 4.2 Umsetzung mit Java EE Das Setzen des optional Attributs auf den Wert false, bewirkt das Generieren eines NotNull Constraints für die gebaeude Spalte in der Datenbank. Ein Raum kann demnach nicht ohne ein dazugehöriges Gebäude existieren. Neben der Beziehung zu einem Gebäude hat ein Raum mehrere Attribute, wie im folgenden Listing exemplarisch anhand der Fensteranzahl gezeigt wird. § Listing 4.5: Anzahl der Fenster eines Raumes ¤ @Min( v a l u e =1, message= " Die Anzahl d e r F e n s t e r kann n i c h t k l e i n e r 0 s e i n . " ) private int a n z a h l F e n s t e r ; ¦ ¥ In der Beschreibung des Domänenmodells wurde festgelegt, dass sämtliche Zahlen als positive Ganzzahlen abzubilden sind. Dies wird durch die Validierungsregel der Min-Annotation umgesetzt. Durch das value Attribut wird der kleinste zulässige Wert von anzahlFenster festgelegt. Die Min-Annotation ist eine Annotation des Bean Validation Standards. Wie bereits die 1-n Beziehung zwischen Gebäuden und Räumen wird auch die Beziehung zwischen einem Raum und mehreren Raumausstattungen über ein Set implementiert. Eine Raumausstattung wird durch die Klasse Ausstattung implementiert. § Listing 4.6: Raumausstattungen in der Raum Klasse ¤ @OneToMany( c a s c a d e=CascadeType . ALL, f e t c h=FetchType .EAGER, mappedBy=" raum " ) private Set<Ausstattung > a u s s t a t t u n g e n = new HashSet<Ausstattung >() ; ¦ ¥ Das fetch Attribut legt in diesem Fall fest, dass alle Raumausstattungen beim Laden eines Raumes aus der Datenbank sofort mitgeladen werden. Andernfalls geschieht dies verzögert (engl. lazy), was bei der Umsetzung des Prototypen zu Ladefehlern geführt hat. Die Implementierungen der Klassen Ausstattung und Merkmal, die das Ausstattungs- merkmal des Domänenmodells repräsentiert, verwenden keine neuen Annotation 47