Handbuch

Werbung
V 2.8
TLGen
Handbuch
EJB3 Code-Generator
Version 2.8 (Deutsch)
Autoren:
Titus Livius Rosu
([email protected])
Titus Rosu
([email protected])
Liviu Rosu
([email protected])
TLGen
1
StarData GmbH
V 2.8
Inhaltsverzeichnis
1.
Allgemeine Information ____________________________________________________ 9
1.1
Ziele______________________________________________________________________ 11
1.2
TLGen´s Architektur-Konzept __________________________________________________ 12
1.2.1
1.2.2
1.3
Code-Generierung mit Hilfe von TLGen __________________________________________ 14
1.3.1
1.3.2
2
Input für die Code-Generierung _______________________________________________________ 13
Verwendung von Callback-Klassen als Fachlogig Interfaces _________________________________ 14
Code-Generierung mit einem Domain-Modell (UML für neue Projekte) _______________________ 16
Generierung mit einer schon vorhandenen Datenbank (für Legacy Projekte) ___________________ 17
TLGen Code-Generierung und die Datenbankanalyse ____________________________ 19
2.1
Analyse des Domainmodells und der Datenbank __________________________________ 20
2.1.1 Verwendung von UML Parameter (Tags) für die Code-Generierung __________________________ 24
2.1.1.1
UML Parameter für Klassen ______________________________________________________ 24
2.1.1.2
UML Parameter für Attribute ____________________________________________________ 24
2.1.1.3
Was wird generiert ____________________________________________________________ 25
2.1.1.3.1 Relationen _________________________________________________________________ 25
2.1.1.3.1.1 Assoziation ____________________________________________________________ 26
2.1.1.3.1.2 Aggregation ____________________________________________________________ 31
2.1.1.3.1.3 Komposition ___________________________________________________________ 35
2.1.1.3.2 Berechnete Relationen überschreiben __________________________________________ 40
3
Beschreibung der generierten Komponenten (Java Klassen) ______________________ 41
3.1
Daten Klassen - Interfaces ____________________________________________________ 41
3.1.1
3.1.2
3.2
Generierung von „JSon“-Klassen für REST calls ___________________________________________ 42
Generierung von Mapping-Klassen zwischen Daten- und JSon-Klassen ________________________ 43
Session Bean _______________________________________________________________ 46
3.2.1 Interfaces für eine Session Bean ______________________________________________________ 48
3.2.2 XML Persistente Datei ______________________________________________________________ 49
3.2.3 Interface-Klassen zu Fachlogik(Bussiness logic)-Komponenten ______________________________ 50
3.2.4 Interceptors_______________________________________________________________________ 50
3.2.5 Generierung der REST-Schnittstelle ____________________________________________________ 51
3.2.5.1
Client-Seite ___________________________________________________________________ 53
3.3
Clients, BCI (Business Common Interface)________________________________________ 54
3.3.1 Test-Klassen ______________________________________________________________________ 55
3.3.1.1
Attribute für <Test> Tag Annotation _______________________________________________ 56
Test-Klasse Name mit vollem path ______________________________________________ 57
3.3.1.2
3.3.1.3
3.4
3.4.1
3.4.2
TLGen
Verwendung von Test-Daten aus externen Dateien __________________________________ 57
“Junit” Test-Klasse für “REST”-calls ________________________________________________ 58
Entity Manager-Klasse _______________________________________________________ 58
Methoden im Entity-Manager ________________________________________________________ 61
Entity Manager-Interfaces ___________________________________________________________ 63
2
StarData GmbH
V 2.8
3.5
Entity Beans _______________________________________________________________ 64
3.5.1 Relationen in Entity Beans ___________________________________________________________ 68
3.5.1.1
Relation „OneToMany“ _________________________________________________________ 68
3.5.1.2
Relation „ManyToOne“ _________________________________________________________ 70
3.5.1.3
Relation „OneToOne“ __________________________________________________________ 70
3.5.1.4
Relation „ManyToMany“ ________________________________________________________ 71
3.5.2 Meta-Klassen (für Criteria) ___________________________________________________________ 74
3.6
„Message Driven“ Bean ______________________________________________________ 74
3.7
Services ___________________________________________________________________ 75
3.7.1
3.7.2
3.8
„Timer Service“ ____________________________________________________________________ 75
„Web Services“ ____________________________________________________________________ 77
Callback-Klasse _____________________________________________________________ 78
3.8.1
Free Klassen ______________________________________________________________________ 79
3.9
Generierung von Datenbank und SQL Skripte_____________________________________ 80
3.10
Regel für die Namengenerierung _______________________________________________ 82
3.11
Log Dateien - Beschreibung ___________________________________________________ 83
3.12
Verwendung von Kommentarien bei generiertem Code ____________________________ 84
3.12.1
3.12.2
4
Kommentarien für Klassen _________________________________________________________ 84
Kommentarien für Methoden ______________________________________________________ 85
Verwendung von TLGen (Beschreibung der Konfigurationsdatei) __________________ 86
4.1
Was wird generiert __________________________________________________________ 86
4.2
Wie wird Code generiert? ____________________________________________________ 86
4.3
Ordnerstruktur für den generierten Code ________________________________________ 86
4.4
Default Konfigurationsdatei __________________________________________________ 88
4.4.1 Default Konfigurationsdatei - Struktur __________________________________________________ 88
4.4.2 Default Konfigurationsdatei - Beschreibung _____________________________________________ 90
4.4.2.1
<Standard> Tag _______________________________________________________________ 90
4.4.2.2
<Project> Tag _________________________________________________________________ 90
4.4.2.3
<Locator> Tag _________________________________________________________________ 90
4.4.2.4
<Class> Tag ___________________________________________________________________ 91
4.4.2.5
<Entity> Tag __________________________________________________________________ 91
4.4.2.6
<Mapping> Tag _______________________________________________________________ 92
4.4.2.7
<Criteria> Tag _________________________________________________________________ 92
4.4.2.8
<JSon> Tag ___________________________________________________________________ 92
4.4.2.9
<Manager> Tag _______________________________________________________________ 93
4.4.2.9.1 Fields für Entity Manager _____________________________________________________ 93
4.4.2.9.2 Methoden für Entity Manager _________________________________________________ 93
4.4.2.10 <Session> Tag _________________________________________________________________ 94
4.4.2.10.1 Methoden in Session Bean ___________________________________________________ 95
4.4.2.10.2 <Client> Tag ______________________________________________________________ 95
4.4.2.10.3 <Xml-persistence> Tag ______________________________________________________ 96
4.4.2.10.4 <Interceptor> Tag __________________________________________________________ 96
4.4.2.11 <Message Driven> Tag __________________________________________________________ 96
4.4.2.12 <UmlControl> Tag _____________________________________________________________ 96
TLGen
3
StarData GmbH
V 2.8
4.4.2.13
4.4.2.14
4.5
<Method> tag _______________________________________________________________ 100
<Variable> Tag _______________________________________________________________ 100
Projekt Konfigurationsdatei __________________________________________________ 100
4.5.1 Projekt Konfigurationsdatei - Struktur _________________________________________________ 101
4.5.2 Projekt Konfigurationsdatei - Beschreibung ____________________________________________ 102
4.5.2.1
<Generator> Tag _____________________________________________________________ 102
4.5.2.1.1 Regel für Namen-Transformation in Klassen, Methoden und Tabellen ________________ 103
4.5.2.2
<Project> Tag ________________________________________________________________ 104
4.5.2.3
<Locator> Tag ________________________________________________________________ 109
4.5.2.4
<Design> Tag ________________________________________________________________ 109
4.5.2.4.1 Regel für package Generierung _______________________________________________ 109
4.5.2.4.2 <Commentary> Tag ________________________________________________________ 109
4.5.2.4.3 <Class> Tag _______________________________________________________________ 110
4.5.2.4.4 <Entity> Tag ______________________________________________________________ 110
4.5.2.4.5 <Manager> Tag ____________________________________________________________ 111
4.5.2.4.5.1 Feldern (Variable) für Entity Manager ______________________________________ 111
4.5.2.4.5.2 Methoden für Entity Manager ____________________________________________ 111
4.5.2.4.5.2.1 Entity Menager Methoden Typ 6 ______________________________________ 112
4.5.2.4.5.2.2 Entity Menager Methoden Typ 7 ______________________________________ 113
4.5.2.4.5.2.3 Entity Menager Methoden Typ 8 ______________________________________ 114
4.5.2.4.5.2.4 Entity Menager Methoden Typ 9 ______________________________________ 117
4.5.2.4.5.2.5 Entity Menager Methoden Typ 10 _____________________________________ 118
4.5.2.4.5.2.6 Entity Menager Methoden Typ 11 _____________________________________ 118
4.5.2.4.5.3 Manager Interfaces _____________________________________________________ 118
4.5.2.4.6 <Session> Tag _____________________________________________________________ 118
4.5.2.4.6.1 Methoden für Session Bean ______________________________________________ 119
4.5.2.4.6.2 <Client> tag ___________________________________________________________ 119
4.5.2.4.6.3 <Xml-persistence> Tag __________________________________________________ 121
4.5.2.4.6.4 < Timerservice> Tag ____________________________________________________ 121
4.5.2.4.6.5 < Web Service> Tag _____________________________________________________ 122
4.5.2.4.6.6 <Interceptor> Tag ______________________________________________________ 123
4.5.2.4.6.7 <Freeclass> Tag ________________________________________________________ 123
4.5.2.4.6.8 <Callback> Tag ________________________________________________________ 123
4.5.2.4.7 < Message Driven> Tag _____________________________________________________ 124
4.5.2.4.7.1 <Client> Tag für Message Driven Bean _____________________________________ 124
4.5.2.4.7.2 <Bean> Tag für Message Driven Bean ______________________________________ 124
4.5.2.4.7.3 <Callback> Tag für Message-Driven Bean ___________________________________ 125
4.5.2.4.8 <Test> Tag ________________________________________________________________ 126
4.5.2.4.8.1 Generierung von Methoden für Test-Klassen ________________________________ 126
4.5.2.4.9 <Dbtable> Tag _____________________________________________________________ 126
4.5.2.4.9.1 <Relation> Tag, Verwendung von Relationen ________________________________ 126
4.5.2.5
<Method> Tag _______________________________________________________________ 127
4.5.2.6
<Variable> Tag _______________________________________________________________ 128
5 Verwendung von TLGen bei Softwarentwicklung (Bedingungsanleitung) und das Beispiel
„Demo“-Beschreibung _______________________________________________________ 130
6
5.1
TLGen-Verwendung in einem neuen IT Projekt, „Demo“ Beispiel ____________________ 130
5.2
Verwendung von TLGen in ein Legacy IT Projekt, „Legacy“ - Beispiel _________________ 135
TLGen Installation _______________________________________________________ 136
TLGen
4
StarData GmbH
V 2.8
6.1
Verwendete Tools und Externe Programme _____________________________________ 137
6.2
Verwendung von „ant“ für die Generierung von Java Code _________________________ 138
6.3
Verwendung von „Maven“ für die Generierung von Java Code ______________________ 138
7
Beispiele von generiertem Code ____________________________________________ 140
7.1
Standard Konfigurationsdatei ________________________________________________ 140
7.2
Konfigurationsdatei ________________________________________________________ 144
7.3
SQL Skript ________________________________________________________________ 149
7.4
Klassen und Interfaces ______________________________________________________ 152
7.4.1
7.4.2
7.4.3
7.4.4
7.5
Data-Klassen _____________________________________________________________________ 152
Interface-Data ____________________________________________________________________ 154
JSon Data-Klasse __________________________________________________________________ 155
Mapping zwischen Data-Klassen und JSon Klasse ________________________________________ 156
Session Bean ______________________________________________________________ 158
7.5.1
7.5.2
7.5.3
7.5.4
7.6
Session Bean-Klassen ______________________________________________________________ 158
Session Bean Interface _____________________________________________________________ 166
Client Factory-Klasse _______________________________________________________________ 167
Session Bean REST Interface _________________________________________________________ 168
Entity Manager Bean _______________________________________________________ 168
7.6.1
7.6.2
Entity Manager Bean-Klasse _________________________________________________________ 168
Entity Manager Bean Interface ______________________________________________________ 174
7.7
Entity Bean _______________________________________________________________ 175
7.8
Interceptor-Klasse _________________________________________________________ 178
7.9
Timerservice-Klasse ________________________________________________________ 179
7.10
Web Service ______________________________________________________________ 180
7.11
REST-Klassen ______________________________________________________________ 181
7.11.1
7.11.2
7.12
Client Seite ____________________________________________________________________ 181
Server Seite ____________________________________________________________________ 186
Message Driven Bean _______________________________________________________ 187
8
Vergleich zwischen TLGen und andere Code-Generatoren _______________________ 190
9
Literaturhinweis ________________________________________________________ 192
10
Glossar ______________________________________________________________ 193
Abbildungsverzeichnis
Abbildung 1: IT Projekt Architektur________________________________________________________________ 10
Abbildung 2: TLGen Architektur __________________________________________________________________ 13
Abbildung 3: Callback Klassen-Diagramm __________________________________________________________ 14
Abbildung 4: Domain-Modell ____________________________________________________________________ 17
Abbildung 5: Database-Modell ___________________________________________________________________ 18
TLGen
5
StarData GmbH
V 2.8
Abbildung 6: TLGen-Generierungsprozess von einem Domain-Modell ____________________________________ 19
Abbildung 7: UML-Klassendiagramm I _____________________________________________________________ 21
Abbildung 8: UML-Klassendiagramm II ____________________________________________________________ 21
Abbildung 9: UML-Klassendiagramm III ____________________________________________________________ 22
Abbildung 10: UML-Klassendiagramm IV ___________________________________________________________ 22
Abbildung 11: UML-Relationen und die TLGen-Gernerierungsparameter _________________________________ 27
Abbildung 12: „OneToMany“-Darstellung im UML-Domainmodell ______________________________________ 69
Abbildung 13: „OneToMany“-Darstelung in der Datenbank ____________________________________________ 69
Abbildung 14: „ManyToMany“-Darstellung im UML-Domainmodell _____________________________________ 72
Abbildung 15: „ManToMany“ Darstellung in der Datenbank ___________________________________________ 72
Abbildung 16: Ordner-Struktur ___________________________________________________________________ 87
Tabellenverzeichnis
Tabelle 2: UML verwendete Attribute für die Generierung _____________________________________________ 25
Table 3: Java-Typen ____________________________________________________________________________ 41
Tabelle 4: Session Bean Annotationen _____________________________________________________________ 46
Tabelle 5: Attribute für <Test> Tag-Annotation ______________________________________________________ 57
Tabelle 6: Automatisch generierbare Default-Methoden im Entity Manager ______________________________ 59
Tabelle 7: Annotationen für Entity Manager-Klasse __________________________________________________ 61
Tabelle 8: Annotationen für Entity Beans (EJB3) _____________________________________________________ 65
Tabelle 9: Annotationen für „Message Driven“ Bean _________________________________________________ 75
Tabelle 10: Namen-Regel _______________________________________________________________________ 82
Table 11: Attribute für den Generator Tag _________________________________________________________ 102
Tabelle 12: Attribute für den Projekt-Tag __________________________________________________________ 104
Table 13: Attribute- für den „ant“ <target> „genertor“ _______________________________________________ 138
Listingverzeichnis
Listing 1: Remote Connect-Klassen ________________________________________________________________ 19
Listing 2: Import Code __________________________________________________________________________ 20
Listing 3: Code für Variable mit vollem Path ________________________________________________________ 20
Listing 4: “OneToOne” Assoziation ________________________________________________________________ 27
Listing 5: “OneToMany” Assoziation - One__________________________________________________________ 28
Listing 6: “OneToMany” Assoziation - Many ________________________________________________________ 29
Listing 7: „ManyToMany“ Assoziation - Many _______________________________________________________ 29
Listing 8: “ManyToMany” Assoziation - Many 1 _____________________________________________________ 30
Listing 9: “ManyToMany” Assoziation - Many 2 _____________________________________________________ 31
Listing 10: “OneToOne” Aggregation ______________________________________________________________ 32
Listing 11: “OneToMany” Aggregation - One ________________________________________________________ 33
Listing 12: “OneToMany” Aggregation - Many ______________________________________________________ 33
Listing 13: „ManyToMany“ Aggregation - Many _____________________________________________________ 34
Listing 14: “ManyToMany” Aggregation - Many 1 ___________________________________________________ 34
Listing 15: “ManyToMany” Aggregation - Many 2 ___________________________________________________ 35
Listing 16: “OneToOne” Komposition ______________________________________________________________ 37
Listing 17: “OneToMany” Komposition - One________________________________________________________ 37
Listing 18: “OneToMany” Komposition - Many ______________________________________________________ 38
Listing 19: “ManyToOne” Komposition - Many ______________________________________________________ 38
TLGen
6
StarData GmbH
V 2.8
Listing 20: “ManyToMany” Komposition - Many 1 ___________________________________________________ 39
Listing 21: “ManyToMany” Komposition - Many 2 ___________________________________________________ 39
Listing 22: Listen ______________________________________________________________________________ 42
Listing 23: Klassen _____________________________________________________________________________ 42
Listing 24: „JSon“ Data-Klasse ___________________________________________________________________ 43
Listing 25: Mapping zwischen einer Data-Klasse und einer„JSon“ Data-Klasse _____________________________ 45
Listing 26: Session Bean ________________________________________________________________________ 48
Listing 27: Session Bean Interface_________________________________________________________________ 49
Listing 28: Persisitence XML _____________________________________________________________________ 49
Listing 29: Interceptor __________________________________________________________________________ 51
Listing 30: REST-Methode in der Konfigurationsdatei _________________________________________________ 52
Listing 31: REST Methode Parameter ______________________________________________________________ 52
Listing 32: REST-Annotations und Parameter in der Konfigurationsdatei __________________________________ 53
Listing 33: REST Beispiel ________________________________________________________________________ 53
Listing 34: REST-calls vom Client __________________________________________________________________ 54
Listing 35: Server Remote Call____________________________________________________________________ 55
Listing 36: Client Class __________________________________________________________________________ 55
Listing 37: Client Interface ______________________________________________________________________ 55
Listing 38: Test-Klasse - Beispiel __________________________________________________________________ 56
Listing 39: Externe Test-Daten ___________________________________________________________________ 57
Listing 40: XML Schema für externe Test-Daten _____________________________________________________ 58
Listing 41: “Find by name” Method _______________________________________________________________ 60
Listing 42: “Find by Primary Key” Method __________________________________________________________ 61
Listing 43: SQL Named Beispiel ___________________________________________________________________ 62
Listing 44: SQL Native Beispiel ___________________________________________________________________ 63
Listing 45: Criteria Beispiel ______________________________________________________________________ 63
Listing 46: Entity Manager Interface Beispiel ________________________________________________________ 64
Listing 47: Entity Bean __________________________________________________________________________ 65
Listing 48: Entity Bean “call…” Helper Methods ______________________________________________________ 67
Listing 49: Entity Bean Sequence Generator ________________________________________________________ 67
Listing 50: Entity Bean (Mapping) ________________________________________________________________ 68
Listing 51: Entity Bean – “OneToMany” Interface ____________________________________________________ 68
Listing 52: ”OneToMany” - Entiy-Bean-Methode _____________________________________________________ 69
Listing 53: „ManyToOne“ Entity-Methode __________________________________________________________ 70
Listing 54: „OneToOne” Data-Interface ____________________________________________________________ 71
Listing 55: „OneToOne” Entity Bean _______________________________________________________________ 71
Listing 56: „ManyToMany“-Interface ______________________________________________________________ 71
Listing 57: „ManyToMany“-Relation in Entity Bean___________________________________________________ 73
Listing 58: Meta-Klasse - Beispiel _________________________________________________________________ 74
Listing 59: Beispiel eines „Timer Services“ __________________________________________________________ 77
Listing 60: „Web Service“-Klasse - Beispiel __________________________________________________________ 77
Listing 61: „Web Service”-Interface _______________________________________________________________ 78
Listing 62: Callback-Klasse - Beispiel_______________________________________________________________ 79
Listing 63: SQL Skript ___________________________________________________________________________ 81
Listing 64: Error Log Datei _______________________________________________________________________ 84
Listing 65: Kommentarien für Klasse ______________________________________________________________ 84
Listing 66: Kommentar vom <Design> Tag __________________________________________________________ 84
Listing 67: Kommentar vom UMD Domain-Modell ___________________________________________________ 85
Listing 68: Methoden Kommentar ________________________________________________________________ 85
Listing 69: Default Konfigurationsdatei ____________________________________________________________ 89
Listing 70: <Column> Tag _______________________________________________________________________ 97
TLGen
7
StarData GmbH
V 2.8
Listing 71: Default Values für <ColType> Tag, z.B. für Oracle ___________________________________________ 97
Listing 72: Default Values für <ColType> Tag, z.B. für MySQL ___________________________________________ 98
Listing 73: <NameChange> Tag __________________________________________________________________ 98
Listing 74: Konfigurationsdatei __________________________________________________________________ 102
Listing 75: „Java“ Code style ____________________________________________________________________ 107
Listing 76: „C“ Code style ______________________________________________________________________ 108
Listing 77: SQL Fields __________________________________________________________________________ 111
Listing 78: Methode Type „6“ in der Konfigurationsdatei _____________________________________________ 112
Listing 79: Methode Typ “6” in Entity Manager-Klasse _______________________________________________ 113
Listing 80: Methode Type “7” in der Konfigurationsdatei _____________________________________________ 113
Listing 81: Methode Type “7” Entity Manager-Klasse ________________________________________________ 114
Listing 82: Methode Typ “7” in der Entity-Klasse ____________________________________________________ 114
Listing 83: Methode Typ „8“ in der Konfigurationsdatei ______________________________________________ 114
Listing 84: Methode Typ „8“ in Entiy-Klasse ________________________________________________________ 116
Listing 85: Daten-Klasse für die Methode Typ „8“ ___________________________________________________ 117
Listing 86: Client Interface _____________________________________________________________________ 120
Listing 87: Factory Client Class __________________________________________________________________ 120
Listing 88: Client call‘s _________________________________________________________________________ 121
Listing 89: Konfigurationsdatei-Eintrag für eine Timer Service-Klasse ___________________________________ 122
Listing 90: Message Driven Bean ________________________________________________________________ 125
Listing 91: Callback-Klasse für eine Message Driven Bean ____________________________________________ 126
Listing 92: Verwendung von <tlgen> Tag __________________________________________________________ 136
Listing 93: Maven „pon.xml“ Datei _______________________________________________________________ 139
TLGen
8
StarData GmbH
V 2.8
1. Allgemeine Information
„Wissen ist Macht“ hat der englische Philosoph Francis Bacon im sechzehnten Jahrhundert
gesagt. Um sich Wissen anzueignen, braucht man Daten.
Daten sind darstellbare Elemente einer Information, mit deren Hilfe Eigenschaften einer
Aktivität beschrieben und in Systemen verarbeitet werden. Heutzutage entsprechen diese
Systeme den Computern, die in einer digitalen Form Daten verarbeiten.
Durch die stetig ansteigende Computerleistung in Verbindung mit Datenbankensystemen und
Vernetzung (z.B. durch das Internet) werden wir von Daten überflutet, die Systeme regelrecht
zusammenbrechen lassen.
Für den Tagesablauf benötigen wir eine Fülle an Informationen (z.B. Banküberweisungen, eMailverkehr, CRM/ERP-Systeme), die wir immer öfter nicht mehr in einer effizienten Form
erhalten (z.B. Systemabstürze, Unterbrechungen, fehlende Daten). Ein Hauptgrund dieser
Problematik findet sich in den Verfahren - Datensuche- und -verfahren -.
Das heutige Standardverfahren für die Datenverwaltung der Informationen bevorzugt den
Einsatz von relationalen Datenbanken (z. B. Oracle, DB2 von IBM, MySQL, SQL Server von
Microsoft etc.) sowie von Applikation Servern (z. B. JBoss, WebLogic von Oracle, WebSphere
von IBM etc.).
Die zwei Komponenten - Datenbanken und Application Server - werden in eine
Persistenzschicht integriert, welche Teil eines Programms ist, das die Fachlogik darstellt,
notwendig für eine bestimmte Aktivität (siehe Abbildung 1).
Der Nutzer (User) verwendet ein Programm über die Bedieneroberfläche (GUI oder Web), die
sich meist auf einem getrennten Computer, dem Client, befindet. Der Client holt sich die
Informationen, die er benötigt, von einem Server, wo sich die Fachlogik des Programms sowie
die Datenbank befinden. Nach heutigem technischen Stand wird die Steuerung der
Kommunikation zwischen Client und Server durch einen Application Server gesteuert, der
gleichzeitig die Daten innerhalb der Datenbank mit Hilfe von so genannten CRUDs (Create,
Read, Update, Delete) verwaltet.
Die Persistenzschicht ist ein essentiell wichtiger Teil eines jeden IT Programms und verursacht
den Hauptanteil der Programmentwicklungskosten zusammen mit Wartung und Erweiterungen
durch neue Features. Der Kostenaufwand wird durch den Einsatz von relationalen
Datenbanken weiter ausgebaut.
- Erhöhte Kosten im IT Sektor werden verursacht von:

Falscher Modellierung von Daten-Modellen sowie der Anwendung von nicht genormten
Daten-Modellen (wichtig ist die dritte Normalform)

Historisch gewachsenen Daten-Modellen

Nicht optimaler Gestaltung der Persistenzschicht, die den Aufwand von Wartung und
Weiterentwicklung erhöht

Mischung von technischem mit fachlichem Code (siehe Anmerkung)
Anmerkung:
In der Softwareentwicklung unterscheidet man drei Typen von Code:

Technischer Code: Code, der zu 100 % unabhängig von der Fachlogik und daher
komplett generierbar ist.

Generierbarer Code: Ist gemischter Code, der aus technischem und fachlogischem
Code besteht (nur Datenstruktur). Dieser Code Typ lässt sich zu 40% bis 80 %
generieren und somit reduziert dieser die Entwicklungs-, Wartungs- sowie
Weiterentwicklungs-Kosten von IT Projekten:
TLGen
9
StarData GmbH
V 2.8
o

In Fehler! Verweisquelle konnte nicht gefunden werden. entspricht dieser
Code Typ den Session Beans, der Persistence Data (Objects/Interfaces), den
Entity Managern, der Entities Beans, BCI, JUnit (Test) und den Interfaces der
Business Tier-, d.h. 40-80 % der Entwicklungskosten eines IT Projekt.
Fachlogik-Code: Ist zu 100 % spezifisch für jedes einzelne IT Projekt. Zu diesem Typ
gehören z.B. die Gestaltung der Oberfläche (Präsentation Tier) oder die
Kommunikationsschnittstellen für Partnersysteme etc.
Abbildung 1: IT Projekt Architektur
TLGen ist ein Code-Generator für den gemischten Java Code auf Basis von EJB 3, eine
Thematik, die detailliert in Kapitel 1 erläutert wird (siehe auch www.tlgen.com).
TLGen
10
StarData GmbH
V 2.8
In Kapitel 2 wird die Verwendung von TLGen mit der genauen Offenlegung seiner Features in
Kombination mit der Ordnerstruktur der Konfigurationsdatei, woraus man die Projektarchitektur
gestalten kann, beschrieben. Dieses Kapitel behandelt TLGen Möglichkeiten wie z.B. die
Optimierung von Datenmodellen oder Vermeiden von Kreisen in Datenmodelle. Dieses Kapitel
gibt auch Anweisungen für eine optimale TLGen-Verwendungen IT Projekten.
Kapitel 3 beschreibt die generierten Java Klassen anhand von Beispielen, d.h. eine detaillierte
Beschreibung der generierten Java Klassen.
Kapitel 4 beschreibt die Konfigurationsdateien und gleichzeitig die Logdateien, die bei der
Generierung entstehen.
Kapitel 5 beschreibt zwei komplette Beispiele für die TLGen Verwendung
Kapitel 6 Beschreibung der TLGen-Installation
Kapitel 7 gibt einige Beispiele für den generierten Code
Kapitel 8 Sonstige Code-Generatoren im Vergleich mit TLGen
1.1 Ziele
TLGen ist ein Code-Generator auf Basis von EJB3 mit Java Annotationen. Ziel unserer Arbeit
war, die Kosten für die Backend-Softwareentwicklung durch eine komplette Generierung von
Code zu minimieren.
Aktuelle Code-Generatoren auf Basis des MDA Ansatzes (AndroMDA, Rapsody etc.) benötigen
nach der Generierung auch einen bedeutenden Arbeitsaufwand durch die Entwickler, nachträgliches Customizing, so dass der angesetzte Zeitgewinn durch weiteren Aufwand verfällt.
Der Mix aus generiertem Code und dem von Programmierern entwickelten Code (manuelle Entwicklung) führen in der Realität zu einer Anzahl von Problemen (unterschiedliche Logik, Layout,
Auseinanderdriften von Modell und Code, Fehler etc.).
Dies ist der Grund, warum der Ansatz von TLGen eine klare Trennung zwischen den
generierten und den manuell entwickelten Code fordert. In der IT wurde des Öfteren bewiesen,
dass sich ein sehr großer Teil von Code vollständig generieren lässt. TLGen ermöglicht diese
Generierung mit Hilfe des Daten-Inputs in Form eines Domainmodells (neue Projekte) oder
einer schon existieren Datenbank (Refactoring Projekte von Legacy Systemen) in Verbindung
mit zwei Konfigurationsdateien (beinhalten die Steuerungsparameter für die Generierung).
TLGen benötigt zwei Konfigurationsdateien: eine für allgemeine Definitionen wie Daten-Typen,
Konvertierung, etc., die nur selten zu ändern ist (wird mit TLGen mitgeliefert) und eine ProjektKonfigurationsdatei, die wichtige Informationen beinhaltet wie Namen, Regeln, Umwandlungen,
Projekt-Struktur (wichtig für Legacy-Projekte), Verknüpfung von Tabellen zu bestimmten
Session Beans usw.
Zusätzlich bietet TLGen die Möglichkeit zu einer Datenbank- oder eine Domainmodell-Analyse
und unterbreitet Vorschläge für deren Optimierung.
Ist die Entwicklungsphase eines IT-Projektes beendet, werden stetig weitere Features für neue
Praxis-Anforderungen implementiert und somit die benötigte Datenbank durch Erweiterung
angepasst (gemeint ist nur die Datenstruktur). Diese historisch wachsenden Datenbanken
führen eher selten zu einer Fortführung optimaler Datenstrukturen und letztendlich zu hohen
Wartungskosten in Verbindung mit dem Zwangsstart von Refactoring Projekten.
TLGen
11
StarData GmbH
V 2.8
Das Datenmodell sollte, mindestens in der dritten Normalform vorliegen (siehe z.B.
http://de.wikipedia.org/wiki/Normalisierung_%28Datenbank%29 ). Die Normalisierung ist ein
wichtiges Hilfsmittel, um die Konsistenz der Daten zu gewährleisten. Das erleichtert die
Wartung sowie die Upgrade-Möglichkeiten für zukünftige Anforderungen der Applikation, ohne
die Datensätze zu verändern.
Da es für viele Datenbanken keine grafische Darstellung der Datenstruktur gibt, um so die
Möglichkeit der Optimierung des Datenmodells zu gewährleisten, wird die Arbeit der
Erstellung eines neuen Modells erheblich erschwert. TLGen bietet jetzt die Möglichkeit an,
aus einem existierenden Datenbankmodell die Grafik bzw. das Domainmodell zu generieren,
zusammen mit Optimierungsvorschlägen. Durch die schnelle Code-Generierung können
diese Änderungen sofort für die obligatorischen Projekt-Tests bereitstehen und somit einen
schnellen Überblick über das Entwicklungsvorhaben ermöglichen.
Diese grafische Darstellung als Domainmodell (UML) ist für die Optimierung einer alten
Datenbank sehr wichtig.
Des Weiteren wird erst durch das neu-erstellte Domainmodell eine Generierung des
Backend’s möglich, da jede Zeile aus einer Datenbanktabelle als Java Bean-Objekt im
generierten Code abgebildet wird (dabei spielt es keine Rollte, ob als Join/Mapping aus
mehreren Tabellen oder aus einer Zeile einer Tabelle).
Der generierte Backend-Code entspricht dem Software-Architekturkonzept, welches in
Abbildung 2 anschaulich erklärt wird.
1.2 TLGen´s Architektur-Konzept
In Abbildung 2 wird das Architektur-Konzept von TLGen zusammen mit den Komponenten,
welche TLGen generiert, dargestellt:

Test-Klassen(JUnit),

Data-Klassen/Interfaces

JSon-Klassen

Mapping-Klassen zwischen Data und JSon-Klassen

Sessions Beans

Entity Manager

Entity Beans

Message Driven Beans

Timer Services

Web Services

REST Interface Klassen

Callback-Klassen (siehe Abbildung 3)

Free Klassen

Log-Dateien (beschreiben im Detail die generierten Elemente)
TLGen
12
StarData GmbH
V 2.8

Datenbank-Skripte (notwendig, um eine Datenbank zu erstellen)
Für das Ändern einer schon vorhandenen Datenbank werden nur die Differenz Skripte
generiert, um so die existierenden Daten nicht zu löschen.
Für die Änderung einer existierenden Datenbank werden nur die Differenz Skripte generiert, um
so die vorhandenen Daten nicht zu löschen. Diese Skripte können direkt in dem Generierungsprozess verwendet werden oder erst bei Bedarf (siehe Kapitel 4).
Abbildung 2: TLGen Architektur
1.2.1 Input für die Code-Generierung
Damit TLGen den Code generieren kann, wird folgender Input benötigt:

Ein Datenstruktur-Modell, welches entweder ein Domainmodell (siehe Fehler!
Verweisquelle konnte nicht gefunden werden.) sein kann, designed in UML für
den Start neuer IT-Projekte (siehe Kapitel 2) oder ein Datenbankmodell (z. B. eine
existierende Datenbank – Abbildung 5) beim Einsatz in Legacy-Projekten (siehe
Kapitel 2), die einen Refactoring Prozess benötigen.

Eine Default Konfigurationsdatei (im XML-Format), welche die Werte für Definitionen
beinhaltet wie z.B. allgemeine Regeln für die Namen-Konventionen, UML Domainmodell Regel, Standard-Methoden für die Datenbankzugriffe, eine Tabelle mit
Konvertierung zwischen den Variablen-Typen in Java Code und in der Datenbank.

Eine Konfigurationsdatei (im XML-Format) mit unterschiedlichen Informationen, abhängig vom Projekt (siehe Kapitel 4).
Oben genannte Input-Informationen werden in Projekten immer von den Designern oder Datenmodellieren erstellt. Lediglich die Konfigurationsdatei ist neu für den Code, denn das Datenoder Datenbankmodell (DM oder DB) ist in der Entwicklung von IT-Projekten immer eine
Notwendigkeit.
TLGen
13
StarData GmbH
V 2.8
1.2.2 Verwendung von Callback-Klassen als Fachlogig Interfaces
Callback-Klassen werden verwendet, um eine komplette Trennung zwischen den von TLGen
generierten Code und den vom Programmierer entwickelten Code zu erzielen. So wird die
Merge (Mischung) technisch komplett ausgeschlossen.
Nach unserer Erfahrung hat die Mischung von generiertem Code mit dem vom
Programmierer entwickelten Code in vielen Projekten zahlreiche Schwierigkeiten ergeben.
Die Architektur-Darstellung für die Verwendung von Callback-Klassen ist in Abbildung 3 und
eine detaillierte Beschreibung dieser Technologie findet sich in Kapitel 3.8.
Abbildung 3: Callback Klassen-Diagramm
Diese Klassen können zusammen mit den generierten SessionBean-Klassen (Message
Driven Bean, Entity Manager, REST, Web-Service, Timer-Service) verwendet werden.
1.3 Code-Generierung mit Hilfe von TLGen
Im fortlaufenden Kapitel werden alle detaillierten Möglichkeiten beschrieben, die TLGen für
die Codegenerierung sowie der Datenbankenanalyse bietet. Die detaillierte Struktur der
Konfigurationsdateien wird in Kapitel 4.4 erläutert.
Wie schon in Kapitel 1.2 erwähnt, steuert TLGen den Generierungsprozess mit Hilfe von
zwei Konfigurationsdateien, eine für Default-Werte, die in der Regel keinen großen
Änderungsbedarf erweist sowie eine Konfigurationsdatei, die individuell für jedes Projekt ist.
TLGen bietet für die Code-Generierung folgende Möglichkeiten an:

TLGen
Das Einbauen von Kommentare innerhalb des generierten Codes (siehe Kap. 3.12)
14
StarData GmbH
V 2.8

Regel für die Namen-Generierung der Datenbanken sowie für den generierten Code
(siehe Kap. 3.10)

Der Einsatz aller Annotationen im generierten Code, die EJB3 anbietet

Informationen für die Generierung mit Hilfe von Apache Tool „ant“; TLGen hat eigene
„ant“ Tag, <tlgen> beschrieben in Kapitel 6

Der generierte Code entspricht dem EJB 3-Standard und ist auf allen Applicationen
Server, die zur Zeit am Markt vertreten sind (WebLogic, WebSphere, JBoss,
GlasFish, IoNas, etc.), verwendbar.

Folgender Code wird generiert:
o
Daten-Klassen, Daten-Interfaces, Daten JSon-Klassen und die MappingKlassen zwischen Daten-Klassen und JSon-Klassen (siehe Kap. 3.1)
o
Session Beans, Interfaces für Session Beans, XML „persistence“ Datei, REST
Dateien, Interceptors Dateien mit allen Annotationen (siehe Kap. 3.2)
o
Entity Manager-Klassen für die Steuerung von Entitie Beans mit allen
möglichen Zugriffen (Methoden) für CRUD (Create, Read, Update, Delete).
Beim Manager ist es auch möglich, eigene SQLs (werden aus den
Konfigurationsdateien gelesen) für Criteria Methoden (siehe Kap. 3.4)
einzubinden bzw. aufzurufen.
o
Entities Beans, wo alle Relationen automatisch generiert werden (vom
Domain-Modell oder aus der Datenbank) - OneToOne, OneToMany,
ManyToOne, ManyToMany (siehe Kap. 3.5)
o
Meta Klassen für die Verwendung bei Criteria Call’s (siehe Kap. 3.5.2)
o
Clients Klassen für BCI (Business Common Interfaces); Diese ermöglichen
die Verbindung zwischen Client und Server (Session Beans) (siehe Kap. 3.2).
o
Test-Klassen auf Basis von JUnit. Die Daten für Test-Klassen können durch
TLGen generiert oder von einer XML Datei geladen werden. Auch die Struktur
der XML-Daten-Dateien kann von TLGen generiert werden. Test-Klassen sind
in zwei Modi zu verwenden, indem die Daten direkt geprintet oder über die
Mechanismen von JUnit getestet werden. Die JUnit Test Klassen können für
„remote“ call’s und REST call’s generiert werden (siehe Kap. 3.3.1)
o
REST Schnittstelle (siehe Kap. 3.2.5)
o
Datenbank-Skripte (in SQL Sprache, um die Datenbank anzulegen oder zu
verwalten (siehe Kap. 7.3)
o
Callback-Klassen als Interfaces für Fachlogik-Code (siehe Kap. 3.8)
o
Interceptoren
o
XML Datei für Persistenz (persistence.xml), eine für jede Session Bean
o
Message Driven-Bean Klassen
o
Service-Klassen:

Timer Service (siehe Kap. 3.7.1)

Web Service (siehe Kap. 3.8.1)
TLGen kann mit dem „ant“ Apachen Tool genutzt werden, da TLGen einen eigenen Tag
„generator“ besitzt.
TLGen
15
StarData GmbH
V 2.8
1.3.1 Code-Generierung mit einem Domain-Modell (UML für neue Projekte)
Die Generierung mit Hilfe eines Domain-Modells als Informations-Input findet seine
Anwendung bei neuen IT-Projekten. Ein IT-Architekt (oder ein Architektur-Team,
projektabhängig) gestaltet zusammen mit der Fachabteilung ein Domain-Modell, das die
Datenstruktur und dessen Verbindungen für das Programm darstellt. Auf diese Basis kann
man letztendlich mit TLGen den kompletten Code generieren und diesen sofort testen.
Für solche Projekte bietet TLGen zu den Eigenschaften aus Kapitel 2.1 noch zusätzliche
Möglichkeiten an, wie:

Eine Analyse des Domain-Modells mit Suche nach falschen Namen (z. B. zu lang für
eine Datenbank), eventuelle Kreise in den Verbindungen zwischen Objekten
(Tabellen) und mögliche Verbesserungsvorschläge (siehe Kap. 2.1).

Innerhalb von einem Domain-Modell können Klassen-Typen und Enume verwendet
werden. Daten- und Klassen-Typen können in jeder beliebigen Art und Weise
verschachtelt werden, so wie die benötigte Logik der Applikation.
TLGen
16
StarData GmbH
V 2.8
Abbildung 4: Domain-Modell
1.3.2 Generierung mit einer schon vorhandenen Datenbank (für Legacy Projekte)
Nachdem TLGen einen Zugang zur Datenbank erhalten hat, übernimmt TLGen alle
relevanten Informationen für die Code-Genierung wie z.B. Tabellen, Spalten, Relationen,
Sequenzen etc. TLGen ist kompatibel zu allen aktuellen Datenbanken.
Für ein Projekt, dass mit einer Datenbank als Input startet (z.B. Refactoring von LegacySystemen) bietet TLGen zu den in Kap. Fehler! Verweisquelle konnte nicht gefunden
werden. aufgelisteten Eigenschaften weitere Möglichkeiten an, wie:

Optimale Verwendung von Tabellen, Spalten etc. für den generierten Code gemäß
den existierenden Namen-Konventionen im Code

Generierung von Datenbank Skripte für eine neue
Änderungsskripte, die dann nur die Differenzen beinhalten
TLGen
17
Datenbank
oder
nur
StarData GmbH
V 2.8
Abbildung 5: Database-Modell
TLGen
18
StarData GmbH
V 2.8
2 TLGen Code-Generierung und die Datenbankanalyse
TLGen ist ein einfaches Tool mit einem technischen Hintergrund auf höchstes Niveau für die
Generierung von Backend Code auf Basis von EJB3. Wie in den Kapiteln zuvor erklärt,
generiert TLGen den Code von einem Domain- (siehe Abbildung 4) oder Datenbankmodell
(siehe Abbildung 5) und bietet gleichzeitig Optimierungsmöglichkeiten der Modelle nach
eigener Analyse an.
Abbildung 6: TLGen-Generierungsprozess von einem Domain-Modell
In diesem Kapitel werden detailliert die generierten Objekte sowie zur Verfügung stehende
Steuerungsmöglichkeiten beschrieben.
Allgemeine Features, die zentral für die gesamte Generierung möglich sind (für Details siehe
Kap. 4):

Projekt-Name

Application Server, z.B. „JBoss“, “Weblogic” etc. Der Application Server ist für die
Verwendung des generierten Codes für „Clients“ wichtig, weil jeder Application Server
eigene Darstellung für die Variable „datasource“ und für die Verbindung zwischen
Client und Server in „remote modus“ eigene Klassen verwendet .
initialcontextfactory="org.jnp.interfaces.NamingContextFactory"
initialcontextpkgprefix="org.jboss.naming:org.jnp.interfaces"
Listing 1: Remote Connect-Klassen

Datenbank-Namen mit Zugriff für die berechtigten User samt Passwörter zum
Auslesen der Informationen (Tabellen, Spalten, Sequences, etc. für Legacy Projekte
oder Ziele, wo die Tabellen generiert werden sollten)

Projekt-Steuerungs-Attribut. Ein Refactoring-Projekt wird durch eine schon
vorhandene Datenbank (wichtig bei vorhandener Legacy-IT) oder Entwicklung einer
neuen Applikation durch ein Domainmodell gesteuert. Bei Generierung einer neuen
Datenbank kann diese vollständig neu erstellt oder nur die Änderungen übernommen
werden, ohne schon vorhandene Daten zu löschen.
TLGen
19
StarData GmbH
V 2.8

Notwendige Informationen für die Generierung von SQL Skripte wie Tablespace etc.

„ear“ Datei-Name

Die generierte Code-Formatierung kann frei gewählt werden (Standard JavaFormatierung z.B. mit geschweiften Klammern in derselben oder nächsten Zeile oder
z.B. die Anzeige der Import-Deklarationen am Klassenanfang oder direkt im Code mit
den vollständigen Import).
import eu.stardata.core.hlp.dataif.CoLanguageDataIf;
import javax.persistence.OneToMany;
class {
private CoLanguageDataIf …
…
}
Listing 2: Import Code
oder ohne Import in Code:
Class {
@ javax.persistence.OneToMany(cascade = { javax.persistence.CascadeType.PERSIST},
targetEntity = eu.stardata.server.core.formular.entity.PageEntity.class)
private eu.stardata.server.core.doclist.entity.DocumentlistEntity …
…
}
Listing 3: Code für Variable mit vollem Path
2.1 Analyse des Domainmodells und der Datenbank
Die Relationen vonKlassen eines Domainmodells oder von Datenbank-Tabellen können je
nach Anforderungen unterschiedlich komplex sein.
Betrachten wir als Beispiel Abbildung 7 eines UML-Klassendiagramms, wo beim Neuanlegen
der Klasse C mindestens ein B über zwei verschiedene Pfade gleichzeitig benötigt werden.
Existiert jedoch kein B, muss dieses erst neuangelegt werden. Dies ist in diesem Fall aber
nur möglich, falls ein C über eine Relation von Pfad A schon existiert. Das Klassendiagramm
ist logisch nicht inkorrekt (z.B. ist A ein Produkt, B ein Element des Produkts und C ein
Bestellauftrag). Aber die Klassen des Beispiels Domainmodell, jeweils als Tabelle in einer
Datenbank abgebildet, führen zum Problem, dass C ein B benötigt (not null) wie A (not null),
doch gleichzeitig benötigt A auch ein B (not null), dass zu diesem Zeitpunkt schon vorhanden
sein müsste.
TLGen
20
StarData GmbH
V 2.8
Abbildung 7: UML-Klassendiagramm I
Anmerkung: Ein UML-Klassendiagramm, wo beim Neuanlegen der Classe C B über 2
verschiedene Pfade benötigt wird. Beim Neuanlegen von B kann dieses dagegen
noch nicht existieren, da C noch nicht über die Relation von Pfad A existiert.
Kreise, durch Pfade in der Erreichbarkeit der Klasse „C“, sind hier wie folgt:
Die Klasse „C“ ist über die Klasse „B“ durch folgende Pfade erreichbar:


[B (NOT NULL)->A (NOT NULL)] ---> [C]
[B (NOT NULL)]
---> [C]
Genau in diesem Schema werden alle Pfade in der Erreichbarkeit einer Klasse (hier „C“),
über welche Klassen (hier „B“) diese Pfade verlaufen, in der Debug-Log Datei bei der
Generierung des Codes durch TLGen dargestellt. Fälle wie in Fehler! Verweisquelle
konnte nicht gefunden werden. werden mit einem „Fatal Error“ in der Debug-LOG Datei
und Error-LOG Datei ausgegeben. Dagegen werden Kreise von Relationspfaden, die nicht
über unterschiedliche Klassen in der Zielklasse enden, mit einem „Warning“ angezeigt (vgl.
Abbildung 8).
Abbildung 8: UML-Klassendiagramm II
Anmerkung: Wie Abbildung 7, aber in der Relation von [B(Null)] ---> [C] ist null erlaubt.
Somit kann B und C über den Relationen von A gleichzeitig angelegt werden.
Direkte Kreise, d.h. Zielklasse ist auch die Startklasse in einem Relationspfad, werden in den
LOG-Dateien als „Fatal Error“ deklariert (vgl. Abbildung 9), falls alle Klassen im
TLGen
21
StarData GmbH
V 2.8
Relationspfad voneinander abhängig sind (hier: [A (NOT NULL)->C (NOT NULL) ->B (NOT NULL)] --->
[A]) und nur mit einem „Warning“, falls dies nicht zutrifft (vgl. Abbildung 7: [A (NOT NULL)->C
(NULL) ->B (NOT NULL)] ---> [A])
Abbildung 9: UML-Klassendiagramm III
Anmerkung: Ein direkter Relationspad, wo jede Startklasse auch Zielklasse
ist und alle voneinander abhängig sind.
Abbildung 10: UML-Klassendiagramm IV
Anmerkung: Ein direkter Relationspad, wo jede Startklasse auch
Zielklasse ist, aber nicht alle voneinander abhängig sind.
Im Folgenden ist ein Knoten mit einer Klasse des Domainmodells oder einer Datenbanktabelle äquivalent.
Die Debug-LOG Datei beinhaltet folgende Informationen, um Pfade zu analysieren:

„CHECK RELATIONS METHODS - Adjacency list”:
Die Liste zeigt alle Knoten (TARGET) an, die über verschiedene Relationspfade erreicht
werden können:
Node: 'TARGET':
TLGen
22
StarData GmbH
V 2.8
[ungeordneter Relationspfad] ---> [TARGET] [alle passierte Vorknoten der Pfade aufsummiert]
Beispiel: [C,B] ---> [A]

[C(1),B(2)]
„CHECK RELATIONS METHODS - CIRCLE PATH (direct)”:
Die Liste zeigt alle Kreise der Knoten (TARGET) an, die über verschiedene
Relationspfade über den TARGET selber erreicht werden können:
Node: 'TARGET':
[geordneter Relationspfad beginnend mit TARGET] ---> [TARGET]
Beispiel: [A(NULL)->C (NOT NULL)->B (NOT NULL)] ---> [A]

„CHECK RELATIONS METHODS - ALL PATHS”:
Die Liste zeigt alle Pfade der Knoten (TARGET) an, die über andere Knoten erreicht
werden können:
Node: 'TARGET':
[geordneter Relationspfad] ---> [TARGET]
Beispiel: [C (NOT NULL)->B (NOT NULL)] ---> [A]
Wenn neben dem Pfad ein „FATAL” angeziegt wird, dann ist TARGET von sich selbst
abhängig.

„CHECK RELATIONS METHODS - CIRCLE PATHS (not direct)”:
Die Liste zeigt alle Pfade der Knoten (TARGET) an, die von verschiedenen Knoten
(SOURCE) über unterschiedliche Relationspfade erreicht werden können:
'TARGET':
'SOURCE':
[geordneter Relationspfad mit SOURCE] ---> [TARGET]
Beispiel: -'C': [C (NOT NULL)->B (NOT NULL)] ---> [A]
Wenn neben dem Knoten SOURCE „FATAL” angeziegt wird, dann sind mehrere Pfade,
die in TARGET enden, von SOURCE abhängig (siehe oben, z.B. [C->D]--->[A] und [C>B]--->[A]). Wird ein „Warning” angezeigt, dann sind mehrere Pfade, die in TARGET
enden, von SOURCE abhängig, wobei diese über denselben Knoten in TARGET (siehe
oben, z.B. [C->D->B]--->[A] und [C->B]--->[A]) enden.
Die Error-LOG Datei beinhaltet folgende Informationen, um Pfade zu analysieren:

„Direct circles in relations”
o „Warning“, wenn es einen Relationspfad gibt, wo Start- und Endknoten gleich
sind.
Beispiel: [A (NULL)->B (NOT NULL)] ---> [A])
TLGen
23
StarData GmbH
V 2.8
o
„FATAL Error“, wenn es einen Relationspfad gibt, wo Start- und Endknoten
gleich und voneinander abhängig sind.
Beispiel: [A (NOT NULL)->B (NOT NULL)] ---> [A]

„Relation Problems?”
o „Warning“, wenn man den Zielknoten über verschiedene Relationspfade
desselben Startknotens erreichen kann und diese voneinander abhängig sind,
aber der Zielknoten immer über denselben Vorgängerknoten endet.
Beispiel: [C (NOT NULL)->B (NOT NULL)] ---> [A] und [C (NOT NULL)->D (NOT NULL)->B (NOT
NULL)] ---> [A])
o
„FATAL Error“, wenn man den Zielknoten über verschiedene Relationspfade
desselben Startknotens erreichen kann und diese voneinander abhängig sind.
Beispiel: [C (NOT NULL)->B (NOT NULL)] ---> [A] und [C (NOT NULL)->D (NOT NULL)] ---> [A]
2.1.1 Verwendung von UML Parameter (Tags) für die Code-Generierung
2.1.1.1 UML Parameter für Klassen
Folgende UML Parameter werden für die Klassengenerierung (siehe Fehler! Verweisquelle
konnte nicht gefunden werden.) in verschieden UML Tools verwendet:
Tabelle 1: UML Verwendete Parameter für die Generierung
Nr.
1
2
Enterprise
Architekt
Name
Package
3
Parsistence
4
Notes
5
Constrains
6
Links
7
LinksMultiplicity
8
Links-Type
9
LinksDirection
Magic Draw
RMI Tags/Attribut
Description
UML:Class.name
tag="package_name"
value=”Package-Name”
tag="persistence"
value="Persistent/Transient"
Class Name
This value is used to build the
class path (view 4.5.2.4)
For „Persistent“ a Table and a
class data is generate in the
database, for “Transient” only a
class data is generated
Class Description
tag="documentation"
value=".. Description ..”
UML:Constraint
name="SQL constraint”
UML:Association
tag="ea_type"
value="Aggregation"
tag="direction"
value="Destination ->t;
Source"
Constrains for database SQL
script. View 5.b.iii
Defined the links between two
classes with all parameters
(Source Role, Target Role)
Define the Multiplicity from link.
OneToOne, OneToMany,
ManyToOne or ManyToMany
Define the Links Type (keine,
Aggregation, Composition) or
Define Direction (Unspezified, BiDerectional, Source->Destination,
Destination->Source)
2.1.1.2 UML Parameter für Attribute
TLGen
24
StarData GmbH
V 2.8
Folgende UML Parameter werden für die Variablen-Generierung (siehe Tabelle 1) für
verschiedene UML Design Tools verwendet:
Tabelle 1: UML verwendete Attribute für die Generierung
Nr.
Enterprise
Architekt
Magic Draw
1
Name
Get the variable name
2
Type
Variable Type, i.e. String, int, long, other class, an
predefiniert enum, etc
3
Attribute
is
a
Collection/Container
Type
Atrributlänge (in DB)
4
Initial
Initial value
5
Notes
Attribute description
6
Derived
Is used to define the database, if this field is null or not
null
7
Constrint/Type
Process
8
Static
=
Description
Call a method for chifer/entchifer by write and read in
the DB
Define, if this field is unique in the database
2.1.1.3 Was wird generiert
Damit die Code-Generierung aus einem UML-Diagramm (für TLGen der XML-Export von
Enterprise Architekt in UML 1.3 / UML2.0) die gewünschten Ergebnisse liefert, muss man die
UML-Relationen und Parameter entsprechend für TLGen konfigurieren. Standardmäßig sind
bestimmte Attribute für TLGen fest gewählt und können in der Default Konfigurationsdatei
entsprechend angepasst werden.
Im Folgenden werden die Standard-Parameter von TLGen erklärt und die Ergebnisse in
Code-Beispielen aufgezeigt.
2.1.1.3.1 Relationen
Mit den Relationen lassen sich die Abhängigkeiten der UML-Klassen in einem DomainModell logisch aufzeigen. Damit TLGen EJB-Code und die Entity-Beans Abhängigkeiten
untereinander generiert, sind die UML-Relationen zu den verschieden EJB OneToOne-,
OneToMany-, ManyToOne- und ManyToMany-Relationen (siehe Kapitel 3.5.1)
standardmäßig konfiguriert und werden im Folgenden erläutert (mit Code-Beispiel). Natürlich
können diese Einstellungen für eigene projektspezifische Anforderungen in der Default
Konfigurationsdatei verändert werden.
TLGen
25
StarData GmbH
V 2.8
Mit Hilfe der drei verschiedenen UML Assoziationen „Assoziation“, „Aggregation“ und
„Komposition“, die Relations-Richtung (B->A „Source to Destination“ oder B<-A „Destination
to Source“), Navigation und Multiplizität (z.B. 0-*, 0-1 oder 1) wird die Relationsart
OneToOne-, OneToMany-, ManyToOne- und ManyToMany generiert. Diese berechneten
Generierungen der Relationsarten können nochmals von der Relationsart selber in der
Konfigurationsdatei überschrieben werden (siehe Kapitel 2.1.1.3.2).
Anmerkung: Im UML Programm Enterprise Architect kann man die Navigation explizit
ändern, d.h. B->A „Source to Destination“ oder B<-A „Destination to Source“ zu B<-A
„Source to Destination“ oder B->A „Destination to Source“, aber die Richtungsart bleibt
erhalten. Dies erkennt TLGen, um weitere EJB-Relationsarten in der Generierung zu
ermöglichen (z.B. siehe Paramenter in Kapitel 2.1.1.3.1.2).
Der EJB Tag „@JoinColumn“-Parameter „insertable“, „updatable“, „nullable“, „optional“ und
der Relationsart-Tag-Parameter (von z.B. „@OneToMany“) „cascade“ werden anhand der
Multiplizität (z.B. nullable=true|false) und der Relationsart festgelegt (siehe Abbildung 8:
UML-Klassendiagramm II).
2.1.1.3.1.1 Assoziation
Die Verwendung der einfachen Assoziation generiert alle Relationsarten OneToOne-,
OneToMany-, ManyToOne- und ManyToMany anhand der Multiplizität (z.B. „1-*“). Die
Richtung spielt hier keine Rolle (siehe Abbildung 11).
Parameter:
-
cascade: Cascade wird nicht generiert.
-
insertable: Ist immer true.
-
updateable: Ist immer true.
-
nullable: Abhängig von der Multiplizität.
TLGen
26
StarData GmbH
V 2.8
Abbildung 11: UML-Relationen und die TLGen-Gernerierungsparameter
Anmerkung: Alle Parameter sind über die Konfigurationsdatei steuerbar.
Die genau eingestellten Parameter sind in den Kapiteln der Relationen
„Assoziation“, „Aggregation“ und „Komposition“ erklärt.
OneToOne Beispiel: Die Source-Klasse Offer (Source) hat eine Assoziation mit der Klasse
AccessControl (Target) mit der Richtung Source->Destination und Multiplizität 1->0..1
Folgender Relations-Code wird nur in die Entity-Klasse Offer generiert:
private AccessControlEntity m_accessControl = null;
...
@OneToOne(targetEntity = AccessControlEntity.class,optional = true)
@JoinColumn(name = "AccessControl_ID",insertable = true, updatable = true, nullable = true, unique =
false, referencedColumnName = "AccessControl_ID")
public AccessControlEntity getAccessControl () {
return m_accessControl;
}
public void setAccessControl (AccessControlEntity arg) {
m_accessControl = arg;
}
Listing 4: “OneToOne” Assoziation
TLGen
27
StarData GmbH
V 2.8
OneToMany Beispiel: Die Source-Klasse ServiceDescription (Source) hat eine Assoziation
mit der Klasse AccessControl (Target) mit der Richtung Source->Destination (Navigation auf
Destination) und Multiplizität 1->0..* (->AccessControl). Dies entspricht einer OneToManyRelation von ServiceDescription zu AccessControl.
Anmerkung: Die Verwendung der mappedby-Funktion für OneToMany wird in der
Konfigurationsdatei aktiviert (siehe Kapitel 4.5.2.2 <Project> Tag).
OneToMany-Relation vom Entity ServiceDescription zum Entity AccessControl:
Klasse ServiceDescription:
private List<AccessControlEntity> m_accessControl = new ArrayList<AccessControlEntity>();
...
@OneToMany(targetEntity = AccessControlEntity.class)
@JoinColumn(name = "ServiceDescription_ID")
public List<AccessControlEntity> getAccessControl() {
return m_accessControl;
}
public void setAccessControl(List<AccessControlEntity> arg) {
m_accessControl = arg;
}
MappedBy:
private AccessControlEntity m_accessControl = null;
...
@OneToMany(mappedBy = "serviceDescription",targetEntity = AccessControlEntity.class)
public List<AccessControlEntity> getAccessControl () {
return m_accessControl;
}
public void setAccessControl (List<AccessControlEntity> arg) {
m_accessControl = arg;
}
Listing 5: “OneToMany” Assoziation - One
Die Entity-Klassen AccessControl der Relation werden in einer Array-Liste gespeichert. Das
gilt für die dazugehörige Daten-Klasse.
Klasse AccessControl:
private ServiceDescriptionEntity m_serviceDescription = null;
...
@ManyToOne(optional = true,targetEntity = ServiceDescriptionEntity.class)
@JoinColumn(name = "ServiceDescription_ID",insertable = true, updatable = true, nullable = false, unique
= false,referencedColumnName = "ServiceDescription_ID")
public ServiceDescriptionEntity getServiceDescription() {
return m_serviceDescription;
TLGen
28
StarData GmbH
V 2.8
}
public void setServiceDescription(ServiceDescriptionEntity arg) {
m_serviceDescription = arg;
}
MappedBy:
private ServiceDescriptionEntity m_serviceDescription = null;
...
@ManyToOne(optional = true,targetEntity = ServiceDescriptionEntity.class)
@JoinColumn(name = "ServiceDescription_ID",insertable = true, updatable = true, nullable = false, unique
= false,referencedColumnName = "ServiceDescription_ID")
public ServiceDescriptionEntity getServiceDescription() {
return m_serviceDescription;
}
public void setServiceDescription(ServiceDescriptionEntity arg) {
m_serviceDescription = arg;
}
Listing 6: “OneToMany” Assoziation - Many
ManyToOne Beispiel: Die Source Klasse Access (Source) hat eine Assoziation mit der Klasse
Order (Target) mit der Richtung Source->Destination und Multiplizität 0..*->0..1
Folgender Relations-Code wird nur in die Entity-Klasse Access generiert (keine OneToManyRückverbindung im Order- Entity):
Klasse Access:
private OrderEntity m_order = null;
...
@ManyToOne(optional = true,targetEntity = OrderEntity.class)
@JoinColumn(name = "OrderTable_ID",insertable = true, updatable = true, nullable = true, unique =
false,referencedColumnName = "OrderTable_ID")
public OrderEntity getOrder() {
return m_order;
}
public void setOrder(OrderEntity arg) {
m_order = arg;
}
Listing 7: „ManyToMany“ Assoziation - Many
ManyToMany Beispiel: Die Source Klasse Service (Source) hat eine Assoziation mit der
Klasse Location (Target) mit der Richtung Source->Destination und Multiplizität 0..*->0..*
Anmerkung: Die Verwendung der mappedby-Funktion für ManyToMany wird in der
Konfigurationsdatei aktiviert (siehe Kapitel 4.5.2.2 <Project> Tag).
ManyToMany-Relation vom Entity Service zum Entity Location:
TLGen
29
StarData GmbH
V 2.8
Klasse Service:
private List<LocationEntity> m_location = new ArrayList<LocationEntity>();
...
@ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},
mappedBy = "service",targetEntity = LocationEntity.class)
public List<LocationEntity> getLocation() {
return m_location;
}
public void setLocation(List<LocationEntity> arg) {
m_location = arg;
}
MappedBy:
private List<LocationEntity> m_location = new ArrayList<LocationEntity>();
...
@ManyToMany(cascade =
{CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},mappedBy =
"serviceDescription",targetEntity = LocationEntity.class)
public List<LocationEntity> getLocation() {
return m_location;
}
public void setLocation(List<LocationEntity> arg) {
m_location = arg;
}
Listing 8: “ManyToMany” Assoziation - Many 1
ManyToMany -Relation vom Entity Location zum Entity Service:
Klasse Location:
private List<ServiceEntity> m_service = new ArrayList<ServiceEntity>();
...
@ManyToMany(targetEntity = ServiceDescriptionEntity.class)
@JoinTable(name = "Service_Location",inverseJoinColumns = {@JoinColumn(name =
"Service_ID",insertable = true, updatable = true, nullable = true, unique = false)},joinColumns =
{@JoinColumn(name = "Location_ID",insertable = true, updatable = true, nullable = true, unique = false)})
public List<ServiceEntity> getService() {
return m_service;
}
public void setService(List<ServiceEntity> arg) {
m_service = arg;
}
MappedBy:
private List<ServiceEntity> m_service = new ArrayList<ServiceEntity>();
...
@ManyToMany(targetEntity = ServiceEntity.class)
TLGen
30
StarData GmbH
V 2.8
@JoinTable(name = "Service_Location",inverseJoinColumns = {@JoinColumn(name =
"Service_ID",insertable = true, updatable = true, nullable = true, unique = false)},joinColumns =
{@JoinColumn(name = "Location_ID",insertable = true, updatable = true, nullable = true, unique = false)})
public List<ServiceEntity> getService() {
return m_service;
}
public void setService(List<ServiceEntity> arg) {
m_service = arg;
}
Listing 9: “ManyToMany” Assoziation - Many 2
In beiden Entity-Klassen werden die anderen Entities der Relation in Array-Listen
gespeichert, genauso in den Daten-Klassen.
Die Mapping Tabelle Service_Location wird automatisch mit generiert (siehe Kapitel 3.5.1.4
Relation „ManyToMany“)
2.1.1.3.1.2 Aggregation
Die Verwendung der Aggregation als stärkere Klassenbindung generiert auch alle
Relationsarten OneToOne-, OneToMany-, ManyToOne- und ManyToMany durch die Multiplizität (z.B. „1-*“) und anhand der Richtung, ob ein OneToMany (Destination-> Source) oder
ein ManyToOne (Source->Destination) generiert wird.
Parameter Relation “< >=====” mit "Source -> Destination” und Navigation ="Source":
-
nullable: Abhängig von der Multiplizität.
Parameter Relation “< >====>” mit "Source -> Destination” und Navigation ="Target":
-
nullable: Abhängig von der Multiplizität.
-
insertable="true"
-
updateable="true"
-
cascade="PERSIST,MERGE"
Parameter Relation “< >=====” mit " Destination -> Source” und Navigation =" Target":
-
nullable: Abhängig von der Multiplizität.
Parameter Relation “< >====>” mit " Destination -> Source” und Navigation =" Source ":
-
nullable: Abhängig von der Multiplizität.
-
insertable="true"
-
updateable="true"
-
cascade="PERSIST "
TLGen
31
StarData GmbH
V 2.8
Konfigurationseinstellung in der XML:
/** -- Relation: < >=====" | Direction: "Source -> Destination" | Navigation: <= to Source" --------------------- **/
<Association type="Shared" name="Shared:Source -> Destination|toSource" position="Source" navigable="Source"
nullable ="true"n comment="Relation: < >===== | Direction: 'Source -> Destination' | Navigation: '<= to
Source'"/>n"
/** -- Relation: < >====>" | Direction: "Source -> Destination" | Navigation: "=> to Destination" ----------- **/
<Association type="Shared" name="Shared:Source -> Destination|toTarget" position="Source" navigable="Target"
nullable ="true" insertable="true" updateable="true" cascade="PERSIST,MERGE" comment="Relation: <
>====> | Direction: 'Source -> Destination' | Navigation: '=> to Destination'"/>
/** -- Relation: < >=====" | Direction: "Destination -> Source" | Navigation: <= to Destination" ----------------- **/
<Association type="Shared" name="Shared:Destination -> Source|toTarget" position="Target" navigable="Target"
nullable ="true"n comment="Relation: < >===== | Direction: 'Destination -> Source' | Navigation: '<= to
Destination'"/>
/** -- Relation: < >====>" | Direction: "Destination -> Source" | Navigation: "=> to Source" ----- **/
<Association type="Shared" name="Shared:Destination -> Source|toSource" position="Target" navigable="Source"
nullable ="true" insertable="true" updateable="true" cascade="PERSIST" comment="Relation: < >====> |
Direction: 'Destination -> Source' | Navigation: '=> to Source'"/>
OneToOne Beispiel: Die Source Klasse Corporate (Target) hat eine Aggregation mit der
Entity-Classe Config (Source) mit der Richtung Destination->Source (Navigation auf Source)
und Multiplizität 0..1->0..1 (->Config). Dies entspricht einer OneToOne-Relation von
Corporate zu Config.
OneToOne-Relation vom Entity
Rückverbindung im Entity Config):
Corporate
zum
Entity
Config
(keine
OneToOne
Klasse Corporate:
private ConfigEntity m_config = null;
...
@OneToOne(cascade = {CascadeType.PERSIST},targetEntity = ConfigEntity.class,optional = true)
@JoinColumn(name = "Config_ID",insertable = true, updatable = true, nullable = true, unique =
false,referencedColumnName = "Config_ID")
public ConfigEntity getConfig() {
return m_config;
}
public void setConfig(ConfigEntity arg) {
m_config = arg;
}
Listing 10: “OneToOne” Aggregation
TLGen
32
StarData GmbH
V 2.8
OneToMany Beispiel: Die Source Klasse Customer (Target) hat eine Aggregation mit der
Klasse CustomerHistory (Source) mit der Richtung Destination->Source (Navigation auf
Source) und Multiplizität 0..1->0..* (->CustomerHistory). Dies entspricht einer OneToManyRelation von Customer zu CustomerHistory.
Anmerkung: Die Verwendung der mappedby-Funktion für OneToMany wird in der
Konfigurationsdatei aktiviert (siehe Kapitel 4.5.2.2 <Project> Tag).
OneToMany-Relation vom Entity Customer zum Entity CustomerHistory:
Klasse Customer:
private List<CustomerHistoryEntity> m_customerHistory = new ArrayList<CustomerHistoryEntity>();
...
@OneToMany(cascade = {CascadeType.PERSIST}, mappedBy = "customer",targetEntity =
CustomerHistoryEntity.class)
public List<CustomerHistoryEntity> getCustomerHistory() {
return m_customerHistory;
}
public void setCustomerHistory (List<CustomerHistoryEntity> arg) {
m_customerHistory = arg;
}
Listing 11: “OneToMany” Aggregation - One
Die Entity-Klassen CustomerHistory der Relation werden in einer Array-Liste gespeichert,
genauso in der Daten-Klasse von Customer.
Klasse CustomerHistory:
private CustomerEntity m_customer = null;
...
@ManyToOne(optional = true,targetEntity = CustomerEntity.class)
@JoinColumn(name = "Customer_ID",insertable = true, updatable = true, nullable = true, unique =
false,referencedColumnName = "Customer_ID")
public CustomerEntity getCustomer() {
return m_customer;
}
public void setCustomer(CustomerEntity arg) {
m_customer = arg;
}
Listing 12: “OneToMany” Aggregation - Many
TLGen
33
StarData GmbH
V 2.8
ManyToOne Beispiel: Die Source Klasse Cos (Target) hat eine Aggregation mit der Klasse
Corporate (Source) mit der Richtung Destination->Source (Navigation auf Source) und Multiplizität 1->0..* (->Cos). Dies entspricht einer ManyToOne-Relation von Cos zu Corporate.
ManyToOne-Relation von Cos zum Entity Corporate (keine OneToMany Rückverbindung zu
Corporate):
Klasse Corporate:
private CosEntity m_cos = null
...
@ManyToOne(optional = true,targetEntity = CosEntity.class)
@JoinColumn(name = "Cos_ID",insertable = true, updatable = true, nullable = false, unique =
false,referencedColumnName = "Cos_ID")
public CosEntity getCos() {
return m_cos;
}
public void setcos(CosEntity arg) {
m_cos = arg;
}
Listing 13: „ManyToMany“ Aggregation - Many
ManyToMany Beispiel: Die Source Klasse Sub (Target) hat eine Aggregation mit der
Klasse App (Source) mit der Richtung Destination->Source (Navigation auf Source) und
Multiplizität 0..*->0..* (->App). Dies entspricht einer ManyToMany-Relation von Sub zu App.
Anmerkung: Die Verwendung der mappedby-Funktion für ManyToMany wird in der Konfigurationsdatei aktiviert (siehe Kapitel 4.5.2.2 <Project> Tag).
ManyToMany -Relation vom Entity Sub zum Entity App:
Klasse Sub:
private List<AppEntity> m_app = new ArrayList<AppEntity>();
...
@ManyToMany(cascade =
{CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},mappedBy = "sub",targetEntity =
AppEntity.class)
public List<AppEntity> getApp() {
return m_app;
}
public void setApp(List<AppEntity> arg) {
m_app = arg;
}
Listing 14: “ManyToMany” Aggregation - Many 1
TLGen
34
StarData GmbH
V 2.8
ManyToMany -Relation vom Entity App zum Entity Sub:
Klasse App:
private List<SubEntity> m_sub = new ArrayList<SubEntity>();
...
@ManyToMany(targetEntity = SubEntity.class)
@JoinTable(name = "Sub_App",inverseJoinColumns = {@JoinColumn(name = "Sub_ID",insertable = true,
updatable = true, nullable = true, unique = false)},joinColumns = {@JoinColumn(name =
"App_ID",insertable = true, updatable = true, nullable = true, unique = false)})
public List<SubEntity> getSub() {
return m_sub;
}
public void setSub(List<SubEntity> arg) {
m_sub = arg;
}
Listing 15: “ManyToMany” Aggregation - Many 2
In beiden Entity-Klassen werden die anderen Entities der Relation in Array-Listen
gespeichert, genauso in den Daten-Klassen.
Die Mapping Tabelle Sub_App wird automatisch mit generiert (siehe Kapitel 3.5.1.4)
2.1.1.3.1.3 Komposition
Die Komposition ist die stärkste Verbindungsart (somit „nullable“ nicht immer „true“) und
generiert auch alle Relationsarten OneToOne-, OneToMany-, ManyToOne- und
ManyToMany, durch die Multiplizität (z.B. „1-*“) und anhand der Richtung, ob ein
OneToMany (Destination-> Source) oder ein ManyToOne (Source->Destination) generiert
wird.
Parameter Relation “<#>=====” mit "Source -> Destination” und Navigation ="Source":
-
nullable=“false“
-
optional="false
Parameter Relation “<#>====>” mit "Source -> Destination” und Navigation ="Target":
-
optional="false"
-
nullable="true"
-
insertable="true"
-
updateable="true"
-
cascade="PERSIST,MERGE,REMOVE"
Parameter Relation “<#>=====” mit " Destination -> Source” und Navigation =" Target":
TLGen
35
StarData GmbH
V 2.8
-
nullable=“false“
-
optional="false
Parameter Relation “<#>====>” mit " Destination -> Source” und Navigation=" Source ":
-
optional="false"
-
nullable="true"
-
insertable="true"
-
updateable="true"
-
cascade="PERSIST,MERGE,REMOVE"
Konfigurationseinstellung in der XML:
/** -- Relation: <#>=====" | Direction: "Source -> Destination" | Navigation: <= to Source" ----------------------- **/
<Association type="Composition" name="Composition:Source -> Destination|toSource" position="Source"
navigable="Source" optional="false" nullable ="false" comment="Relation: <#>===== | Direction: 'Source ->
Destination' | Navigation: '<= to Source'"/>
/** -- Relation: <#>====>" | Direction: "Source -> Destination" | Navigation: "=> to Destination" ---------------- **/
<Association type="Composition" name="Composition:Source -> Destination|toTarget" position="Source"
navigable="Target" optional="false" nullable ="true" insertable="true" updateable="true"
cascade="PERSIST,MERGE,REMOVE" comment="Relation: <#>====> | Direction: 'Source -> Destination' |
Navigation: '=> to Destination'"/>n"
/** -- Relation: <#>====="" | Direction: "Destination -> Source" | Navigation: <= to Destination" --------------- **/
<Association type="Composition" name="Composition:Destination -> Source|toTarget" position="Target"
navigable="Target" optional="false" nullable ="false"n comment="Relation: <#>===== | Direction: 'Destination ->
Source' | Navigation: '<= to Destination'"/>
/** -- Relation: <#>====>" | Direction: "Destination -> Source" | Navigation: "=> to Source" ------------------ **/
<Association type="Composition" name="Composition:Destination -> Source|toSource" position="Target"
navigable="Source" optional="false" nullable ="true" insertable="true" updateable="true"
cascade="PERSIST,MERGE,REMOVE" comment="Relation: <#>====> | Direction: 'Destination -> Source' |
Navigation: '=> to Source'"/>
OneToOne Beispiel: Die Source Klasse Product (Source) hat eine Komposition mit der
Klasse Asset (Target) mit der Richtung Destination->Source (Navigation auf Product) und
Multiplizität 1->1 (->Product).
OneToOne-Relation vom Entity Asset zum Entity Product (keine OneToOne Rückverbindung
zu Product):
TLGen
36
StarData GmbH
V 2.8
Klasse Asset:
private ProductEntity m_product = null;
...
@OneToOne(cascade =
{CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},targetEntity =
ProductEntity.class,optional = true)
@JoinColumn(name = "Product_ID",insertable = true, updatable = true, nullable = false, unique =
false,referencedColumnName = "Product_ID")
public ProductEntity getProduct() {
return m_product;
}
public void setProduct(ProductEntity arg) {
m_product = arg;
}
Listing 16: “OneToOne” Komposition
OneToMany Beispiel: Die Source Klasse Login (Source) hat eine Komposition mit der
Klasse Customer (Target) mit der Richtung Destination->Source (Navigation auf Source) und
Multiplizität 0..*->0...1 (->Customer).
Anmerkung: Die Verwendung der mappedby-Funktion für OneToMany wird in der Konfigurationsdatei aktiviert (siehe Kapitel 4.5.2.2 <Project> Tag).
OneToMany -Relation vom Entity Customer zum Entity Login:
Klasse Customer:
private List<LoginEntity> m_login = new ArrayList<LoginEntity>();
...
@OneToMany(cascade =
{CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},mappedBy =
"customer",targetEntity = LoginEntity.class)
public List<LoginEntity> getLogin() {
return m_login;
}
public void setLogin(List<LoginEntity> arg) {
m_login = arg;
}
Listing 17: “OneToMany” Komposition - One
Die Entity-Klassen Login der Relation werden in einer Array-Liste gespeichert, genauso in
der Daten-Klasse von Customer.
TLGen
37
StarData GmbH
V 2.8
Klasse Login:
private CustomerEntity m_customer = null;
...
@ManyToOne(optional = true,targetEntity = CustomerEntity.class)
@JoinColumn(name = "Customer_ID",insertable = true, updatable = true, nullable = true, unique =
false,referencedColumnName = "Customer_ID")
public CustomerEntity getCustomer() {
return m_customer;
}
public void setCustomer(CustomerEntity arg) {
m_customer = arg;
}
Listing 18: “OneToMany” Komposition - Many
ManyToOne Beispiel: Die Source Klasse UserRole (Source) hat eine Komposition mit der
Klasse AccessControl (Target) mit der Richtung Source->Destination (Navigation auf
AccessControl) und Multiplizität 1..*->1 (->AccessControl).
ManyToOne-Relation vom Entity AccessControl zum Entity UserRole (keine OneToMany
Rückverbindung zu UserRole):
Klasse UserRole:
private AccessControlEntity m_accessControl = null;
...
@ManyToOne(optional = true,targetEntity = AccessControlEntity.class)
@JoinColumn(name = "AccessControl_ID",insertable = true, updatable = true, nullable = false, unique =
false,referencedColumnName = "AccessControl_ID")
public AccessControlEntity getAccessControl() {
return m_accessControl;
}
public void setAccessControl (AccessControlEntity arg) {
m_accessControl = arg;
}
Listing 19: “ManyToOne” Komposition - Many
In diesem Beispiel gibt es keine cascade, nur eine starke Bindung (siehe Kapitel 2.1.1.3.2).
ManyToMany Beispiel: Die Source Klasse Contract (Target) hat eine Komposition mit der
Klasse ServiceDescription (Source) mit der Richtung Destination->Source (Navigation auf
TLGen
38
StarData GmbH
V 2.8
Source) und Multiplizität 1..*->1..* (->ServiceDescription).
ManyToMany-Relation von Contract zu ServiceDescription.
Dies
entspricht
einer
Anmerkung: Die Verwendung der mappedby-Funktion für ManyToMany wird in der
Konfigurationsdatei aktiviert (siehe Kapitel 4.5.2.2 <Project> Tag).
ManyToMany -Relation vom Entity Contract zum Entity ServiceDescription:
Klasse Contract:
private List<ServiceDescriptionEntity> m_serviceDescription = new ArrayList<ServiceDescriptionEntity>();
...
@ManyToMany(cascade =
{CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},mappedBy =
"contract",targetEntity = ServiceDescriptionEntity.class)
public List<ServiceDescriptionEntity> getServiceDescription() {
return m_serviceDescription;
}
public void setServiceDescription(List<ServiceDescriptionEntity> arg) {
m_serviceDescription = arg;
}
Listing 20: “ManyToMany” Komposition - Many 1
ManyToMany -Relation vom Entity ServiceDescription zum Entity Contract:
Klasse ServiceDescription:
private List<ContractEntity> m_contract = new ArrayList<ContractEntity>();
...
@ManyToMany(targetEntity = ContractEntity.class)
@JoinTable(name = "Contract_ServiceDescription",inverseJoinColumns = {@JoinColumn(name =
"Contract_ID",insertable = true, updatable = true, nullable = false, unique = false)},joinColumns =
{@JoinColumn(name = "ServiceDescription_ID",insertable = true, updatable = true, nullable = false, unique
= false)})
public List<ContractEntity> getContract() {
return m_contract;
}
public void setContract(List<ContractEntity> arg) {
m_contract = arg;
}
Listing 21: “ManyToMany” Komposition - Many 2
In beiden Entity-Klassen werden die anderen Entities der Relation in Array-Listen gespeichert,
genauso in den Daten-Klassen.
Die Mapping Tabelle Contract_ServiceDescription wird automatisch mit generiert (siehe Kapitel
3.5.1.4 Relation „ManyToMany“)
TLGen
39
StarData GmbH
V 2.8
2.1.1.3.2 Berechnete Relationen überschreiben
Die OneToOne-, OneToMany-, ManyToOne- und ManyToMany-Relationen, welche wie in
Kapitel 2.1.1.3.1 beschrieben, generiert wurden, kann man nochmals über die Einstellungen der
Default Konfigurationsdatei überschreiben.
Parameter:
-
overwrite: true, falls vorher Berechnetes überschrieben werden soll .
-
direction: true, die Richtungseinstellung soll verwendet werden.
-
optional: @JoinColumn-Parameter
-
insertable: @JoinColumn-Parameter
-
updateable: @JoinColumn-Parameter
-
cascade: z.B. @OneToMany-Parameter
Standardmäßig sind folgende Überschreibungen für die Relationen in der Konfigurationsdatei
aktiv:
-
OneToOne:
<Association type="OneToOne" name="OneToOne" overwrite="true" direction="true" optional="true"
insertable="true" updateable="true"/>
-
OneToMany:
<Association type="OneToMany" name="OneToMany" overwrite="true" direction="true" insertable="true"
updateable="true"/>
-
ManyToOne:
<Association type="ManyToOne" name="ManyToOne" overwrite="true" direction="true" optional="true"
insertable="true" updateable="true" cascade="null"/>
-
ManyToMany:
<Association type="ManyToMany" name="ManyToMany" overwrite="true" direction="true" optional="true"
insertable="true" updateable="true" cascade="PERSIST,MERGE,REMOVE"/>
TLGen
40
StarData GmbH
V 2.8
3 Beschreibung der generierten Komponenten (Java Klassen)
3.1 Daten Klassen - Interfaces
TLGen kann Daten, Klassen/Interfaces aus einem Domainmodell oder aus einer vorhandenen
Datenbank generieren. Es wandelt die Datenbank-Tabellen mit seinen Spalten in Klassen/Interfaces mit ihren Variablen um. Es wandelt Daten-Typen von Spalten in Java Daten-Typen um
wie in Table 2 dargestellt. Für Sonderwünsche der Typ-Verwendung kann in der Default-Konfigurationsdatei eine eigene Umwandlung definiert werden (siehe Kap. 4.4).
Table 2: Java-Typen
Nr.
Datenbank Type
Java (Code) Type
1
CHAR
char
2
NCHAR
char
3
DATE
java.util.Date
4
TIMESTAMP
java.util.Date
5
DECIMAL
double
6
BINARY_DOUBLE
double
7
BINARY_FLOAT
float
8
INTEGER
int
9
NUMBER
long
10
VARCHAR
java.lang.String
11
VARCHAR2
java.lang.String
12
NVARCHAR2
java.lang.String
13
LONG
java.lang.Long
14
RAW
java.lang.String
15
LONG RAW
byte[]
16
CLOB
java.lang.String
17
NCLOB
java.lang.String
18
BLOB
byte[]
19
TEXT
java.lang.String
20
LONGTEXT
java.lang.String
21
INT
int
22
BIGINT
long
23
DATETIME
java.util.Date
24
SMALLINT
short
TLGen
41
StarData GmbH
V 2.8
In Konfigurationsdateien ist es möglich auch die Klassen/Interface Path mit „extends“ zu
definieren. Diese „extends“ sind Basis-Klassen/Interfaces, die eventuelle Variablen beinhalten,
die die komplette Applikation beinhaltet und können vom TLGen Anwender geschrieben
werden. TLGen liefert auch diesen Code für Standard-Anwendungen mit. Diese Superklassen
sind für das Programm nicht unbedingt notwendig.
TLGen hat auch eigene Basis-Klassen/Interfaces, die als Default verwendet werden, falls der
TLGen Anwender nicht eigene schreibt. In Konfigurationsdateien werden auch das Path für
Klassen „Typen“ und „Enums“ definiert, falls diese in der Applikation verwendet werden.
TLGen generiert für die Relationen, die in der Datenbank oder in dem Domainmodell vorhanden
sind, entsprechende Variablen als Liste oder einfache Variablen wie für Interfaces:
public abstract List<CoPageDataIf> getPage();
public abstract void setPage(List<CoPageDataIf> arg);
Listing 22: Listen
private List<CoPageDataIf> m_page;
...
public List<CoPageDataIf> getPage() {
return m_page;
}
public void setPage(List<CoPageDataIf> arg) {
m_page = arg;
}
Listing 23: Klassen
Für die Klassen/Interfaces, die seitens Domainmodells generiert sind, werden alle Attribute
übernommen, persistente und nicht persistente, wobei in den SQL Skripten (die für die
Datenbank-Generierung notwendig sind) nur die persistenten Variablen verwendet werden.
Für die Klassen/Interfaces, die von einer vorhandenen Datenbank generiert werden, können
neue Variablen eingefügt werden, die nicht persistent sind.
3.1.1 Generierung von „JSon“-Klassen für REST calls
JSon, JavaScript Object Notation ist ein Datenformat, der für die Datenobjektdarstellung verwendet wird, notwendig für den Datenaustausch zwischen verschiedene Anwendungen.
TLGen generiert Daten-Klassen im JSon Format für die REST Schnittstellen.
Wenn in der Configdatei beim Tag <Project> ein Attribut „jsonData“ auf „true“ (als Defaultwert
ist für dieses Attribut „false“ gesetzt) gesetzt wird, dann wird für jede Daten-Klasse auch ein
JSon-Objekt generiert wie in Listing 24. Diese Klassen werden bei der gleichen Addresse wie
die Daten-Klassen generiert.
TLGen
42
StarData GmbH
V 2.8
@XmlRootElement(name = "login")
public class LoginJSon implements Serializable {
private static final long serialVersionUID = 310747291;
// Methods from columns
private String name;
private long loginID;
private String password;
private AuthTypeEnum authMethod;
private Date modifyDate;
// Methods from relations tables
private UnitJSon unit;
// Methods from columns
public String getName() {
return name;
}
public void setName(String arg) {
name = arg;
}
public long getLoginID() {
return loginID;
}
…
// Methods from relations tables
public UnitJSon getUnit() {
return unit;
}
public void setUnit(UnitJSon arg) {
unit = arg;
}
}
Listing 24: „JSon“ Data-Klasse
Durch das Attribut „pathJsonData“ kann aber eine andere Adresse für die Generierung von
„JSon“-Klassen verwendet werden, z.B. „pathJsonData=“de.firma.project.jsondata““.
3.1.2 Generierung von Mapping-Klassen zwischen Daten- und JSon-Klassen
Verwendet man das Attribut „mapping=“true““ in der Config Datei, Tag <Project> generiert
TLGen eine Mapping-Datei zwischen jeder Daten-Klasse und eine JSon-Datenklasse in beide
Richtungen wie in Listing 25.
TLGen
43
StarData GmbH
V 2.8
/**
* This class map the class data to JSon class data and inverse
*/
public class UserMap implements Serializable {
private static final long serialVersionUID = 268222648;
// Mapping methods between class data and JSon data objects
/**
* Map "UserData" object to "UserJSon" object data
* @param json
* @return
*/
public static UserData mapJSonToData(UserJSon json) {
UserData data = new UserData();
data.setName(json.getName());
data.setEmail(json.getEmail());
data.setFirstName(json.getFirstName());
data.setUserID(json.getUserID());
data.setTelefon(json.getTelefon());
data.setLastName(json.getLastName());
data.setModifyDate(json.getModifyDate());
data.setLogin(getLoginJSon(json.getLogin()));
data.setUserRole(getUserRoleJSonList(json.getUserRole()));
return data;
}
/**
* Map "UserJSon" object to "UserData" object data
* @param data
* @return
*/
public static UserJSon mapDataToJSon(UserData data) {
UserJSon json = new UserJSon();
json.setName(data.getName());
json.setEmail(data.getEmail());
json.setFirstName(data.getFirstName());
json.setUserID(data.getUserID());
json.setTelefon(data.getTelefon());
json.setLastName(data.getLastName());
json.setModifyDate(data.getModifyDate());
json.setLogin(getLoginData(data.getLogin()));
json.setUserRole(getUserRoleDataList(data.getUserRole()));
return json;
}
/**
* Helper method for mapping
* @param data
* @return
*/
private static LoginData getLoginJSon(LoginJSon data) {
LoginData objLogin = null;
if(data != null) {
objLogin = LoginMap.mapJSonToData(data);
TLGen
44
StarData GmbH
V 2.8
}
return objLogin;
}
/**
* Helper method for mapping
* @param list
* @return
*/
private static List<UserRoleData> getUserRoleJSonList(List<UserRoleJSon> list) {
List<UserRoleData> listUserRole = null;
if(list != null && !list.isEmpty()) {
listUserRole = new ArrayList<UserRoleData>();
for(UserRoleJSon json : list) {
if(json != null) {
UserRoleData data = UserRoleMap.mapJSonToData(json);
listUserRole.add(data);
}
}
}
return listUserRole;
}
/**
* Helper method for mapping
* @param data
* @return
*/
private static LoginJSon getLoginData(LoginData data) {
LoginJSon objLogin = null;
if(data != null) {
objLogin = LoginMap.mapDataToJSon(data);
}
return objLogin;
}
/**
* Helper method for mapping
* @param list
* @return
*/
private static List<UserRoleJSon> getUserRoleDataList(List<UserRoleData> list) {
List<UserRoleJSon> listUserRole = null;
if(list != null && !list.isEmpty()) {
listUserRole = new ArrayList<UserRoleJSon>();
for(UserRoleData data : list) {
if(data != null) {
UserRoleJSon json = UserRoleMap.mapDataToJSon(data);
listUserRole.add(json);
}
}
}
return listUserRole;
}
}
Listing 25: Mapping zwischen einer Data-Klasse und einer„JSon“ Data-Klasse
TLGen
45
StarData GmbH
V 2.8
Das Attribut „mapping“ ist als „true“ gesetzt, aber wird nur wenn auch das Attribut „jsonData“
gesetzt ist, verwendet. Falls nur die Generierung von JSon-Klassen jedoch nicht die MappingKlassen gebraucht werden, sollte man das - Attribut „mapping=“false““ verwenden.
3.2 Session Bean
Session Bean ist eine wichtige Klasse und die erste Klasse, welche von einem Client über RMI
aufgerufen wird. Sie hat innerhalb von EJB3 eine vordefinierte Form und kann mit mehreren
Annotationen verwendet werden (siehe Tabelle 3: Session Bean Annotationen).
Mit Hilfe der Steuerung über die Konfigurationsdateien können für die Session Beans folgende
Features generiert werden:

Annotationen mit Parameter

Selbst geschriebene „extends“-Klassen oder die von TLGen Default Session Bean
Basis-Klassen

Interceptoren (siehe 3.2.4)

Clients (siehe 3.3)

Entity Manager-Klassen (siehe 3.4)

Entities Beans (siehe 3.5)

XML Persistente Datei (siehe 3.2.2)

Definiert die Methoden, die vom Client aufgerufen werden. Diese Methoden können von
den Manager-Klassen übernommen werden.

Kann bestimmen, welcher Transaktionentyp verwendet wird.

Interface-Klassen, welche die Verbindung zwischen generiertem Code und Fachcode
ermöglichen.
Tabelle 3: Session Bean Annotationen
Annotationen
Verwendung
in TLGen 2.7
Kommentar
javax.ejb.Stateless
ja
Definiert eine Stateless Session Bean
javax.ejb.Stateful
ja
Definiert eine Stateful Session Bean
javax.ejb.EJB
ja
Definiert eine lokale References z. B. Name
einer Manger-Interface (siehe 2.5)
javax.ejb.Remote
ja
Bezeichnet eine Remote Verwendung von
Session Bean
javax.ejb.Local
ja
Für eine Lokale Verwendung
javax.ejb.ApplicationException
nein
javax.ejb.EJBs
ja
javax.ejb.Init
nein
TLGen
Definiert eine oder mehreren EJB Annotationen
46
StarData GmbH
V 2.8
javax.ejb.LocalHome
nein
Entspricht nicht der Philosophie von EJB3
javax.ejb.PostActivate
ja
Methode wird nach dem Aktivierung von
Session Bean aufgerufen
javax.ejb.PrePassivate
ja
Nur für Stateful Session Bean
javax.ejb.RemoteHome
nein
Entspricht nicht der Philosophie von EJB3
javax.ejb.Remove
ja
Call Methode mit den Annotation PreDestroy
(nur für Stateful Session Bean)
javax.ejb.Timeout
ja
Session Bean wird nach Ablauf von timeout
verworfen
javax.ejb.TransactionAttribute
ja
Transaction Type (REQUIRED, MANDATORY,
etc.)
javax.ejb.TransactionManagement
ja
Transaction management (CONTAINER or
BEAN)
javax.jws.Web Service
ja
Definiert eine Service die über www aufgerufen
werden kann
Für eine Session Bean kann man eine oder mehrere Manager-Klassen mit deren Anweisungen
für eine optimale TLGen-Verwendung in IT Projekten aufrufen.
Von einem Domainmodell kann für jedes Package eine Session Bean generiert werden und innerhalb der Session Bean für jedes Element-Objekt ein Tandem vom Manager, Entity Bean
sowie eine Datenbank-Tabelle.
Für die Legacy-Projekte (Refactoring), die auf Basis einer vorhandenen Datenbank durchgeführt werden, soll in der Konfigurationsdatei eine Tabellenliste, zugehörig zu einer Session
Bean, vorhanden sein.
Session Bean Code Beispiel:
package eu.stardata.server.core.formular;
import eu.stardata.server.core.formular.bci.ExecBci;
import eu.stardata.server.core.formular.bci.TablecolBci;
…
import javax.ejb.EJB;
@Stateless(name = FormularBci.JNDI_NAME, mappedName = "efp/"+FormularBci.JNDI_NAME+"/remote")
@Remote(FormularBci.class)
public class FormularSessionBean extends BaseSessionBean implements FormularBci {
private static final long serialVersionUID = 196502766;
// Session annotations and fields for local manager
@EJB
private EntryBci m_EntryBci;
…
/**
* Session method "createEntry()"
* @param arg
* @return
* @throws PersistenceException
*/
public CoEntryDataIf createEntry(CoEntryDataIf arg) throws PersistenceException {
try {
TLGen
47
StarData GmbH
V 2.8
return m_EntryBci.create(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex,1);
}
}
}
Listing 26: Session Bean
3.2.1 Interfaces für eine Session Bean
Session Bean benötigt eine Interface mit allen definierten Methoden, die vom Client aufgerufen
werden. Diese Interfaces für Session Bean verwenden zwei Annotationen:
@Remote für eine Remote-Verbindung vom Client sowie @Local für eine lokale Verwendung.
In diesem Interface sind auch drei vordefinierte Variablen, die für EJB3 sehr wichtig sind:



String JNDI_NAME = Wert, ist der notwendige Name für den Client-Aufruf und eindeutig
für die gesamte Applikation. TLGen verwendet für diese Variable den Inhalt des
kompletten Session Bean Namens, z. B.
"eu.stardata.server.core.formular.FormularSessionBean"
String MANAGER_NAME = "managerFormular". Diese Variable ist für die Verwendung
der Manager-Klasse (siehe Kapitel 3.4) wichtig.
String EAR_NAME = "efp". Diese Variable bekommt den Wert aus der
Konfigurationsdatei und wird in der XML Persistenz-Datei verwendet (siehe Kapitel
3.2.2).
Ein Beispiel für ein Session Bean Interface als „Remote“:
package eu.stardata.client.core.formular.bci;
import eu.stardata.core.form.dataif.CoRuletypeDataIf;
…
import eu.stardata.core.form.dataif.CoRulefieldDataIf;
import javax.ejb.Remote;
import java.lang.String;
import eu.stardata.core.form.dataif.CoFormularDataIf;
import eu.stardata.server.common.exception.PersistenceException;
import eu.stardata.core.form.dataif.CoExecDataIf;
@Remote
public interface FormularBci {
// Client interface Fields
public final static String JNDI_NAME = "eu.stardata.server.core.formular.FormularSessionBean";
public final static String MANAGER_NAME = "managerFormular";
public final static String EAR_NAME = "efp";
// Session - Client interface methods
public void clearExec() throws PersistenceException;
public CoFieldDataIf createField(CoFieldDataIf arg) throws PersistenceException;
public CoFieldDataIf[] findAllField() throws PersistenceException;
…
public CoElementDataIf createElement(CoElementDataIf arg) throws PersistenceException;
public void clearWebstyle() throws PersistenceException;
}
TLGen
48
StarData GmbH
V 2.8
Listing 27: Session Bean Interface
3.2.2 XML Persistente Datei
Ab EJB 3 ist nur eine XML Datei für ein Deployment Description notwendig. Alle anderen
Dateien der Vorversionen werden entweder abgeschafft oder als Annotation verwendet.
Zusätzlich gibt es noch eine XML Datei „orm.xml“ für das Mapping für Version 3 von EJB, doch
diese wird wegen der Performance mit TLGen nicht benützt. TLGen erlaubt das Mapping direkt
im generierten Java Code und zwar in den Entity Beans (siehe Kapitel 3.5 sowie 4.4.2.5).
In der Datei „persistence.xml“, die für jede Session Bean generiert wird, sind folgende Informationen automatisch enthalten:

In Tag „persistence-unit“ die Parameter name  ManagerName Variable und
Transaction-type

In Tag „jta-data-source“ die Data Source im Format, welche der jeweilige Applikation
Server benötigt (jede mit eigenem Format)

Eine vollständige Liste von allen in der Applikation vorhandenen Entity Beans mit
vollständig definierten Namen

In Tag „propertie“ allgemeine Informationen für den Application Server
Ein Beispiel für eine generierte „persistence.xml“:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name = "managerFormular" transaction-type = "JTA">
<jta-data-source>java:/efpPool</jta-data-source>
<class>eu.stardata.server.core.user.entity.UserEntity</class>
<class>eu.stardata.server.core.hlp.entity.OperationEntity</class>
<class>eu.stardata.server.core.hlp.entity.FormatEntity</class>
<class>eu.stardata.server.core.hlp.entity.KeyEntity</class>
<class>eu.stardata.server.core.formular.entity.FieldEntity</class>
<class>eu.stardata.server.core.hlp.entity.FieldtypeEntity</class>
………………………………………………..
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
</properties>
</persistence-unit>
</persistence>
Listing 28: Persisitence XML
In der Datei „persistence.xml“ können einige Informationen, vom Applikation Server benötigt, (in
einer „properties“ Tag) definiert werden.
Hinweis: Für den Applikation Server „JBoss“ Version 5 sollte die Oracle Datenbank in Version
10 benutzt werden, da diese Version von „JBoss“ noch nicht die Oracle Version erkennt!
TLGen
49
StarData GmbH
V 2.8
3.2.3 Interface-Klassen zu Fachlogik(Bussiness logic)-Komponenten
Innerhalb einer Session Bean kann bzw. können eine oder mehrere Klassen definiert werden,
die zu oder von anderen Systemen gehören bzw. aufgerufen werden oder für die Kodierung
reiner Fachlogik benötigt werden. Wurden diese einmal generiert, lässt der Generator es zu,
diese dort abzuspeichern, um den dort manuell entwickelten Code nicht zu löschen.
Nach unserer Erfahrung ist es weder produktiv noch notwendig generierten Code mit selbst
entwickelten zu mischen (merging). Daher ermöglicht TLGen eine vollständige Trennung dieser
Code-Arten.
3.2.4 Interceptors
Ein Interceptor ist eine einfache Java Klasse deren Methoden immer dann aufgerufen werden,
wenn Session Bean-Methoden benützt werden. Die Interceptoren sind Klassen, die eigentlich
zum Beispiel unter anderem zur Überwachung einer Session Bean, Übernahme der Informationen-Protokollierung oder für die Zeitmessung gedacht sind.
Diese Java Klassen können über die Konfigurationsdateien in den generierten Code eingebettet
werden. Es können entweder selbst geschriebene Klassen sein oder die, welche von TLGen
Default-Interceptoren zur Verfügung gestellt werden.
Einfaches Bespiel von einer Interceptor-Klasse für die Zeitmessung (siehe Listing 29):
public class TimeFormular
{
// Session annotations and fields for interceptor
/**
* Default Constructor
*/
public TimeFormular() {
super();
}
// Session class methods
/**
* Interceptor method "timeTrace()"
* @param invocation
* @return
* @throws PersistenceException
*/
@AroundInvoke
public java.lang.Object timeTrace(InvocationContext invocation) throws PersistenceException {
long start = 0;
boolean toTime = true;
try {
if(toTime)
{
start = System.currentTimeMillis();
}
return invocation.proceed();
TLGen
50
StarData GmbH
V 2.8
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex,1);
}
Finally {
if(toTime) {
// Example to time
long ende = System.currentTimeMillis();
String klasse = invocation.getTarget().toString();
String methode = invocation.getMethod().getName();
System.out.println(klasse + ":" + methode + " -> " + (ende - start) +
"ms");
}
}
}
}
Listing 29: Interceptor
3.2.5 Generierung der REST-Schnittstelle
Um eine REST-Schnittstelle zu generieren, muss ein <Design> mit dem Attribute archive=“3“
angelegt werden. In der Tag <Session> wird das Attribute sessionType="REST" gesetzt und
dadurch wird automatisch eine Application-Klasse mit generiert. Diese verwendet
standardmäßig das Attribute „appPath“ als Namenzusatz. Da appPath=““ als konformer Application Pfad „/“ auch verwendet wird, wird der Designname als Namenzusatz verwendet. Das
Attribute „restPath“ gibt den Pfad der Session Beans an.
URL-Erstellung: Eine URL, wie folgt, wird folgendermaßen erstellt:
http://DOMAIN/<War path>/<Application path>/<Sessionbean path>



“War path” in <Design pathToGenerate="warname" >
„Application path“ in <Session appPath="appname" >
„ Sessionbean path“ in <Session restPath="sessionname" >
Um den Bsp.-Pfad http://DOMAIN/rest/service zu generieren, sollte z.B.


<Design pathToGenerate="rest" >
<Session appPath="" restPath="service" >
Rest-Methoden:
Es gibt 2 Generierungsarten von Rest-Methoden, die automatische (mit Voreinstellungen) und
die genauer einstellbare.
Methode 1: Diese Methode verwendet den Methoden-Namen automatisch, um den Pfad
festzulegen z.B.(siehe Listing 30)
<Method name="updateWorkOrder" return="java.util.List<de.test.business.service.WorkOrderJSon>"
client="Rest" rest="PUT" methodtype="0">
<Exception name="java.lang.Exception"/>
<Parameter value="Path" name="workorderid" type="java.lang.Long"/>
<Parameter value="Query" name="customerid" type="java.lang.Long"/>
TLGen
51
StarData GmbH
V 2.8
<Parameter name="data" type="de.test.business.service.WorkOrderJSon" />
</Method>
Listing 30: REST-Methode in der Konfigurationsdatei
Pfad: http://DOMAIN/rest/service/updateWorkOrder
Folgende REST-Typen generieren weitere Annotationen automatisch dazu:




Typ GET: Generiert automatisch die Annotation @Produces("application/json")
Typ DELETE: Generiert automatisch die Annotation @Produces("application/json")
Typ PUT: Generiert automatisch die Annotationen @Produces("application/json"),
@Consumes ("application/json")
Typ POST: Generiert automatisch die Annotation @Produces("application/json")
Damit dies auch mit der zuvor genannten Methode funktioniert, muss der letzte Parameter des
Methoden-Tags der „Consumer“ sein. Der “Producer” ist im Attribute „return“ festgelegt:
<Parameter name="data" type="de.test.business.service.WorkOrderJSon" />
Die Methode wird folgendermaßen generiert (siehe Listing 31):
@PUT
@Path("/updateWorkOrder/{workorderid}/")
@Produces("application/json")
@Consumes("application/json")
public List<WorkOrderJSon> updateWorkOrder(
@PathParam("workorderid") java.lang.Long workorderid,
@QueryParam("customerid") java.lang.Long customerid,
WorkOrderJSon data) throws Exception;
Listing 31: REST Methode Parameter
Der vollständige Pfad der Applications-Methode ist dann z.B.:
http://DOMAIN/rest/service/updateWorkOrder/1
Die Parameter-value sind „Query“ oder „QueryParam“ für @QueryParam und „Path“ oder
„PathParam“ für @PathParam (Die Abkürzungen gelten nur für diese beiden sowie für
Methode 2).
Method 2: Diese Methode ermöglicht, die Pfade und alle Tags genau zu definieren. Hier ist es
wichtig, das Annotations-Typen und Libs, welche nicht standardmäßig bekannt sind, mit dem
vollständigen Namen anzusprechen. Um diese Methode zu verwenden, muss man nur eine
Annotation mit name=“Path“ definieren.
Oben genanntes Beispiel ist folgendermaßen dann definiert (siehe Listing 32):
<Method name="updateWorkOrder" return="java.util.List<de.test.business.service.WorkOrderJSon>"
client="Rest" rest="PUT" methodtype="0">
<Exception name="java.lang.Exception"/>
<Annotation name="Path" value="workorder/{workorderid}/"/>
<Annotation name="Produces" value="application/json"/>
<Annotation name="Consumes" value="application/json"/>
<Parameter value="PathParam" content="workorderid" name="workorderid" type="java.lang.Long"/>
TLGen
52
StarData GmbH
V 2.8
<Parameter value="QueryParam" name="customerid" type="java.lang.Long"/>
<Parameter name="data" type="de.test.business.service.WorkOrderJSon" />
</Method>
Listing 32: REST-Annotations und Parameter in der Konfigurationsdatei
Wobei der Pfad hier @Path("/workorder/{workorderid}/") ist.
Freie Annotationen und Parameter:

Um eine freie Annotation @org.jboss.resteasy.annotations.providers.jaxb.XmlHeader
zu erhalten, genügt folgender Parameter:
<Annotation name="org.jboss.resteasy.annotations.providers.jaxb.XmlHeader"/>
Um eine Klasse als value zu erhalten, muss diese im Attribute „type” definiert werden,
z.B.:
@Consumes(MediaType.APPLICATION_ATOM_XML) mit
<Annotation type="Consumes" type="MediaType.APPLICATION_ATOM_XML" />
da im Attribute value, der String mit Hochkomma eingefügt wird.

Auch freie Parameter sind nun erlaubt:
Beispiel Listing 33:
<Method name="createUnit" return="de.test.business.unit.UnitJSon" client="Rest" rest="POST" methodtype="0">
<Exception name="java.lang.Exception"/>
<Annotation name="Path" value="unit/{unitid}/"/>
<Annotation name="org.jboss.resteasy.annotations.providers.jaxb.XmlHeader"
type="MediaType.APPLICATION_ATOM_XML"/>
<Annotation name="Produces" value="application/json"/>
<Annotation name="Consumes" value="application/json"/>
<Parameter value="CookieParam" content="id" name="sessionid" type="javax.ws.rs.core.Cookie"/>
<Parameter value="PathParam" content="unitid" name="unitid" type="java.lang.Long"/>
<Parameter value="QueryParam" name="imei" type="java.lang.String"/>
<Parameter value="QueryParam" name="customerid" type="java.lang.Long"/>
<Parameter name="data" type="de.test.business.unit.UnitJSon"/>
</Method>
@POST
@Path("/unit/{unitid}/")
@XmlHeader(MediaType.APPLICATION_ATOM_XML)
@Produces("application/json")
@Consumes("application/json")
public UnitJSon createUnit(
@CookieParam("id") Cookie sessionid,
@PathParam("unitid") java.lang.Long unitid,
@QueryParam("imei") String imei,
@QueryParam("customerid") java.lang.Long customerid,
UnitJSon data) throws Exception;
Listing 33: REST Beispiel
3.2.5.1 Client-Seite
TLGen
53
StarData GmbH
V 2.8
Zu den REST-Services werden auch automatisch JUnit-Client-Testmethoden hinzugeneriert.
Falls „Consumer“ bekannt ist, werden diese automatisch mitgeneriert (dafür wird für JSON die
Gson google jar benötigt). Ein einfacher HTTPClient wird mitgeneriert. Dieser ist einfach für
weitere Header-Aurufe erweiterbar, um z.B. mittels eines Server-Interceptors die REST-Calls
mit einem REST-Auth abzufangen und zu überprüfen.
Ein Beispielcode dazu (siehe Listing 34):
System.out.println("----------- testupdateRoutings() -----------");
// Initialise input parameters
Gson gson0 = new GsonBuilder().setDateFormat(DATE_FORMAT).create();
RoutingJSon json0 = new RoutingJSon();
json0.setEndDate(new Date(System.currentTimeMillis()));
json0.setStartDate(new Date(System.currentTimeMillis()));
json0.setRoutingID(3L);
json0.setNextDestinationSite("4473");
json0.setModifyDate(new Date(System.currentTimeMillis()));
//fill the values for methods
//json0.setUnit(de.test.business.unit.UnitJSon);
List<RoutingJSon> list = new ArrayList<RoutingJSon>();
list.add(json0);
String strJSon = gson0.toJson(list);
// REST call
String strContent = "/?customerid=3";
String strResponse = this.getHttpClient("PUT","http://localhost:8080/rest/service/routing" +
strContent,"application/json",strJSon);
// print return data
if(strResponse != null)
{
System.out.println("strResponse :" + strResponse);
}
else
{
System.out.println("ReturnObject is null !!!");
}
Listing 34: REST-calls vom Client
3.3 Clients, BCI (Business Common Interface)
Auf der Client -Seite befindet sich das User Interface, mit dem dieser die Applikation aufrufen
kann. Auf dem Server hingegen befindet sich die Applikation-Logik mit dem benötigten Code.
TLGen generiert vollständig die Klassen, welche für die Kommunikation zwischen Client und
Server notwendig sind. Für den Client generiert TLGen auch die Test-Klassen (auf Basis von
JUnit), die für die Applikation-Tests benötigt werden.
Beispiel für einen generierten Server-Aufruf (siehe Listing 35), um einen Satz in einer
Datenbank abzuspeichern:
CoFormularDataIf clFormular = getFormularObject();
// make a factory client for call the session bean
FormularBci factory = FormularBciFactory.getFormularBci();
TLGen
54
StarData GmbH
V 2.8
// call the session bean method over the client factory
clFormular = factory.createFormular(clFormular);
Listing 35: Server Remote Call
Dieser Serveraufruf ist wie folgt durchzuführen: Zuerst ruft man die notwendige Factory (diese
entspricht in der Regel einer bestimmten Session Bean auf der Serverseite) und danach mit
Hilfe der Factory die gewünschte Methode auf. Im oberen Beispiel wird die Abspeicherung in
der Datenbank eines Formular-Objekts dargestellt.
TLGen generiert zwei Klassen/Interfaces, die diese Aufgabe erfüllen. In unserem Beispiel die
Klasse FormularBciFactory.java und das Interface FormularBci.java, Teil des generierten
Codes für die Factory:
/**
* getFormularBci()
*/
public static synchronized FormularBci getFormularBci() throws PersistenceException {
return (FormularBci)getBciImplementation(FormularBci.class);
}
Listing 36: Client Class
Als auch für die Interfaces:
@Remote
public interface FormularBci {
// Client interface Fields
public final static String JNDI_NAME = "eu.stardata.server.core.formular.FormularSessionBean";
public final static String MANAGER_NAME = "managerFormular";
public final static String EAR_NAME = "efp";
…
public CoFormularDataIf createFormular(CoFormularDataIf arg) throws PersistenceException;
…
}
Listing 37: Client Interface
3.3.1 Test-Klassen
TLGen kann Test-Klassen (JUnit) generieren. Diese können gändert werden und sind als Hilfe
für die Realisierung eines Test-Konzeptes gedacht.
TLGen generiert für die gewünschten Aufrufe die kompletten Test-Klassen mit generierten TestWerten oder aus einer Daten-Datei die geladenen Test-Daten. Für welche Aufrufe die TestKlassen (JUnit) zu generieren sind, soll in der Konfigurationsdatei eingetragen werden (für
weitere Details siehe Kapitel 4.5.2.4.8).
TLGen
55
StarData GmbH
V 2.8
Test-Klassen kann man testen und die Ergebnisse in einer Datei printen oder direkt auf den
Bildschirm ausgeben (z. B. in Eclipse). Auch kann man diese im JUnit, wo sie mit Hilfe der
Asset-Methode zur Verfügung gestellt werden, ersehen. Listing 38 zeigt ein Beispiel für eine
Test-Klasse:
public class FormularWriteReadTest extends TestCase {
private static final long serialVersionUID = 435512065;
// Test class data fields
private static CoFormularDataIf m_clFormular = null;
/**
* Default Constructor
*/
public FormularWriteReadTest() {
super();
// Insert your configuration data for application server
de.stardata.base.config.InitProgramm.put(de.stardata.base.config.ConfigKeyNames.INITIAL_CONTEXT,"jn
p://localhost:9099");
de.stardata.base.config.InitProgramm.put(de.stardata.base.config.ConfigKeyNames.INITIAL_CONTEXT_F
ACTORY,"org.jnp.interfaces.NamingContextFactory");
de.stardata.base.config.InitProgramm.put(de.stardata.base.config.ConfigKeyNames.INITIAL_PKG_PREFIX
ES,"org.jboss.naming:org.jnp.interfaces");
}
// Test class methods
/**
* Test method "testCreateFormular()"
*/
public void testCreateFormular() {
try {
m_clFormular = new CoFormularData();
// initialize data for test class
m_clFormular.setCoreId(3);
……………………………………………………………………..
m_clFormular.setLanguage(writeLanguage());
m_clFormular.setMandant(writeMandant());
// make a factory client for call the session bean
FormularBci factory = FormularBciFactory.getFormularBci();
// call the session bean method over the client factory
m_clFormular = factory.createFormular(m_clFormular);
// print the new primary key
System.out.println("New primary key is = " + m_clFormular.getFormularId());
} catch(PersistenceException ex) {
ex.printStackTrace();
}
}
Listing 38: Test-Klasse - Beispiel
3.3.1.1 Attribute für <Test> Tag Annotation
Für Test-Klassen können mehrere Attribute verwendet werden, um so die Generierung zu
steuern (siehe Tabelle 4).
TLGen
56
StarData GmbH
V 2.8
Tabelle 4: Attribute für <Test> Tag-Annotation
Attributen
Default
Name
nein
Kommentar
Test-Klasse Name mit vollem path
sessionType
ja
Generiert folgende Test-Klassen Typen: „Session“ ist eine
normale Test-Klasse für eine Remote Verbindung und „REST“,
generiert eine Client Test-Klasse für ein REST call
client
nein
Definiert den Namen des Clients
type
ja
public (ist default), protected oder private
3.3.1.2 Verwendung von Test-Daten aus externen Dateien
Mit Hilfe der Konfigurationsdateien kann man eine XML Datei generieren, welche die Datenstruktur einer oder mehrerer Test-Objekte nachbildet. Diese XML kann mit den gewünschten
Daten erweitert und für Tests genutzt werden. Diese Datei wird in Listing 39: Externe TestDaten4 dargestellt.
<?xml version="1.0" encoding="UTF-8"?>
<TestMethod xsi:noNamespaceSchemaLocation = "C:/Project-TLGen-2.1/source/generated/TestDataSchema.xsd"
name = "testCreateFormular" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" type = "void">
<Variable name = "FormularId" value = "2" type = "long"/>
<Variable name = "CoreId" value = "2" type = "long"/>
………………………………………………………………………………………………..
<Variable name = "Document_id" value = "2" type = "long"/>
……………………………………………………………………………………………….
<Method name = "writeMandant" type = "eu.stardata.core.cor.dataif.CoMandantDataIf">
<Variable name = "MandantId" value = "4" type = "long"/>
………………………………………………………………………………………………..
<Variable name = "Code" value = "-628" type = "java.lang.String"/>
</Method>
</TestMethod>
Listing 39: Externe Test-Daten
Die verwendete Schema-Datei “TestDataSchema.xsd” hat folgende Struktur:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--W3C Schema generated by XMLSpy v2009 (http://www.altova.com)-->
<!--Please add namespace attributes, a targetNamespace attribute and import elements according to your
requirements-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xs:element name="Variable">
<xs:complexType>
<xs:attribute name="name" use="required" type="xs:anySimpleType"/>
<xs:attribute name="type" type="xs:anySimpleType"/>
<xs:attribute name="value" type="xs:anySimpleType"/>
</xs:complexType>
</xs:element>
<xs:element name="Type">
TLGen
57
StarData GmbH
V 2.8
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Variable"/>
<xs:element ref="Type"/>
<xs:element ref="Enum"/>
</xs:choice>
<xs:attribute name="name" use="required" type="xs:anySimpleType"/>
<xs:attribute name="type" type="xs:anySimpleType"/>
</xs:complexType>
</xs:element>
<xs:element name="TestMethod">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Variable"/>
<xs:element ref="Method"/>
<xs:element ref="Type"/>
<xs:element ref="Enum"/>
</xs:choice>
<xs:attribute name="name" use="required" type="xs:anySimpleType"/>
<xs:attribute name="type" type="xs:anySimpleType"/>
</xs:complexType>
</xs:element>
<xs:element name="Method">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Type"/>
<xs:element ref="Enum"/>
<xs:element ref="Variable"/>
<xs:element ref="Method"/>
</xs:choice>
<xs:attribute name="name" use="required" type="xs:anySimpleType"/>
<xs:attribute name="type" type="xs:anySimpleType"/>
</xs:complexType>
</xs:element>
<xs:element name="Enum">
<xs:complexType>
<xs:attribute name="name" use="required" type="xs:anySimpleType"/>
<xs:attribute name="type" type="xs:anySimpleType"/>
<xs:attribute name="value" type="xs:anySimpleType"/>
</xs:complexType>
</xs:element>
</xs:schema>
Listing 40: XML Schema für externe Test-Daten
3.3.1.3
“Junit” Test-Klasse für “REST”-calls
Siehe Kapitel 3.2.5.1
3.4 Entity Manager-Klasse
Eine Entity Manager-Klasse ist eine lokale Stateless Session Bean, die für die Steuerung der
Persistenz (Entity Bean) genutzt wird.
Entity Manager-Klassen können Default-Methoden für Datenbank-Administration für CRUD sein
oder aber auch Datenbank-Zugriffsmethoden, generiert auf Basis von selbst geschriebenen
SQL’s. In Tabelle 5 sind die Default-Methoden, welche TLGen automatisch generieren kann:
TLGen
58
StarData GmbH
V 2.8
Tabelle 5: Automatisch generierbare Default-Methoden im Entity Manager
Nr.
Method Name
Parameter
Return
Funktionalität
1
create“Name“
Objekt
Objekt
Speichern eines neuen Objekts in
der Datenbank
2
update“Name“
Objekt
void
Aktualisieren eines Objekts
seine Kinder in der Datenbank
und
3
remove“Name“
Object
-
Löschen eines
Datenbank
der
4
flusch“Name“
Object
-
Beenden des Vorgangs
5
close“Name“
-
-
Schließt ein Entity Objekt ein
6
clear“Name“
-
-
7
findByPrimaryKey“Name“
Object
PK
8
findAll“Name“
9
mit
Objekts
in
Object
Lesen eines Objekts aus DB mit dem
PK
-
Object[]
Lesen aller abgespeicherten Objekte
findBy“Name“
Parameter
List
Object[]
Lesen
aller
Parameter List
10
deleteBy“Name“
Parameters,
level
int
Löschen aller Daten (Zeile in der
betroffenen Tabelle) in der Datenbank für die eingegebenen Parameter. Falls für diese Entity Bean
auch Links existieren, werden auch
diese alle gelöscht
11
detach
Object
void
Detach Methode
12
readUpdate
Object
-
Lesen des Objekts ID, dann update
dieses Objekts in Database
13
fullUpdate
Object
-
Zuerst werden die Daten aus der
Datenbank gelesen, dann erfolgt die
Aktualisierung der Daten mit all
seinen Kindern (OtO, OtM, OtO MtM)
in der Datenbank
14
getEntityManager
-
EntityManager
Übernimmt
die
“javax.persistence.EntityMnager”
local Variable
15
getManager
Object
Object
Übernimmt eine instance aus der
Entity Manager-Klasse
Objekte
für
die
Ein Beispiel für generierten Code aus Fehler! Verweisquelle konnte nicht gefunden
werden., Zeile 9 ist in Listing 41 dargestellt:
TLGen
59
StarData GmbH
V 2.8
public class ProductManager extends BaseManager implements ProductBciIf {
private String m_getNameAndOffer = "select u from ProductEntity u
where u.name = :name and u.productOfferingId = :productOfferingId";
………………………………………………………………
/**
* Manager method "findByNameAndOffer()"
* @param name
* @param productOfferingId
* @return
* @throws PersistenceException
*/
public ProductDataIf[] findByNameAndOffer(String name, String productOfferingId) throws
PersistenceException {
try {
ProductDataIf[] listData = null;
List<?> list = m_manager.createQuery(m_getNameAndOffer).setParameter("name",
name).setParameter("productOfferingId",productOfferingId).getResultList();
if(list != null && list.size() > 0) {
listData = new ProductDataIf[list.size()];
int idx = 0;
for(Object entity : list) {
if(entity != null) {
listData[idx++] = ((ProductEntity)entity).callProduct();
}
}
}
return listData;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex,1);
}
}
………………………………………………………………..
}
Listing 41: “Find by name” Method
Das Lesen, Abspeichern oder Löschen von Objekten kann direkt im Aufruf gesteuert werden,
ob nur das „Vater“ Objekt gelesen, gespeichert oder gelöscht wird oder aber dieser zusammen
mit seinen „Kindern“ (solange die Beziehungen zwischen diesen „Null“ akzeptiert).
Für das selbst geschriebene SQL bietet TLGen eine Fülle von Modellen an, die sehr einfach in
der Konfigurationsdatei zu nutzen sind, mit der letztendlich TLGen den entsprechenden Code
generiert. In der Regel ist es nur sehr selten notwendig ein solches SQL zu schreiben, weil
durch automatisches Einbeziehen von Relationen alle benötigten Objekte gelesen und
abgespeichert werden.
Es folgt ein Ausschnitt einer generierten Manager-Klasse (siehe Listing 42):
package eu.stardata.server.core.formular.manager;
import javax.persistence.EntityManager;
………………………………………………..
import javax.ejb.Local;
@Stateless(name = eu.stardata.server.core.formular.bci.FormularBci.JNDI_NAME)
@Local(eu.stardata.server.core.formular.bci.FormularBci.class)
TLGen
60
StarData GmbH
V 2.8
public class FormularManager extends BaseManager implements eu.stardata.server.core.formular.bci.FormularBci {
private static final long serialVersionUID = 644414680;
// Manager class data fields
@PersistenceContext(unitName = FormularBci.MANAGER_NAME)
public EntityManager m_manager = null;
private String m_getName = "select o from FormularEntity o where o.formular = :formular";
private String m_SQL_FIND_ALL = "select o from FormularEntity o";
…………………………………………………………………
/**
* Manager method "findByPrimaryKey()"
* @param arg
* @return
* @throws PersistenceException
*/
public CoFormularDataIf findByPrimaryKey(CoFormularDataIf arg) throws PersistenceException {
try
{
CoFormularDataIf classData = null;
FormularEntity entity = m_manager.find(FormularEntity.class, arg.getFormularId());
if(entity != null){
classData = entity.callFormular();
}
return classData;
} catch(Exception ex){
throw new PersistenceException(ex.getMessage(),ex,1);
}
}
……………………………………………….
}
Listing 42: “Find by Primary Key” Method
Alle in den Manager-Klassen verwendeten Methoden können von den dazugehörigen Session
Beans übernommen werden oder auch nicht. Dies kann über die Konfigurationsdatei gesteuert
werden (Default bedeutet, dass alle übernommen werden).
In Tabelle 6 sind die Annotationen, die für eine Manager-Klasse verwendet werden.
Tabelle 6: Annotationen für Entity Manager-Klasse
Annotationen
Vervendung
inTLGen
Kommentar
Stateless
ja
Bezeichnet eine Session Stateless Bean
Local
ja
Ist nur lokal zu verwenden
PersistenceContext
ja
Definiert den Manager-Name
3.4.1 Methoden im Entity-Manager
In der generierten Entity Manager-Klasse werden auch zahlreiche Methoden generiert, notwendig für den Datenbankzugriff. Die Generierung dieser Methoden wird in der „config“-Datei
eingetragen und ist für die SQL Typen „named“ und „native“ gültig. Folgende Methoden sind
generierbar:
 Automatisch generierte Methoden (siehe Tabelle 5)
 Methodtype=6, für die Verwendung von„Named“ SQL(siehe Listing 43)
TLGen
61
StarData GmbH
V 2.8



Methodtype=7, für die Verwendung g von„Named“ SQL
Methodtype=8, für die Verwendung von „Native“ SQL (siehe Listing 4444)
Methodtype= , für die Criteria Aufrufe. In diesem Fall wird auch der Link zu einer Klasse,
in welcher der Programmierer sein Java Code eingebaut hat, generiert (siehe Listing 45)
Eintrag in der „config“ Datei:
<Method name="findHistoryCustomer" return="java.util.List<%interfacedata%>"
manager="HistoryCustomer" methodtype="6">
<Parameter name="customer" type="Object" />
<Sql name="getHistoryCustomer" sql="select o from HistoryCustomerEntity o where o.customer =
:customer"/>
</Method>
Und der generierte Code:
public List<HistoryCustomerData> findHistoryCustomer(Object customer, int level) throws
PersistenceException {
try {
List<HistoryCustomerData> list = null;
List<?> entityList =
m_manager.createQuery(m_getHistoryCustomer).setParameter("customer",customer).getResultList();
if(entityList != null && entityList.size() > 0) {
list = new ArrayList<HistoryCustomerData>();
for(Object entity : entityList) {
if(entity != null) {
list.add(((HistoryCustomerEntity)entity).callHistoryCustomer(level));
}
}
}
return list;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
Listing 43: SQL Named Beispiel
Eintrag in “config” datei:
<Method name="NativeQuery00" manager="Customer" mapping="true" methodtype="8">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Sql sql="SELECT * FROM Customer WHERE Customer_ID = ?" />
</Method>
Und das generierte code:
public List<NativeQuery00Data> NativeQuery00(long Customer_id, int level) throws
PersistenceException {
try {
List<NativeQuery00Data> list = null;
List<?> entityList =
m_manager.createNativeQuery(m_NativeQuery00,"NativeQuery00").setParameter(1,Customer_id).getResultList();
if(entityList != null && entityList.size() > 0) {
list = new ArrayList<NativeQuery00Data>();
for(Object entity : entityList) {
if(entity != null) {
NativeQuery00Data data = new NativeQuery00Data();
if(entity instanceof CustomerEntity) {
data.setCustomer(((CustomerEntity)entity).callCustomer(level));
}
list.add(data);
}
TLGen
62
StarData GmbH
V 2.8
}
}
return list;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
Listing 44: SQL Native Beispiel
Eintrag in “config” datei:
<Method name="countTestServices" return="java.lang.Long" criteria="true" manager="Customer"
methodtype="11">
<Parameter name="corporateId" type="java.lang.Long" />
<Parameter name="service" type="java.lang.String" />
<Parameter name="statusEnumFilterMatrix"
type="java.util.List<java.util.List<java.lang.Enum<?>>>"/>
</Method>
Und der generierte code:
public Long countTestServices(java.lang.Long corporateId, String service, List<List<Enum<?>>>
statusEnumFilterMatrix) throws PersistenceException {
try {
CustomerCriteria criteria = new CustomerCriteria();
return criteria.countTestServices(m_manager, corporateId, service,
statusEnumFilterMatrix);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
Listing 45: Criteria Beispiel
Der Inhalt einer Criteria-Methode wird in eine Klasse ausgelagert, die auch von TLGen auf ein
Path, eventuell definiert in den <Project> , generiert wird (siehe 4.5.2.2). Die Fachlogik für
diesen Zugriff wird manuell mit Hilfe von Meta-Klassen geschrieben (siehe 3.5.2).
In Listing 45 ist diese Klasse „eu.stardata.test.persistence.CustomerCriteria“ mit der Methode
„countTestService()“ und folgenden Parametern:

m_manager ist das „javax.persistence.EntityManager“ und ist für die Verwendung in
Criteria API (z. B. Verwendung von „CriteriaBuilder“) notwendig

corporateId ist ein Arbeitsparameter

service ist ein anderer Parameter
Diese Methode ergibt ein Ergebnis, welches im Programm verwendet werden kann.
3.4.2 Entity Manager-Interfaces
Weil Manager Klassen eigentlich lokale Session Beans sind, benötigen sie ein eigenes Interface. Diese werden auch automatisch von TLGen generiert.
Beispiel für ein Interface einer Manager-Klasse (Listing 46):
TLGen
63
StarData GmbH
V 2.8
import eu.stardata.core.form.dataif.CoFormularDataIf;
import java.lang.String;
import eu.stardata.server.common.exception.PersistenceException;
import eu.stardata.server.core.formular.bci.FormularBci;
import eu.stardata.server.core.formular.entity.FormularEntity;
public interface FormularBci {
// Manager interface data fields
public String JNDI_NAME = "eu.stardata.server.core.formular.bci.FormularBci";
public String EAR_NAME = "efp";
// Manager interface methods
public CoFormularDataIf findByPrimaryKey(CoFormularDataIf arg) throws PersistenceException;
…
public void close() throws PersistenceException;
}
Listing 46: Entity Manager Interface Beispiel
3.5 Entity Beans
Die Entity Beans sind das Tor zur Datenbank, besser gesagt, sie sind die Schnittstellen für eine
relationale Datenbank. Eine Entity Bean sollte einer Tabelle in der Datenbank entsprechen und
so eine saubere sowie strukturierte Architektur für die Persistenzschicht ermöglichen. Das ist
von großer Bedeutung für die Code-Wartung als auch für weitere Entwicklungen. Entity Beans
sind seit EJB3 POJO’s (Old Java Objects, darum auch nicht mehr Entity Beans genannt)
normale Java-Klassen und anders als die Session Beans, denn sie brauchen keine Interfaces.
Jede Entity Bean muss einen Standardkonstruktor besitzen, weil es unter anderem Aufgabe
einer Manager-Klasse ist, eine Instanz für die Entity Bean zu erzeugen.
TLGen generiert in einer Entity Bean die notwendigen Annotationen, Variablen, Default-Konstruktor, Mapping Methoden zwischen Daten-Objekt Attributen, Tabellenspalten, einige
Hilfsmethtoden, die diese Mapping unterstützen sowie die Methoden für die Relationen.
Für eine Entity Bean werden auch mehrere Annotationen und Variablen generiert wie in Listing
47 dargestellt:
package eu.stardata.server.core.formular.entity;
import javax.persistence.GeneratedValue;
…………………………………………………………………..
import javax.persistence.Entity;
@Entity
@Table(name="CORE_FORMULAR")
@SequenceGenerator(name="SEQ_STORE_FORMULAR", sequenceName="CORE_FORMULAR_SEQ",
initialValue=1, allocationSize=20)
public class FormularEntity {
private static final long serialVersionUID = 802995295;
// Entity data field
private CoFormularDataIf m_formular = null;
// Fields from relations tables
TLGen
64
StarData GmbH
V 2.8
private List<PageEntity> m_page = new ArrayList<PageEntity>();
private List<DocumentlistEntity> m_documentlist = new ArrayList<DocumentlistEntity>();
private LanguageEntity m_language = null;
…
// constructors
/**
* Default Constructor
*/
public FormularEntity() {
}
/**
* Constructor
* @param arg
*/
public FormularEntity(CoFormularDataIf arg) {
m_formular = arg;
fillFormular();
}
// Helper methods
/**
* Helper Method "makeFormular"
*/
public CoFormularDataIf makeFormular() {
if(m_formular == null) {
m_formular = new eu.stardata.core.form.data.CoFormularData();
}
return m_formular;
}
…
}
Listing 47: Entity Bean
In Tabelle 7 sind die Annotationen dargestellt, die für Entity Beans von EJB3 vorgesehen sind:
Tabelle 7: Annotationen für Entity Beans (EJB3)
Annotationen
Vervendung
inTLGen
Kommentar
Entity
ja
Definiert eine Entity Bean
Table
ja
Tabelle, die zu einer Entity gehören
Column
ja
Spalte einer Tabelle (für Mapping)
SequenceGenerator
ja
Definiert die Art von Sequence-Generator
GeneratedValue
ja
Generiert eine Sequence (für die automatische
Generierung von ID‘s)
Id
ja
Definiert eine PK
ManyToMany
ja
Relation Typ (siehe 2.6.1.4 und 4.5.3.8)
ManyToOne
ja
Relation Typ (siehe 2.6.1.2 und 4.5.3.8)
OneToMany
ja
Relation Typ (siehe 2.6.1.1 und 4.5.3.8)
OneToOne
ja
Relation Typ (siehe 2.6.1.3 und 4.5.3.8)
Version
ja
Verwendet für die Versionskennzeichnung, wird für Locking
verwendet
TLGen
65
StarData GmbH
V 2.8
PostLoad
ja
Hilfsmethoden, welche vor oder nach Processing
aufgerufen werden
PostPersist
ja
Hilfsmethoden, welche vor oder nach Processing
aufgerufen werden
PostRemove
ja
Hilfsmethoden, welche vor oder nach Processing
aufgerufen werden
PostUpdate
ja
Hilfsmethoden, welche vor oder nach Processing
aufgerufen werden
PrePersist
ja
Hilfsmethoden, welche vor oder nach Processing
aufgerufen werden
PreRemove
ja
Hilfsmethoden, welche vor oder nach Processing
aufgerufen werden
PreUpdate
ja
Hilfsmethoden, welche vor oder nach Processing
aufgerufen werden
JoinColumn
ja
Verbindungsspalte für eine Relation
JoinColumns
ja
Mehrzahl von Verbindungsspalten
JoinTable
ja
Verbindung DB Tabelle für eine ManyToMany Relation
Embeddable
ja
Für komplexe Primary Key verwendet
NamedQuery
ja
Definiert eine named SQL Query
NamedNativeQuery
ja
Definiert eine named Native Query
OrderBy
ja
Sortiert die Ergebnisse
Enumerated
nein
Vorgesehen für die nächste Version
EmbeddedId
nein
Vorgesehen für die nächste Version
Transient
nein
Vorgesehen für die nächste Version
TableGenerator
nein
Vorgesehen für die nächste Version
Temporal
nein
Vorgesehen für die nächste Version
Lob
ja
Für Blob und Clob (Große Daten) verwendet
SecondaryTable
nein
Vorgesehen für die nächste Version
Basic
ja
Wird zusammen mit Lob verwendet
PersistenceProperty
nein
Vorgesehen für die nächste Version
PersistenceUnit
nein
Vorgesehen für die nächste Version
UniqueConstraint
nein
Vorgesehen für die nächste Version
Inheritance
nein
Vorgesehen für die nächste Version
Innerhalb einer Entity Bean generiert TLGen eine Reihe von Hilfsmethoden, die für das
Mapping von Daten-Relationen notwendig sind. Diese Methoden sind:

fill„Name“(), hat keine Parameter und wird im Constructor aufgerufen. Ist für das
Speichern eines neuen Objekts in der Datenbank für eine “ManyToOne” Relation
notwendig

add„Name“(), hat keine Parameter und wird vom Manager aufgerufen. Ist für das
Speichern eines neuen Objekts in der Datenbank für eine “OneToMany” Relation notwendig
TLGen
66
StarData GmbH
V 2.8

call„Name“(), wird für alle Relationen beim Lesen eines Objekts aus der Datenbank
benutzt.
Listing 48 zeigt ein Beispiel-Code an:
/**
* Helper Method "callFormular"
*/
public CoFormularDataIf callFormular() {
// Relation ManyToOne, read data for "Formular" child, "Language"
if(getLanguage() != null) {
makeFormular().setLanguage(getLanguage().callLanguage());
}
// Relation ManyToOne, read data for "Formular" child, "Mandant"
if(getMandant() != null) {
makeFormular().setMandant(getMandant().callMandant());
}
// return the data object
return makeFormular();
}
Listing 48: Entity Bean “call…” Helper Methods
In Listing 49 stellt ein Beispiel einer Mapping-Methode mit einem Sequence Generator für
Primary Key dar:
// Methods from columns
@Id
@Column(name = "FORMULAR_ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_STORE_FORMULAR")
public long getFormularId() {
return makeFormular().getFormularId();
}
public void setFormularId(long arg)
{
makeFormular().setFormularId(arg);
}
Listing 49: Entity Bean Sequence Generator
TLGen generiert auch automatisch komplex verschachtelte Aufrufe für das Mapping, Beispiel
(Listing 50):
@Column(name = "authentificationFirstname", length = 255)
public String getAuthentificationFirstname()
{
if(makeUser().getAuthentification() != null && makeUser().getAuthentification().getName() != null) {
return makeUser().getAuthentification().getName().getFirstname();
}
return null;
}
public void setAuthentificationFirstname(String arg) {
if(makeUser().getAuthentification() == null) {
makeUser().setAuthentification(new Authentification());
}
TLGen
67
StarData GmbH
V 2.8
if(makeUser().getAuthentification().getName() == null) {
makeUser().getAuthentification().setName(new Name());
}
makeUser().getAuthentification().getName().setFirstname(arg);
}
Listing 50: Entity Bean (Mapping)
3.5.1 Relationen in Entity Beans
Ein wichtiger Bestandteil von Entity Beans sind die Relationen zwischen verschiedene Objekte,
die in einer Datenbank abgespeichert oder ausgelesen werden.
In diesem Kapitel erfolgt die Beschreibung für die Verwendung von Relationen sowie des vom
TLGen generierten Codes.
3.5.1.1 Relation „OneToMany“
„OneToMany“ Relation wird verwendet, wenn ein Objekt mehrere sub-objects (Kinder) besitzt.
In einer Datenbank wird dieses durch eine Tabelle, die eine „OneToMany“-Relation zu einer
anderen Tabelle hat, dargestellt. In das Daten-Interface wird so eine Relation durch eine Liste,
wie in Listing 51, erkennbar, dargestellt:
public interface CoFormularDataIf extends BaseDataIf
{
…
public abstract List<CoPageDataIf> getPage();
public abstract void setPage(List<CoPageDataIf> arg);
…
}
Vom “Formular” Objekt zum “Page” Objekt:
{
…
public abstract CoFormularDataIf getFormular();
public abstract void setFormular(CoFormularDataIf arg);
…
}
Listing 51: Entity Bean – “OneToMany” Interface
und vom “Page”-Objekt zum “Formular” Objekt wie in Listing 52:
// Methods from relations tables
@OneToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},
mappedBy = "formular",targetEntity = PageEntity.class)
public List<PageEntity> getPage() {
return m_page;
}
TLGen
68
StarData GmbH
V 2.8
public void setPage(List<PageEntity> arg) {
m_page = arg;
}
Listing 52: ”OneToMany” - Entiy-Bean-Methode
Ob solch ein Objekt gespeichert werden muss oder nicht, hängt von der Art der Relation ab,
„not null“ oder „null“. All seine Kinder werden automatisch gespeichert, wenn im Vater Objekt
die Kinderdaten vorhanden sind. Der Abspeicherungsprozess von Daten erfolgt automatisch
durch einen einzigen Aufruf einer „create“ Methode. Beim Lesen werden zusammen mit dem
Vater auch alle seine Kinder berücksichtigt, wenn diese vorhanden sind. Die Tiefe von RelationEbenen kann gesteuert werden, d. h. es kann nur der Vater gelesen/gespeichert werden oder
die Ebenen können immer weiter mit den Kindern erweitert werden. Diese Ebenenerweiterungen werden dann möglich, wenn die Art der Relationen „null“ ist. (Beispiel: ein
„Formular“ hat mehrere „Pages“ und jede Page hat mehrere „Fields“ usw.).
Abbildung 12: „OneToMany“-Darstellung im UML-Domainmodell
Eine UML-Darstellung für so eine Relation und befindet sich in Abbildung 12. Zwischen
„Formular“-Objekt und „Page“-Objekt existiert eine „null OneToMany“-Relation und zwischen
„Page“-Objekt und „Fields“-Objekt eine „not null OneToMany“-Relation. Als Datenmodell im
UML wird diese Relation in Abbildung 13 dargestellt.
Abbildung 13: „OneToMany“-Darstelung in der Datenbank
TLGen
69
StarData GmbH
V 2.8
3.5.1.2 Relation „ManyToOne“
Diese Relation ist eine symmetrische Relation zu „OneToMany“, d. h. ein Objekt kann mit
mehreren anderen Objekten verwendet werden. Auch bei dieser Art von Relation kann eine „not
null“-Verbindung existieren und dieser Link muss immer mit Daten versorgt werden, d. h. in der
Datenbank muss der Fremdschlüssel in den Kinder-Tabellen „not null“ sein (z.B. ein FK
=Fremdschlüssel) , der Typ „long“ soll immer größer als 0 sein und in der Tabelle, wo FK
angezeigt wird, muss ein richtiger Satz vorhanden sein
Die UML-Darstellung ist gleich mit der in Abbildung 12 und das Datenmodell wie in Abbildung
13, aber die Richtung ist umgekehrt als bei der Relation „OneToMany“. Das gilt auch für die
Code-Darstellung in Listing 52: ”OneToMany” - Entiy-Bean-Methode.
Für den Entity Bean Code ist Listing 53: „ManyToOne“ Entity-Methode zu beachten:
@ManyToOne(optional = true,targetEntity = WebstyleEntity.class)
@JoinColumn(name = "WEBSTYLE_ID",insertable = true, updatable = true, nullable = true,
unique = false,referencedColumnName = "WEBSTYLE_ID")
public WebstyleEntity getWebstyle() {
return m_webstyle;
}
public void setWebstyle(WebstyleEntity arg) {
m_webstyle = arg;
}
Listing 53: „ManyToOne“ Entity-Methode
3.5.1.3 Relation „OneToOne“
Die Relation „OneToOne“ verbindet zwei Objekte so, dass eines ein einziges Kind besitzt. Auch
bei dieser Relation ist eine „null“-Verbindung möglich, d. h. der Fremdschlüssel kann null oder
„not null“ sein. In diesem Fall muss der Fremdschlüssel immer vorhanden sein und zu einem
vorhandenen Satz in der Datenbank die Verbindung anzeigen.
Auch bei dieser Verbindung gibt es einen Vater und ein Kind.
Code für diese Relation ist in Listing 54 (Daten-Interfaces) und in Listing 55 für das Entity-Bean
dargestellt.
TLGen
70
StarData GmbH
V 2.8
public interface CoFieldDataIf extends BaseDataIf {
…
public abstract CoTableDataIf getTable();
public abstract void setTable(CoTableDataIf arg);
…
}
Listing 54: „OneToOne” Data-Interface
public class FieldEntity {
private private TableEntity m_table = null;
…
@OneToOne(cascade =
{CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},
targetEntity = TableEntity.class,optional = true)
@JoinColumn(name = "TABLE_ID",insertable = false, updatable = false, nullable = true,
unique = false,referencedColumnName = "TABLE_ID")
public TableEntity getTable() {
return m_table;
}
public void setTable(TableEntity arg) {
m_table = arg;
}
…
}
Listing 55: „OneToOne” Entity Bean
3.5.1.4 Relation „ManyToMany“
Die Relation „ManyToMany“ ist die komplexe Form für das Verbinden mehrerer Objekte/Tabellen. Auf der Code-Ebene hat jedes Objekt eine Liste mit den anderen Objekten wie in Listing
56.
public interface UserDataIf extends BaseDataIf
{
...
// Methods from relations tables
public abstract List<UserRoleDataIf> getUserRole();
public abstract void setUserRole(List<UserRoleDataIf> arg);
...
}
Vom “User” Objekt zu “UserRole” Objekt
public interface UserRoleDataIf extends BaseDataIf
{
...
// Methods from relations tables
public abstract List<UserDataIf> getUser();
public abstract void setUser(List<UserDataIf> arg);
...
}
Listing 56: „ManyToMany“-Interface
TLGen
71
StarData GmbH
V 2.8
In der Datenbank-Ebene ist für diese Relation eine dritte Tabelle notwendig, eine so genannte
Mapping Tabelle, wie in Abbildung 15. Die Darstellung in einem Domain-Modell ist in Abbildung
14 ersichtlich.
Abbildung 14: „ManyToMany“-Darstellung im UML-Domainmodell
Aus einem Domaimodelll generiert TLGen für „ManyToMany“-Relationen automatisch die
nötige Mapping Tabelle als SQL Skript.
Abbildung 15: „ManToMany“ Darstellung in der Datenbank
In den Entity Beans werden Annotationen mit den dazugehörigen Methoden, wie in unserem
Beispiel, sowohl in der „UserEntity“ Bean als auch in „UserRoleEntity“ Bean generiert (siehe
Listing 57):
@Entity
@Table(name="UserTable")
@SequenceGenerator(name="SEQ_STORE_USER", sequenceName="USERTABLE_SEQ", initialValue=1,
allocationSize=10)
public class UserEntity extends BaseData implements Serializable {
// Entity data field
private UserDataIf m_user = null;
…
// Methods from relations tables
@ManyToMany(targetEntity = UserRoleEntity.class)
@JoinTable(name = "UserRole_UserTable",inverseJoinColumns = {@JoinColumn(name =
"UserRole_ID",insertable = true, updatable = true, nullable = false, unique = false)},
joinColumns = {@JoinColumn(name = "UserTable_ID",insertable = true, updatable = true,
TLGen
72
StarData GmbH
V 2.8
nullable = false, unique = false)})
public List<UserRoleEntity> getUserRole() {
return m_userRole;
}
public void setUserRole(List<UserRoleEntity> arg) {
m_userRole = arg;
}
…
}
„ManyToMany“ zwischen “User” und „UserRole“
@Entity
@Table(name="UserRole")
@SequenceGenerator(name="SEQ_STORE_USERROLE", sequenceName="USERROLE_SEQ",
initialValue=1, allocationSize=10)
public class UserRoleEntity extends BaseData implements Serializable {
private static final long serialVersionUID = 413271821;
// Entity data field
private UserRoleDataIf m_userRole = null;
…
// Methods from relations tables
@ManyToMany(cascade =
{CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},
mappedBy = "userRole",targetEntity = UserEntity.class)
public List<UserEntity> getUser() {
return m_user;
}
public void setUser(List<UserEntity> arg) {
m_user = arg;
}
…
}
Listing 57: „ManyToMany“-Relation in Entity Bean
In der Praxis haben wir 3 Möglichkeiten Tabellen zwischen denen eine „ManyToMany“ Relation
existiert, abzuspeichern, wie:

Speichern beider Objekte gleichzeitig. Das „User“-Objekt beinhaltet die Daten für
dessen „UserRole“ und in der Datenbank werden drei Sätze gespeichert, einer in der
„USERROLE“ Tabelle, der andere in die „USER“ Tabelle und der dritte Satz in Tabelle
„USER_USERROLE“ mit beiden ID’s (USER_ID und USERROLE_ID).

Speichern einer „UserRole“ von einem oder mehreren Objekt(en) in der „USERROLE“
Tabelle

Speichern eines „User“ Objektes, der mit einem „USERROLE_ID“ einer vorhandenen
„USERROLE“ versorgt wird, in dem Datenbank-Objekt einer „UserRole“. In diesem Fall
werden zwei Sätze in der Datenbank gespeichert, einer in die „USER“ Tabelle und ein
zweiter in der Tabelle „USER_USERROLE“ mit beiden ID’s. Falls der „USERROLE_ID“
zeigt, dass ein „USERROLE“ in dieser Tabelle nicht vorhanden ist, wird eine Exception
zurück zum Client gesendet und eine Roll-Back Transaktion folgt.
TLGen
73
StarData GmbH
V 2.8
3.5.2 Meta-Klassen (für Criteria)
Meta-Klassen werden für die Codierung von Criteria API verwendet.
Man erstellt von Entity Beans ein Meta-Modell, in dem alle Klassen und Attribute mit ihren
Datentypen definiert sind. Will man sich bei der Verwendung der Criteria API auf eine bestimte
Spalte einer Bean beziehen, greift man dann auf dieses Meta-Modell zurück.
In Listing 588 wird eine Meta Modell-Klasse dargestelt:
@StaticMetamodel(CustomerEntity.class)
public class CustomerEntity_ implements Serializable {
private static final long serialVersionUID = 1102865432;
// Meta annotations and fields
public static volatile SingularAttribute<CustomerEntity,Long> customerID;
public static volatile SingularAttribute<CustomerEntity,Long> ejb3Optlock;
public static volatile SingularAttribute<CustomerEntity,Date> modifyDate;
……….….
public static volatile SingularAttribute<CustomerEntity,LanguageEntity> language;
public static volatile ListAttribute<CustomerEntity,HistoryCustomerEntity> historyCustomer;
public static volatile ListAttribute<CustomerEntity,LoginEntity> login;
public static volatile ListAttribute<CustomerEntity,SubscriberEntity> subscriber;
}
Listing 58: Meta-Klasse - Beispiel
3.6
„Message Driven“ Bean
Bestimmte Aufgaben von komplexen Anwendungen müssen nicht sofort erledigt werden,
sondern können mit bestimmten Nachrichten auf einem späteren Zeitpunkt verschoben werden.
Für diese Art von Aufgaben stehen im Applikation-Server die Message Driven Beans bereit.
Die Kommunikation zwischen Client und Server über Message Driven Beans läuft über dem
JMS (Java Message Service). TLGen kann die Message Driven Beans mit sehr wenig Aufwand
generieren.
Mit den generierten Message Driven Beans kann die Applikation über Callback-Klassen
kommunizieren (siehe Kap. 3.8) und somit ist eine klare Trennung zwischen der technischen
und der fachlichen Schicht realisierbar.
Mit Hilfe der Steuerung über die Konfigurationsdateien können für die Message Driven Beans
folgende Features generiert werden:
TLGen
74
StarData GmbH
V 2.8

Annotationen mit Parametern (Tabelle 8)

Client-Klassen

Message Driven Bean-Klassen

Callback-Klassen für die Verbindung mit der Fachlogik-Schicht.
Tabelle 8: Annotationen für „Message Driven“ Bean
Annotationen
Verwendung
in TLGen
Kommentar
javax.annotation.Resource
ja
Definiert die Ressource der Message Driven
Beans
javax.ejb.MessageDriven
ja
Definiert ein Message Driven Bean
javax.ejb.ActivationConfigProperty
ja
Setzt die Eigenschaften der Message Driven
Beans
3.7 Services
Die Applikation Server bieten für EJB 3.1 zwei Services an, „Timerservices“, mit deren Hilfe ein
bestimmter Prozess zu einem bestimmten Zeitpunkt aufgerufen werden kann (periodisch
wiederholbar) und „Web Services“, die Session-Beans über Internet/Intranet aufrufen können.
TLGen kann beide Services generieren.
3.7.1 „Timer Service“
Ein Timer Service kommt in der Applikation zum Einsatz, wenn eine zeitgesteuerte Verarbeitung benötig wird. Der Methodenaufruf kann wahlweise einmalig oder in einem bestimten
Zeitintervall dauerhaft erfolgen.
TLGen generiert ein Timer Service und seine Komponenten wie den Client des Timer Service,
Timer Service und eine Callback-Klasse (siehe 3.8) für die Implementierung von eigener Fachlogik, die von diesem Service benötigt wird.
Timer Services werden von TLGen in drei Varianten generiert:
1. Vollautomatisch, in diesem Fall werden die Start-, Stopp-Zeit - Aufrufe und die
periodische Wiederholung automatisch nach der Timer Service - Initialisierung gesteuert.
2. Start - und Stopp - Zeit wird durch die Client-Aufrufe gesteuert.
3. Verwendet die automatische und manuelle Steuerungsmöglichkeit.
Die Timer Services können z.B. von einer Session-Bean oder einer Message Driven-Bean
verwendet werden.
TLGen
75
StarData GmbH
V 2.8
In Listing 59 ein Timer Service Beispiel.
/**
* This is a generate package for 'emails'
* This is a timer service class
*/
@Stateless(name = EmailserviceBci.JNDI_NAME, mappedName = "vms/"+EmailserviceBci.JNDI_NAME+"/remote")
@Remote(EmailserviceBci.class)
public class EmailserviceSessionBean implements EmailserviceBci {
private static final long serialVersionUID = 240781750;
// Session annotations and fields for timer service
@Resource
private TimerService m_timerService;
private static final String KOMMAND = "TLG";
@Inject
private CallBackEmailserviceIf m_callBack;
// Session class methods
/**
* Timer service method "initemails()"
* @param start
* @param stop
* @param repeat
* @return
* @throws PersistenceException
*/
public void initemails(Date start, Date stop, long repeat) throws PersistenceException {
try {
// time to start and repeat timer service
m_timerService.createTimer(start,repeat,KOMMAND);
// time to stop timer service
m_timerService.createTimer(stop,KOMMAND);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Timer service method "stopemails()"
*/
public void stopemails() {
for(Object obj : m_timerService.getTimers()) {
Timer timer = (Timer)obj;
String command = (String)timer.getInfo();
if(command.equals(KOMMAND)) {
timer.cancel();
}
}
}
/**
* Timer service method "timeoutemails()"
* @param timer
* @return
*/
@Timeout
public void timeoutemails(Timer timer) {
String command = (String)timer.getInfo();
if(command.equals(KOMMAND)) {
m_callBack.checkEmails(this);
}
}
}
TLGen
76
StarData GmbH
V 2.8
Listing 59: Beispiel eines „Timer Services“
In der Klassen-Methode „eu.stardata.server.CallBakcEmailService“ kann die gewünschte
Fachlogik eingebaut werden (in der Methode checkEmails).
3.7.2 „Web Services“
Ein Web Service ist ein beliebiger Service (z. B. eine Session-Bean), der von einem Client über
z.B. das Internet aufgerufen werden kann.
Es werden zwei Arten von Web Services unterschieden, RPC (Remote Procedure Call) und
DOCUMENT. RPC ist ein Aufruf einer Methode (z. B. eine Methode von einer Session-Bean)
über Web.
TLGen generiert für diese Services den Client, den Web Service und eine Callback-Klasse
(siehe 3.8), falls diese nötig ist, um dort die nötige Fachlogik zu implementieren.
In Listing 60 ein Beispiel einer Web Service-Klasse
package eu.stardata.server.provider
/**
* A session bean encapsulates business logic that can be invoked programmatically
* by a client over local, remote, or web service client views.
*/
@Stateless(name = ProviderBci.JNDI_NAME, mappedName = "vms/"+ProviderBci.JNDI_NAME+"/remote")
@Remote(ProviderBci.class)
@Web Service(endpointInterface = "eu.stardata.provider.client.bci.ProviderBci", serviceName =
"ProviderSessionBeanService")
public class ProviderSessionBean extends BaseSessionBean implements ProviderBci
{
// Session annotations and fields for local manager
@Inject
private CallBackServiceProviderIf m_callBack;
………………
public RetrieveServiceResponse retrieveServiceIn(RetrieveServiceRequest retrive) throws
PersistenceException {
try {
return m_callBack.retrieveServiceIn(retrive);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
…………….
}
Listing 60: „Web Service“-Klasse - Beispiel
In der Klassen-Methode „eu.stardata.server.CallBakcPtroviderIf“ kann die gewünschte Fachlogik eingebaut werden (in der Methode retriveServiceIn).
TLGen
77
StarData GmbH
V 2.8
In Listing 61 das Interface dieser Web Service-Klasse.
package eu.stardata.provider.client.bci
@Remote
@Web Service
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public interface ProviderBci {
// Client interface Fields
public final static String JNDI_NAME_PREFIX = "vms";
public final static String JNDI_NAME = "eu.stardata.server.provider.ProviderSessionBean";
public final static String MANAGER_NAME = "managerProvider";
public final static String EAR_NAME = "vms";
public final static String PACKAGE_NAME = "provider";
// Session - Client interface methods
@WebMethod
public RetrieveServiceResponse retrieveServiceIn(RetrieveServiceRequest retrive) throws
PersistenceException;
@WebMethod
public UpdateServiceResponse updateServiceIn(UpdateServiceRequest update) throws
PersistenceException;
}
Listing 61: „Web Service”-Interface
3.8 Callback-Klasse
Die Callback-Klasse kann eine normale Java-Klasse oder eine Session Bean-Klasse sein.
Der Aufruf einer Callback-Klasse von einer Session Bean ist in Listing 62 dargestellt. TLGen
generiert den Aufruf dieser Klasse und eventuell seine Interfaces mit der Struktur von verwendeten Methoden. Die Programmierer werden diese Klassen mit dem selbsgeschriebenen FachCode, der Applikation versorgen.
Die Kommunikation zwischen der aufgerufenen Klasse und der Callback-Klasse erfolgt über
Methoden, die „Parameter“ und „Return“-Werte haben.
@Inject
private CallBackServiceUpsIf m_callBack;
…………………….
public RetrieveServiceResponse retrieveServiceIn(RetrieveServiceRequest retrive) throws PersistenceException {
try {
return m_callBack.retrieveServiceIn(retrive);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
TLGen
78
StarData GmbH
V 2.8
Callback Interface:
@Local
public interface CallBackServiceUpsIf {
……………………………………
/**
* retrieve the informations from the VMS system
* @param adr
* @return
* @throws PersistenceException
*/
public abstract RetrieveServiceResponse retrieveServiceIn(
RetrieveServiceRequest retrieve) throws PersistenceException;
}
Callback Class:
public class CallBackServiceUps extends UpsFunctions implements Serializable, CallBackServiceUpsIf {
……………………………..
@Override
public RetrieveServiceResponse retrieveServiceIn(RetrieveServiceRequest retrieve) throws PersistenceException {
…………..// Insert Fach Code
}
Listing 62: Callback-Klasse - Beispiel
Diese Art von Klasse ist als Schnitstelle zwischen dem technischen Code, der von TLGen
generiert wird, und dem fachlichen Code, der die Fachlogik der Applikation beinhaltet, gedacht.
Die Generierung der Klasse kann wie folgt gesteuert werden:

merge = 0, TLGen generiert diese Klasse immer wieder neu und überschreibt
vorhandene.

merge = 1, diese Klasse wird nur generiert, falls sie nicht existiert.

merge = 2, Generierung einer neuen Klasse und Zusammenfassung dieser mit der
Implementierung der vorhandenen
3.8.1 Free Klassen
Diese „freien“ Klassen sind für den eigenen Programmteil des Projekts gedacht und beinhalten
die Fachlogik. Diese muss selbst implementiert werden. Falls der Generator eine freie Klasse
findet, welche angegeben wurde und sich innerhalb des Ordners „generated“ befindet, kann er,
abhängig von einem Parameter „merge“, wie folgt diese überschreiben oder neu generieren:

merge = 0, TLGen generiert diese Klasse immer wieder neu und überschreibt
vorhandene.

merge = 1, diese Klasse wird nur generiert, falls sie nicht existiert

merge = 2, Generierung einer neuen Klasse und Zusammenfassung dieser mit der
Implementierung der vorhandenen

Merge = 3 generiert nur die neuen Methoden in eine schon existierende Klasse
TLGen
79
StarData GmbH
V 2.8
3.9 Generierung von Datenbank und SQL Skripte
TLGen kann ein Datenbank SQL Skript aus einem Domainmodell mit seinen Tabellen, Spalten,
Relationen, Indexes und Sequenzen generieren. Ist der Datenbankzugriff (User und Password)
in der Konfigurationsdatei vorhanden, verwendet TLGen das generierte Skript, um die Datenbank zu generieren.
Ein komplettes Beispiel einer SQL Script siehe in Kap: 7.3.
UML-Parameter für die SQLSkript Generierung:
1. Regel für die SQL Tabellen Generierung:
a. Die Kommentare werden aus den UML-Klassen übernommen und dem SQL
Skript hinzugefügt.
b. UML-Klassen als „persistent“ gekennzeichnet werden auch als Tabellen generiert, wobei für die „transienten“ Klassen nur die Daten-Klassen/Interfaces
generiert werden.
c. Constraints werden vom SQL Skript übernommen. Ist der Name „tablespace“
vorhanden, wird der Constrain String mit der aus der „Config“- XML -Datei
Tablespace-Index Wert ergänzt.
2. Regel für die SQL Spalten/Columns:
a. Die Spalten (UML-Klassenattribute), gekennzeichnet in der UML als „derived“,
werden als „NOT NULL“-Felder generiert.
b. Die Spalten, gekennzeichnet in der UML als „static“, werden als „UNIQUE“Felder generiert.
c. Das Attribut „container“ im Collection UML Tail beim TAG „UML:TaggedValue“
muss die Länge dieser Variablen angeben, ansonsten werden die Standardwerte
aus der Konfigurationsdatei übernommen (z.B. für String ist die Länge 255
Char).
d. „Name“, „Type“ und „Initial“ werden von den dazugehörigen Tags übernommen.
3. Regel für Sequences:
a. Weil einige Datenbanken wie z.B. Oracle eine begrenzte Länge für die Namen
(30 char) haben, sind einige Regel für die Namengenerierung notwendig. Die
zwei Regeln sind in TLGen implementiert :
i. Sequence Type 0 (Dieser Wert ist eitragbar in der „Standard
Konfiguration“ Datei, Tag <UmlControl>, Attribut „sequenceType“):
Sequence-Name = „Table-Name“ + „Sequence Endung“
ii. Sequence Type 1:
Sequence-Name = „Table-Name“ + „_“ + „ColumnName“ + „_ID“ + “Sequence Endung”
TLGen
80
StarData GmbH
V 2.8
Die “Sequence Endung” ist in der „Standard Konfiguration“ Datei, Tag <UmlControl>, im Attribut
„endSequence“ einzutragen. Weil diese Kombination manchmal eine größere Namenlänge als
der zugelassene Wert ergibt, wird diese mit Hilfe von Eintragungen in der „Standard Konfiguration“ -Datei verkürzt, Tag <UmlControl>, <NameChange>. Z.B.:
<NameChange name="ProvisioningStatus_ProvisioningStatus_ID_1SQ" type="ProvisStat_ProvisStat_ID_1SQ"/>
Der Name "ProvisioningStatus_ProvisioningStatus_ID_1SQ" wird mit dem Namen
ProvisStat_ProvisStat_ID_1SQ. Ersetzt.
Dies ist auch möglich, wenn die Datenbank schon vorhanden ist. Dann werden nur die Änderungen (es wird auch ein Änderungs-Skript generiert) generiert und somit werden die schon
vorhandenen Daten nicht gelöscht.
Skript-Beispiele in Listing 63:
----------- Drop all Tables ----------DROP TABLE Contract CASCADE CONSTRAINTS;
DROP TABLE Product CASCADE CONSTRAINTS;
…………………………………………………………
----------- Create Tables ----------CREATE TABLE Product (
Product_ID NUMBER(19,0) NOT NULL,
DB_VERSION NUMBER(16) NULL,
description VARCHAR2(255) NULL,
………………………………………………………
shortName VARCHAR2(255) NULL,
CustomerService_ID NUMBER(19,0) NULL,
PRIMARY KEY (Product_ID) USING INDEX TABLESPACE XINDEX
) Tablespace XDATA;
………………………………………………………
----- Foreign key -----ALTER TABLE Product ADD CONSTRAINT FK201A7DE FOREIGN KEY (CustomerService_ID) REFERENCES
CustomerService;
ALTER TABLE Contract ADD CONSTRAINT FKF96859 FOREIGN KEY (Customer_ID) REFERENCES Customer;
ALTER TABLE Contract ADD CONSTRAINT FK31C7538 FOREIGN KEY (AccessControlContext_ID)
REFERENCES AccessControlContext;
ALTER TABLE Contract ADD CONSTRAINT FK7FE790 FOREIGN KEY (Offer_ID) REFERENCES Offer;
………………………………………………….
----------- Create Sequences ----------CREATE SEQUENCE Contract_SEQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
CREATE SEQUENCE Product_SEQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
Listing 63: SQL Skript
Die sofortige Generierung einer Datenbank ist für den Datenbank Optimierungsprozess (neue
und alte Projekte) wichtig (siehe Kap. 2.1).
TLGen
81
StarData GmbH
V 2.8
3.10 Regel für die Namengenerierung
TLGen verwendet für die Namengenerierung im Code Generierungsprozess zwei Arten von
Regeln:

Die Domainmodell-Namen sind eigentlich Namen gemäß den Java Konventionen für
Datenbank-Namen. In diesem Fall verwendet die Datenbanknamen-Generierung
vorhandene Namen aus dem Domainmodell.

Bei einer schon vorhandenen Datenbank (Legacy Projekte) gibt es in den meisten
Fällen Namen, die anders als die Java Namenskonventionen sind. Für diesen Fall sind
acht Namensumwandlungen möglich:
o
Aus den groß geschriebenen Namen, aus mehreren Teilen mit ein „underscore“
verbunden, wird ein Name kleingeschrieben, ohne „underscore“. (siehe Fehler!
Verweisquelle konnte nicht gefunden werden., Zeile 1)
o
„underscore“ wird nicht mehr verwendet, d.h. der erste Buchstabe ist groß, Zeile
2
o
„underscore“ wird nicht verwendet, der restliche Name bleibt gleich, Zeile 4 und
5
o
„underscore“ wird verwendet, der restliche Name bleibt gleich, Zeile 6
o
underscore“ wird verwendet und der restliche Name verwendet die Java NamenKonvention, Zeile 7
o
keine Namen-Änderung.
Tabelle 9: Namen-Regel
Nr.
Datenbank Format
Java Format
1
CORE_FORMULAR
Formular
2
CORE_FORMULAR
CoreFormular
testCoreFormular
TestCoreFormular
CORE_FORMULAR
CoreFormular
testCoreFormular
TestCoreFormular
FORMULAR
Formular
CORE_FORMULAR
COREFORMULAR
testCoreFormular
TestCoreFormular
CORE_FORMULAR
CoreFormular
testCoreFormular
Testcoreformular
6
CORE_FORMULAR
COREFORMULAR
7
CORE_FORMULAR
Core_formular
8
CORE_FORMULAR
CORE_FORMULAR
3
4
5
Details siehe auch in Kapitel 4.4.
TLGen
82
StarData GmbH
V 2.8
Diese Regeln können auch aus dem Domain-Modell in Bezug auf die Datenbank verwendet
werden, jedoch machen die meisten Datenbanken keinen Unterschied zwischen Klein- und
Grossschreibung.
3.11 Log Dateien - Beschreibung
TLGen erzeugt im Generierungsprozess mehrere Log Dateien, die in allen Generierungsprozessen eingetragen werden. Durch diese Log Dateien kann kontrolliert werden, ob das ProjektDesign den gewünschten Ergebnissen entspricht.
Die Verwendung von Log Dateien ist einstellbar und der Name ist wählbar, d. h. es kann bzw.
können nur eine oder mehrere Log Dateien verwendet werden. Sind es mehrere, weil die Information in diesen Dateien sehr groß ist, wird die Verwendung dieser Dateien somit erleichtert.
TLGen kann folgende Log Dateien verwenden:

Eine Log Datei für die Generierung allgemeiner Schritte

Eine Log Datei für die Generierung von Session Beans

Eine Log Datei für die Generierung von Entity Beans

Eine Log Datei für die Generierung von Test Klassen

Eine Log Datei für die Generierung von Daten-Klassen/Interfaces

Eine Log Datei für die Generierung von Manager-Klassen.
Es gibt eine Error Log Datei, in der die Generierung Error, wie z. B. zu lange Namen, Fehler im
Domainmodell (z. B. Kreise in Relationen) eingetragen werden. Ein Beispiel für eine Error Log
Datei befindet sich in Listing 64 (siehe auch Kap. 2.1):
Time Start : Sat Feb 05 13:29:11 CET 2011
0 Domain Error | Class-name is too lang[35] + 'AverageFlatDurationCalculationParam'
==== Direct circles in relations ==============================================
Warning: TARGET [Order] in a path starting with himself as SOURCE [Order]: [Order(NOT NULL)>Customer(NULL)->Asset(NOT NULL)->AssetItem(NOT NULL)] ---> [Order]
Warning: TARGET [Offer] in a path starting with himself as SOURCE [Offer]: [Offer(NOT NULL)>Customer(NULL)->Asset(NOT NULL)->AssetItem(NOT NULL)->Order(NOT NULL)->Contract(NOT NULL)] --->
[Offer]
………………………………………………..
==== Relation Problems? ==================================================
FATAL Error: [ServiceDescriptiontItem] needed by different mandatory relations starting from [AssetItemStatus]
[AssetItemStatus->AssetItem->Order->Contract->ServiceDescription] ---> [ServiceDescriptiontItem]
[AssetItemStatus->AssetItem->OrderItem] ---> [ServiceDescriptiontItem]
FATAL Error: [ServiceDescription] needed by different mandatory relations starting from [AssetItem]
[AssetItemStatus->AssetItem->Order->Contract] ---> [ServiceDescription]
[AssetItemStatus->AssetItem->Order->Contract->Offer] ---> [ServiceDescription]
Warning: [ProductRelation] can be reached over [AssetItem] in different relations:
[AssetItemStatus->AssetItem->OrderItem->ServiceDescriptiontItem->Product] ---> [ProductRelation]
[ServiceDescriptiontItem->AssetItem->OrderItem->Product] ---> [ProductRelation]
[OrderItem->ServiceDescriptiontItem->AssetItem->Product] ---> [ProductRelation]
TLGen
83
StarData GmbH
V 2.8
Listing 64: Error Log Datei
3.12 Verwendung von Kommentarien bei generiertem Code
TLGen generiert Kommentarien auf der Ebene von Klassen-Methoden.
3.12.1 Kommentarien für Klassen
Für Klassen gibt es zwei Möglichkeiten Kommentarien im generierten Code zu verwenden.
1. Text-Kommentarien, die vom „package“ Eintrag dargestellt werden, die für alle Klassen
gleich sind und vom „standard“ xml stammen wie in Listing 65. Wenn statt ein
Kommentar Text im Attribut „commentary“ der String „false“ existiert, dann wird kein
Kommentar generiert.
2. Innerhalb einer Klasse können verschiedene Kommentarien eingebaut werden; von
jedem <Design> Tag und diese werden in allen Klassen, die zu diesem Tag (package)
gehören, generiert (siehe Listing 66).
In Klasse:
/**
* **** do not change with a file editor *****
*/
package com.thgen.server.persistence.customer;
und in “standard-config” xml Datei:
und in “standard-config” xml Datei:
<Standard name="Standard-VMS"
……………………
commentary="**** do not change with a file editor *****" >
Listing 65: Kommentarien für Klasse
<Design name="common" >
<Commentary name="This is a generate package for 'common'"/>
Listing 66: Kommentar vom <Design> Tag
In den UML Domain-Modell kann ein Kommentar im Attribut „note“ eingebaut werden. Dieser
wird zusammen mit dem zuvor beschriebenen Kommentar vom <Design> Tag generiert, siehe
Listing 67. Dieser Kommentar wird auch im generierten SQLSkript vor der dazugehörigen
Tabelle eingebaut sowie in der „JSon“-Klasse, falls diese Klasse auch generiert wird.
TLGen
84
StarData GmbH
V 2.8
/**
* This is a generate package for 'customer'
*
* A session bean encapsulates business logic that can be invoked programmatically
* by a client over local, remote, or web service client views.
*/
……………………………
public class CustomerSessionBean implements CustomerBci
Listing 67: Kommentar vom UMD Domain-Modell
3.12.2 Kommentarien für Methoden
Kommentarien von Methoden kommen, wie im UML Domain Modell beschrieben, bei jedem
Attribut vor und werden vor der „Get“ Methode, die diese Attribute darstellen, in alle SQL Skripts
und Daten-Klassen generiert, siehe Listing 68.
/**
* last name of the customer
*/
public String getLastName() {
return m_lastName;
}
public void setLastName(String arg) {
m_lastName = arg;
}
Listing 68: Methoden Kommentar
TLGen
85
StarData GmbH
V 2.8
4 Verwendung von TLGen (Beschreibung der Konfigurationsdatei)
4.1 Was wird generiert
Siehe Kapitel 1.2
4.2 Wie wird Code generiert?
TLGen generiert den Java Code mit Hilfe eines Domain Modells (UML) für neue Projekte, einer
existierenden Datenbank für Legacy Projekte und zwei Konfigurationsdateien. Spezifisch für
TLGen sind nur die Konfigurationsdateien im XML Format, eine Default-Konfigurationsdatei und
die projektspezifischen Konfigurationsdateien.
Der Aufwand zur Erstellung der projektspezifischen Konfigurationsdatei ist sehr gering, da
üblicherweise nur ein paar Parameter, abhängig vom eigenen Projekt, angepasst werden muss.
Die restlichen Parameter werden automatisch von den Default-Werten übernommen (siehe Kap
4.3 und 4.4).
Diese Default-Werte können durch die Default Konfigurationsdatei überschrieben, im Generierungsprozess verwendet werden und gelten dann für alle projektspezifischen Konfiguraionsdateien.
Default-Werte können in der projektspezifischen Konfigurationsdatei überschrieben werden.
Diese Informationen-Verkettung für den Generierungsprozess ist für Firmen gedacht, welche
viele Projekte haben und bestimmte Standard-Werte für alle Projekte benötigen, z.B. Layout
des generierten Codes. Die Unterschiede zwischen Projekte (fachprojektspezifisch) werden mit
Hilfe der projektspezifischen Konfigurationsdatei geregelt. So kann die Default Konfigurationsdatei nur allgemeine Informationen beinhalten, welche alle untergeordneten Projekte dann
verwenden.
Für Firmen, die wenige Projekte entwickeln, ist die detaillierte Steuerung von ProjektHierarchien (mit der Default-Konfigurationsdatei und mehreren Projekt-Konfigurationsdateien)
für die Code- Generierung uninteressant und kann deshalb entfallen.
4.3 Ordnerstruktur für den generierten Code
Eine übersichtliche und fachgerechte Strukturierung von Ordnern für den neu generierten Code
vereinfacht die Wartung und Weiterentwicklung von neuen oder refaktorieten Projekten.
Für den neu generierten Code schlagen wir folgende Ordner-Struktur vor (siehe Abbildung 16).
TLGen
86
StarData GmbH
V 2.8
Für den generierten Code gibt es für die Pfad-Struktur „de.stardata.demo“ (mit dem Projektnamen „demo“) folgende drei Unterordner:

bussines Ordner, in welchem die Daten-Objekte generiert werden

client, der Code für die Client-Aufrufe:

o
bci (business common interface), Ordner, wo die Verbindungszugriffe zwischen
Client und Server generiert werden
o
message Ordner, wo die Client Message-Klassen generiert werden sollten
o
test Ordner, wo die JUnit-Test-Klassen generiert werden
server Ordner, wo Server-Klassen generiert werden
o
message Ordner für die Message Beans
o
persistence Ordner, wo sich alle Klassen, notwendig für die Daten-Persistence,
befinden, wie die Session Beans, Entity Manager, Entities Beans, etc.
Abbildung 16: Ordner-Struktur
TLGen
87
StarData GmbH
V 2.8
Diese Ordner-Struktur ist nur eine Empfehlung seitens TLGen Generator Team, denn eigentlich
kann jeder die eigene Struktur über die Konfigurationsdatei definieren.
4.4 Default Konfigurationsdatei
Wie zuvor schon beschrieben, beinhaltet diese Konfigurationsdatei die allgemeinen Informationen, die in mehreren Projekten verwendet werden können.
In den folgenden Kapiteln werden die Parameter und Einstellungen genauer beschrieben.
Für die Code-Generierung mit Hilfe von TLGen aus einem Domain-Modell (UML) oder aus einer
vorhandenen Datenbank (z.B. für Legacy-Projekte) heraus gibt es nur einen Unterschied,
nämlich das Setzen eines Parameters.
4.4.1 Default Konfigurationsdatei - Struktur
Die Default Konfigurationsdatei hat folgende XML-Struktur (siehe Listing 69):
<?xml version="1.0" encoding="UTF-8"?>
<Standard xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="C:\Project-TLGen-2.2\config\template\DefaultSchema.xsd">
<Project/>
<Locator></Locator>
<Class>
<Extends/>
</Class>
<Entity>
<Implements/>
<Extends/>
<Annotation/>
</Entity>
<Mapping>
</Mapping>
<Criteria>
</Criteria>
<JSon>
</JSon>
<Manager>
<Extends/>
<Implements/>
<Annotation/>
<Method>
<Exception/>
<Parameter/>
</Method>
</Manager>
<Session>
<Extends/>
<Annotation/>
<Client>
<Extends/>
<Annotation/>
<Variable/>
</Client>
TLGen
88
StarData GmbH
V 2.8
<Xml-persistence>
<Property/>
</Xml-persistence>
<Interceptor>
<Method>
<Annotation/>
<Parameter/>
<Exception/>
</Method>
</Interceptor>
<Freeclass>
</Freeclass>
</Session>
<Message>
</Message>
<UmlControl>
<Column/>
<ColType/>
<NameChange/>
<Relation/>
<Association/>
<RelationType/>
<AggregationType/>
<DirectionType/>
<AssociationType/>
<AssociationSubType/>
<Navigability/>
<Compare/>
</UmlControl>
</Standard>
Listing 69: Default Konfigurationsdatei
Die Default Konfigurationsdatei verwendet folgende Tags:

Standard Tag, ist der Main Tag.

Locator

Class

Entity

Mapping

Criteria

JSon

Manager

Session
o
Client
o
Xml-persistence
o
Interceptor
o
Freeclass

Message

UmlControl
TLGen
89
StarData GmbH
V 2.8
Die detaillierte Beschreibung dieser Tags und deren Attribute sind im folgenden Kapitel dargestellt.
4.4.2 Default Konfigurationsdatei - Beschreibung
Die Default Konfigurationsdatei beinhaltet allgemeine Einstellungen und Parameter und ist für
eine Gruppe von Projekten gedacht, welche in der Projekt Konfigurationsdatei überschrieben
werden können.
Bemerkung: Strings in den Attributen innerhalb eines Tags welche mit einem „%“ beginnen und
enden (z.B. %package%) sind Ersetzungsnamen oder Platzhalter, welche der Generator dann
automatisch einsetzt (z.B. alle Entities mit Ihren richtigen packages).
Des Weiteren sind alle Werte eines Tag-Attributs, wie
name=„com.tlgen.common.bci.ServiceLocator“ (hier eine Klasse), nur Beispiele, sie müssen
aber nicht verwendet werden. TLGen wurde mit diesen getestet und diese entsprechen auch
den Standard-Aufrufen.
4.4.2.1 <Standard> Tag
Ist der Main Tag für diese XML. Es gibt folgende Attribute:

name: Projekt-Name

company: Firmen-Name

path: Allgemeine Pathstruktur, z.B. „eu.stardata.%project%“

Commentary: Kurzbeschreibung des Projekts
4.4.2.2 <Project> Tag
Siehe Kapitel 4.5.2.2.
4.4.2.3 <Locator> Tag
Es ist ein optionaler Tag. Dieser Tag beinhaltet die Klasse für die RMI-Verbindung. Gibt es
keine Eintragungen in diesem Tag, wird die Default-Klasse verwendet. Folgende Attribute werden mit den Default-Werten verwendet:

name = „com.tlgen.common.bci.ServiceLocator“, Standard Locator-Klasse

instance = “getInstance”ist der Methoden-Name für die Instanz

local = „getLocalReference“ Methoden-Name des lokalen RMI-Aufrufs
TLGen
90
StarData GmbH
V 2.8

remote = "getRemoteReference" Methoden-Name des Remote-Aufrufs
4.4.2.4 <Class> Tag
Dieser ist ein optionaler Tag und kann auch über die projektspezifische Konfigurationsdatei
über die <Class>-Tags überschrieben werden. Der Tag generiert Daten-Klassen und Ihre Interfaces. Dazu gehören folgende Attribute:

path = „de.stardata.demo.business“, Klassen/Interface-Pfad und optionales Attribut

name = "de.stardata.demo.business.%package%.data.%classname%Data|
de.stardata.demo.business.%package%.dataif.%classname%DataIf", der Name
beinhaltet zwei Teile, für die Klassen bzw.Interfaces, getrennt durch “|“. Die Attribute der
zwei Platzhalter sind:
o
%package% ist der Package-Name. Dieser wird vom Generator mit dem
Package-Namen aus dem Domain-Modell ersetzt oder aber aus den
festgelegten Namen aus der projektspezifischen Konfigurationsdatei.
o
%classname% dieses Attribut wird automatisch vom Generator mit dem ObjektNamen aus dem Domain-Modell ersetzt oder mit den Werten der TabellenNamen (werden eventuell durch die Rules geändert) aus der Datenbank.

pathEnum = "de.stardata.demo.business.%package%.%classname%" wird für die
Generierung von Enums verwendet. Die Platzhalter haben die gleiche Bedeutung wie
zuvor erwähnt.

pathType = “de.stardata.demo.business.%package%.%classname%” wird für die
Typen Klassen verwendet.
Dieser Tag hat zwei Kind-Tags, die optional sind und folgende Standard-Einstellung haben:

<Extends name="com.tlgen.common.data.BaseData"/> kann eigene Super-Klassen
verwenden.

<Extends name="com.tlgen.common.data.BaseDataIf" type="interface"/>
4.4.2.5 <Entity> Tag
Dieser Tag versorgt den Generator mit Informationen über die Entities. Es ist ein optionaler
Tag. Fehlt dieser, werden die Default-Informationen (z.B. mit Hilfe des Domain Modells) verwendet oder können über die projektspezifische Konfigurationsdatei überschrieben werden.
Entity Tag hat folgende Attribute:

path = "de.stardata.server.persistence" (Beschreibung wie unter 4.4.2.5)

name = "de.stardata.server.persistence.%package%.entity.%classname%Entity"
(Beschreibung wie unter 4.4.2.5)

seqstrategy="SEQUENCE" ist der Default-Wert. Dieses Attribut ist für die automatische
Generierung von einem Primary Key notwendig (z.B. für die Datenbank Oracle).
TLGen
91
StarData GmbH
V 2.8
Dieser Tag hat folgende Kinder-Tags, die optional sind:

<Implements> mit Attribut Name="java.io.Serializable"

<Extends> mit Attribut Name="com.tlgen.common.ejb.entity.BaseEntityBean",
z.B. eine Standard Super-Klasse wie
<Extends name="com.tlgen.common.ejb.entity.BaseEntityBean"/>

<Annotation>, dieser Tag ist optional und der Generator kann damit folgende
Annotationen in die Entities generieren:
o
"javax.persistence.Entity"
o
"javax.persistence.Table" der Generator übernimmt automatisch den TabellenNamen
o
"javax.persistence.SequenceGenerator"
4.4.2.6 <Mapping> Tag
Dieser Tag versorgt den Generator mit Informationen über die Mapping-Klassen zwischen
Data-Klassen und JSon-Klassen. Es ist ein optionaler Tag. Fehlt dieser, werden die DefaultInformationen verwendet.
<Mapping> Tag hat folgende Attribute:

name = „eu.stardata.%project%.business.%package%.%classname%Map“
4.4.2.7 <Criteria> Tag
Dieser Tag versorgt den Generator mit Informationen über die Criteria-Klassen. Es ist ein optionaler Tag. Fehlt dieser, werden die Default-Informationen verwendet.
<Criteria> Tag hat folgende Attribute:

name = „eu.stardata.%project%.business.%package%.%classname%Criteria“
4.4.2.8 <JSon> Tag
Dieser Tag versorgt den Generator mit Informationen über die JSon Daten-Klassen. Es ist ein
optionaler Tag. Fehlt dieser, werden die Default-Informationen verwendet.
<Criteria> Tag hat folgende Attribute:
TLGen
92
StarData GmbH
V 2.8

name = „eu.stardata.%project%.business.%package%.%classname%JSon“
4.4.2.9 <Manager> Tag
Dieser Tag versorgt den TLGen Generator für die Generierung mit Informationen von Entity
Manager und hat folgende Attribute:

name="eu.stardata.server.persistence.%package%.manager.%classname%Manager
(Beschreibung wie unter 4.4.2.9)

transactiontype: z.B."JTA“ ist ein Standard Wert.

Exception: Zur Verwendung einer eigenen Exception-Klasse, z.B.
"com.tlgen.common.exception.PersistenceException".
Dieser Tag hat folgende Unter-Tags, die optional sind:

<Extends> mit Attribut Name=" com.tlgen.common.ejb.manager.BaseManager "

<Annotation>, dieser Tag ist optional und folgende Annotationen sind z. B. für die
Entities möglich:
o
"javax.ejb.Stateless"
o
"javax.ejb.Local"
4.4.2.9.1 Fields für Entity Manager
Für den Manager werden folgende notwendige Fields automatisch generiert (für den Tag
<Variable> siehe auch 4.4.2.9.1):
1. name="JNDI_NAME" vartype="string" content="%interfacemanager%" fieldtype="1"
abstract="true"
2. name="EAR_NAME" varitype = "string" content="%earname%" fieldtype="1"
abstract="true"
3. name="m_manager" vartype = "javax.persistence.EntityManager"
type="%clientdata%.MANAGER_NAME". Für dieses Field werden folgende Annotation
generiert:
a. name="javax.persistence.PersistenceContext"mit folgenden Parametern:
i. name="properties" type="Text-Prop"/>
ii. name="unitName" type="%clientdata%.MANAGER_NAME"
4.4.2.9.2 Methoden für Entity Manager
TLGen
93
StarData GmbH
V 2.8
Für den Tag <Method> siehe auch 4.4.2.10. Die Manager Bean-Methoden können in drei
Kategorien eingeteilt werden: Es sind Methoden, die intern vom Manager Bean gebraucht
werden, Methoden, die vom Client über die Session-Beans aufgerufen werden und für die Verwaltung des Persistenz-Prozesses notwendig sind und als dritte Kategorie sind die Methoden
für die Persistenz-Verwaltung, welche vom User über die Konfigurationsdatei übergeben
werden (siehe 4.5.2.4.3.1).
Die Methoden im Manager können auch eine Exception werfen und werden mittels Tags
<Exception> individuell gesteuert. Dieser Tag hat ein Attribut „name“ und braucht den
kompletten Namen der Exception-Klasse.
Folgende interne Methoden werden für den Manager Bean standardmäßig generiert:
1. name="getManager" return="%interfacemanager%" methodtype="4", holt vom BeanContainer den aktuellen Manager.
2. name="getEntityByPrimaryKey" return="%Klassentity%" methodtype="5"
Folgende Methoden werden standardmäßig für die Remote-Verwendung generiert:
1. name="create" return="%interfacedata%" methodtype="4", speichert ein neues Objekt in
der Datenbank ab. Der Platzhalter %interfacedata% wird vom Generator automatisch
mit dem richtigen Interface Namen ersetzt.
2. name="update" methodtype="4", ändert ein Datenobjekt in der Datenbank
3. name="remove" methodtype="4", löscht ein Objekt in der Datenbank
4. name="flush" methodtype="4"
5. name="close" methodtype="4"
6. name="clear" methodtype="4"
7. name="findByPrimaryKey" return="%interfacedata%" methodtype="5", sucht ein Objekt
in der Datenbank nach dessen PrimaryKey. Der Platzhalter %interfacedata% wird vom
Generator mit dem Interface Name ersetzt.
8. name="findAll" return="%interfacedata%[]" methodtype="5", holt alle Objekte für diesen
Manager-Bean aus der Datenbank. Der Platzhalter %interfacedata% wird vom
Generator mit dem Interface Name ersetzt.
4.4.2.10 <Session> Tag
Dieser Tag versorgt den Generator mit allgemeinen Informationen für die Generierung der
Session Beans. Falls dieser nicht vorhanden ist, werden die Default-Daten für die Generierung
verwendet.
Der Session Bean Tag hat folgende Attribute:

TLGen
name="de.stardata.demo.server.persistence.%package%.%classname%SessionBean",
ist der Name (%classname%) und dazu der Pfad - Platzhalter (%package%) für alle
Session Beans.
94
StarData GmbH
V 2.8

managername="manager%classname%", gibt dem Manager Informationen, die für die
„persistence.xml“ Datei notwendig sind (siehe 0)

transactiontype, Transaktions-Typ (z.B. JTA).
Session Bean hat z.B. folgende mögliche Annotationen:

name="javax.ejb.Stateless"oder „javax.ejb.Stateful“

name="javax.ejb.Remote"
Werden Session Beans als Web Services oder Timer Services generiert, können auch andere
Annotationen verwendet werden (siehe 4.5.2.4.6.4, 4.5.2.4.6.5)
4.4.2.10.1 Methoden in Session Bean
Eine Session Bean übernimmt alle oder nur die auserwählten Methoden vom Entity Manager,
aufgerufen über die jeweilige Session Bean (Details siehe 4.5.2.4.6.1).
Die Namen der Methoden werden aus dem Namen der Methode und dem Manager-Namen
zusammengesetzt, da z.B. der Aufruf „findByPrimaryKey“ für jedes Entity nützlich ist und von
mehreren Managern benötigt wird.
Z.B. das Manager Formular hat im Session-Bean den zusammengesetzten Aufrufnamen aus
„findByPrimaryKey“ und seinem Namen: „findByPrimaryKeyFormular“.
Diese Namen werden bis zum Client gleichbleibend verwendet, d.h. auch in den Client
Interfaces/Daten-Klassen (DAOs).
4.4.2.10.2 <Client> Tag
Ist ein Tag innerhalb der Session Beans und dient zur Generierung von Client-Aufrufen. Auch
dieser Tag ist optional und wird er nicht verwendet, generiert der Generator Standard-Aufrufe.
Dieser Tag hat folgende Attribute:

name="de.stardata.demo.client.bci.%package%.%classname%Bci"

exception = "com.tlgen.common.exception.PersistenceException"
TLGen
95
StarData GmbH
V 2.8
4.4.2.10.3 <Xml-persistence> Tag
Der Tag setzt die Properties der persistence.xml, die z.B. in einer EAR benötigt werden, um die
eigene Applikation in einem Application Server zu installieren. Diese Werte sind Applikation
Server abhängig. Statt das Attribut value wird hier type für <Property> verwendet.
Beispiel: JBoss 5.x brauchte bei Verwendung der Oracle-Datenbank 11x die folgende
Information, um eine Verbindung zur Datenbank aufzubauen:
<Property name="hibernate.dialect" type="org.hibernate.dialect.Oracle10gDialect" />
4.4.2.10.4 <Interceptor> Tag
EJB3 bietet die Möglichkeit an, eigene Interceptors zu verwenden. Folgende Attribute können
für diesen Tag verwendet werden:

name="de.stardata.demo.server.persistence.%package%.TimeCore", kompletter
Klassen-Name des Interceptors (Pfad)

path ="C:/Project-TLGen-2.2/source/generated", ist der Pfad, wo die Klasse generiert
wird. Ist dieser nicht vorhanden, wird der Interceptor in denselben Pfad wie der Session
Bean hinein generiert.
Ein Interceptor kann mehrere Methoden mit folgenden Daten haben:

name="timeTrace", interceptor name

return="java.lang.Object" , Rückgabewert

finally="C:/Project-TLGen-2.2/resources/FinallyTime.xml"
4.4.2.11 <Message Driven> Tag
Dieser wird für Message Driven Beans verwendet und hat folgendes Attribut:

name="de.stardata.demo.server.persistence.%package%.message"
4.4.2.12 <UmlControl> Tag
Dieser Tag wird für die Generierung der Klassen aus den UML Domain Datenmodellen benötigt. Da dies feste Einstellungen sind und z.B. die Standard UML-Relationen der Klassen festlegen, sollten diese Werte nicht geändert werden.
Folgende Attribute sind für diesen Tag verwendbar:
TLGen
96
StarData GmbH
V 2.8













name ist der Domen Modell Name z.B. "Demo-DM"
lenString ist die Default Strings Länge wenn keine im Domain Modell definiert ist z.B.
„255“
versionDb ist der Name für die Version Variable in Entity Bean, z.B. „OPTLOCK“
versionDbType ist die Variable Version Type in DB, z.b. „NUMBER(12,0)“
enumType ist die Type von „enum“ in DB, z.B. "VARCHAR2(32)"
primKeyType ist den Primary Key Type in DB, z.B. "long"
endSequence ist die Endung vom Sequence Namen in DB, z.B. "_1SQ"
sequenceType ist die Sequence Type, z.B. “1”
sequenceCache ist die Sequence Cache Größe, z.B. „10“
sequenceInit ist der Inititalisierungswert für die DB Sequence, z.B. „1“
sequenceIncrement ist der Increment für den Sequence Wert, z.B. „1“
dataTablespace ist der Name vom Tablespace für Daten in DB, z.B. "ADMDATA"
indexTablespace ist der Name vom Tablespace für Index in DB, z.B. "ADMINDEX"
Folgende Tags können im Tag <UmlControl> verwendet werden:

<Column> legt die Daten für ein bestimmtes column in der Datenbank fest. Diese
Column wird bei der Generierung von SQL Skript in allen Tabellen eingebaut, z.B. siehe
Listing 70
<Column name="EJB3_OPTLOCK" type="long" dbType="NUMBER" dataLen="16" locking="true"/>
<Column name="MODIFY_DATE" type="Date" dbType="TIMESTAMP" dataLen="0" locking="false" nullable="true"
defaultValue="CURRENT_TIMESTAMP"/>
Listing 70: <Column> Tag

<ColType> legt die Datenbank Typen für ein Column fest. Es gibt Default Werte (siehe
Listing 71 und Listing 72) für diesen Tag, können aber geändert werden
<ColType name="char" type="CHAR"/>
<ColType name="Date" type="TIMESTAMP(6)"/>
<ColType name="String" type="VARCHAR2"/>
<ColType name="DbType" type="NUMBER(10,0)"/>
<ColType name="byte[]" type="BLOB"/>
<ColType name="int" type="NUMBER(12,0)"/>
<ColType name="Integer" type="NUMBER(12,0)"/>
<ColType name="long" type="NUMBER(24,0)"/>
<ColType name="Long" type="NUMBER(24,0)"/>
<ColType name="double" type="NUMBER(28,4)"/>
<ColType name="Double" type="NUMBER(28,4)"/>
<ColType name="float" type="NUMBER(12,2)"/>
<ColType name="Float" type="NUMBER(12,2)"/>
<ColType name="short" type="SMALLINT"/>
<ColType name="Short" type="SMALLINT"/>
<ColType name="boolean" type="NUMBER(1,0)"/>
<ColType name="Boolean" type="NUMBER(1,0)"/>
Listing 71: Default Values für <ColType> Tag, z.B. für Oracle
<ColType name="char" type="CHAR"/>
<ColType name="Date" type="TIMESTAMP"/>
TLGen
97
StarData GmbH
V 2.8
<ColType name="String" type="VARCHAR"/>
<ColType name="TIMESTAMP" type="TIMESTAMP"/>
<ColType name="DbType" type="int"/>
<ColType name="byte[]" type="BLOB"/>
<ColType name="Text" type="Text"/>
<ColType name="int" type="int"/>
<ColType name="Integer" type="int"/>
<ColType name="long" type="bigint"/>
<ColType name="Long" type="bigint"/>
<ColType name="double" type="double"/>
<ColType name="Double" type="double"/>
<ColType name="float" type="float"/>
<ColType name="Float" type="float"/>
<ColType name="short" type="SMALLINT"/>
<ColType name="Short" type="SMALLINT"/>
<ColType name="byte" type="TINYINT"/>
<ColType name="dec" type="DEC"/>
<ColType name="boolean" type="boolean"/>
<ColType name="TablespaceExtra" type="ENGINE=InnoDB DEFAULT CHARSET=utf8"/>
Listing 72: Default Values für <ColType> Tag, z.B. für MySQL

<NameChange> ändert den Namen eines Domain Modell Objekts in der Datenbank,
siehe Listing 73
<NameChange name="User" type="UserTable"/>
Listing 73: <NameChange> Tag

<Relation>
Der Relation Tag ändert den Algorithmus, um z.B. rekursive Richtungen zu erlauben und einen
anderen Namenszusatz zu den Methoden-Namen zu addieren, damit es keine Codekonflikte
gibt.
Rekursive Relationen:
o
o
type="recursiv" name="recursiv" mit value=“true“ erlaubt rekursive Relationen
(false für nicht).
type="recursiv" name="recursivName" mit value="Parent" addiert zum Relation
Methoden-Namen rekursiver Relationen “Parent”
Mehrere Relationen in einer Klasse:
o
o
type="sameRelationDirection" name="sameRelationDirection" erlaubt mehrere
Relationen in einer Klasse (false für nicht).
type="sameRelationDirection" name="sameRelationDirectionName" addiert zum
Relation Methoden-Namen weiterer Relationen “Parent”
Mehrere Rück-Relationen in einer Klasse:
o
o
TLGen
type=" backRelationDirection" name=" backRelationDirection" erlaubt mehrere
Relationen in einer Klasse (false für nicht).
type=" backRelationDirection" name=" backRelationDirectionName" addiert zum
Relation Methoden-Namen weitere Relationen “Parent”
98
StarData GmbH
V 2.8

<Association>
Assoziation behandeln die OneToOne-, OneToMany-, ManyToOne- und ManyToManyRelationen.

Um den ENUM-Typ der Assoziation „Shared“ und „Composition“ und deren
Möglichkeiten (z.B. cascade) der Richtungen zu bestimmen (siehe Kapitel 2.1.1.3.1).
Beispiel:
<Association type="Composition" name="Composition:Source -> Destination|toSource" position="Source"
navigable="Source" optional="false" nullable ="false" />

Um den ENUM-Typ OneToOne-, OneToMany-, ManyToOne- oder ManyToMany fest zu
überschreiben, können diese festgelegt werden (siehe Kapitel 2.1.1.3.2). Das Attribut
overwrite muss auf „true“ gesetzt werden.
Beispiel:
<Association type="OneToMany" name="OneToMany" overwrite="true" direction="true" insertable="true"
updateable="true" />

<RelationType>
Relationstyp setzt vorhandene ENUMs, welche auf die UML-Multiplizität Strings in der XMI
Mappen. z.B. „m0_infinite“ auf „*“ oder auch auf „0..*“.
Enums: mStandard, mNull, m0, m1, m0_1, m0_n, m0_infinite, m0_infinite, m1_n, m1_infinite,
mm_n.
Beispiel:
<RelationType name="m0_infinite" type="RELATION_TYPE" return="Many" value="*"/>

<AggregationType>
AggregationType setzt die vorhandenen ENUMs (None, Shared, Composition), welche auf die
UML-Assoziationarten Strings in der XMI mappen. Z.B. „None“ auf „none“.
Beispiel:
<AggregationType name="None" type="UML_ASSSOCIATION_TYPE" return="association" value="none"/>

<DirectionType>
DirectionType setzt die vorhandenen ENUMs (Unspecified, SourceToDest, DestToSource,
BiDirectional), welche auf die Richtungs-Strings in der XMI mappen. Z.B. „BiDirectional“ auf
„Bi-Directional“.
Beispiel:
<DirectionType name="BiDirectional" type="UML_CONNECTION_END_TYPE" return="bidirectional" value="BiDirectional"/>
TLGen
99
StarData GmbH
V 2.8

<AssociationType>
AssotiationType setzt die vorhandenen ENUMs (Association, Aggregation), welche auf die
UML-Assoziationarten Strings in der XMI mappen. Z.B. „Aggregation“ auf „Aggregation“.
Beispiel:
<AssociationType name="Aggregation" type="UML_ASSSOCIATION_TYPE" return="aggregation"
value="Aggregation"/>

<AssociationSubType>
AssociationSubType setzt die vorhandenen ENUMs (Association, Strong, Weak), welche auf
die Assoziationsubarten Strings in der XMI mappen. Z.B. „Association“ auf „Association“.
Beispiel:
<AssociationSubType name="Association" type="UML_ASSSOCIATION_TYPE" return="association" value="null"/>

<Navigability>
Navigability setzt die vorhandenen ENUMs (None, Navigable, NonNavigable, Unspecified),
welche auf die Navigation Strings in der XMI mappen. Z.B. „None“ auf „None“.
Beispiel:
<Navigability name="Navigable" type="UML_CONNECTION_END_NAVIGABLE_TYPE" return="navigable"
value="Navigable"/>

<Compare>
Compare setzt die vorhandenen ENUMs (manytomany, onetomany, manytoone, onetoone), ob
sie eine einfache Relation oder auch eine “many”-Relation sind.
Beispiel:
<Compare name="manytoone" type="RELATION_TYPE" return="ManyToOne" value="Many" />
<Compare name="manytoone" type="RELATION_TYPE" return="ManyToOne" value="One"/>
4.4.2.13 <Method> tag
Siehe Kap. 4.5.2.5
4.4.2.14 <Variable> Tag
Siehe Kap. 4.5.2.6
4.5 Projekt Konfigurationsdatei
TLGen
100
StarData Gmb
V 2.8
Die Projekt Konfigurationsdatei gibt dem TLGen-Generator projektspezifische Daten über das
Projekt. Die Daten aus der Konfigurationsdatei überschreiben die vorhergehenden Daten, die
Default-Werte sowie die aus der Standard-Konfigurationsdatei.
4.5.1 Projekt Konfigurationsdatei - Struktur
Die Default Konfigurationsdatei hat folgende XML Struktur (siehe Listing 74):
<?xml version="1.0" encoding="UTF-8"?>
<Generator xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="C:\Project-TLGen-2.2\config\template\ConfigSchema.xsd">
<Project>
<Design>
<Commentary/>
<Class>
<Extends/>
</Class>
<Entity> </Entity>
<Manager>
<Extends/>
<Implements/>
<Method>
<Exception/>
<Parameter/>
<Sql/>
</Method>
</Manager>
<Session>
<Extends/>
<Annotation/>
<Client>
<Extends/>
<Annotation/>
<Variable/>
</Client>
<Timerservice>
<Extends/>
<Annotation/>
<Variable/>
<Method/>
</Timerservice>
<Xml-persistence>
<Property/>
</Xml-persistence>
<Method>
<Exception/>
<Parameter/>
</Method>
</Session>
<Messagedriven>
<Extends/>
<Annotation/>
<Client/>
<Bean>
<Callback/>
</Bean>
</Messagedriven>
<Test>
<Extends/>
<Import/>
TLGen
101
StarData Gmb
V 2.8
<Method>
<Exception/>
<Parameter/>
</Method>
</Test>
<Dbtable>
<Relation>
<JoinColumn/>
<JoinTable>
<JoinColumn/>
<InverseJoinColumn/>
</JoinTable>
</Relation>
</Dbtable>
</Design>
</Project>
</Generator>
Listing 74: Konfigurationsdatei
4.5.2 Projekt Konfigurationsdatei - Beschreibung
Die Konfigurationsdatei erlaubt detaillierte Einstellungsmöglichkeiten und kann alle vorherigen
Daten überschreiben.
4.5.2.1 <Generator> Tag
Dieser ist das Hauptelement und versorgt den Generator mit allgemeinen Informationen über
die Code Generierung. Folgende Attribute können verwendet werden (siehe Table 10). Die verwendeten Attribute können nach der Generierung in der „log“ Folder ersichtlich sein.
Table 10: Attribute für den Generator Tag
Nr.
Attribute Name
Pflichfeld
Beispiel-Wert
Kommentar
1
name
no
Demo
Projekt Name
2
inputsource
yes
database
3
location
yes
C:/Projects/Project-RMA/project
Die Addresse sollte vom
Code generiert werden
4
datasource
yes
java:/efpPool
Conditioned from
App.Server
TLGen
102
StarData Gmb
V 2.8
5
appserver
yes
JBoss
6
standardConfigFile
yes
C:/Project-TLGen2.5/config/config_tlgen_demo_d
efault.xml
7
umlFile
yes/no
C:\Project-TLGen2.5\doc\model\DomainModelDemo-01.xml
Is mandatory only for
type=guml and is the
XMI file from the UML
domain model
8
databaseConnect
yes
jdbc:oracle:thin:@localhost:1521
:orcl
Connect string to the
database
9
database
yes
ORACLE
Database name
10
userPwd
yes
demo/demo
For access to the
database
101
type
yes
guml/gdb
guml - generated from a
domain model - gdb generated from a
database.
12
mapping
no
true
13
rule
no
3
Default is 0, siehe
4.5.2.1.1
14
databaseScript
yes/no
C:/Project-TLGen2.5/doc/db/demo_schema.sql
Is mandatory for
makeDatabse=true and
type=guml
15
makeDatabase
no
true
Generate a new
Database with the help of
a generated SQL-script
16
makeDatabaseDiff
17
indexTablespace
yes/no
DEMOINDEX
Mandatory only if
generating a database
18
dataTablespace
Yes/no
DEMODATA
Mandatory only if
generating a database
19
makeJavaCode
no
true
20
initProgram
no
21
keyName
no
22
reference
no
Generate a different
SQL-script
true
4.5.2.1.1 Regel für Namen-Transformation in Klassen, Methoden und Tabellen
Mit TLGen kann folgende Regel für die Namen-Generierung verwenden:

TLGen
RULE_DEFAULT_VALUE = 0, Default value, no underscore, if all is upper, then first
char is upper, rest is lower amd the rest is not changed. Examples:
o
‘CORE_FORMULAR_PAGE_FIELD’ -> ‘CoreFormularPageField’
o
‘bruttoNettoSpecification’ -> ‘BruttoNettoSpecification’
o
‘_FIELDLONGDATA_’ -> ‘Fieldlongdata’
103
StarData Gmb
V 2.8

RULE_NO_UNDERSCORE = 1, No underscore. Examples:

o
‘CORE_FORMULAR_PAGE_FIELD’ -> 'COREFORMULARPAGEFIELD’
o
'bruttoNettoSpecification' -> 'bruttoNettoSpecification’
o
'_FIELDLONGDATA_ -> 'FIELDLONGDATA’
RULE_NO_UNDERSCORE_FIRST_UPPER = 2, No underscore, first char is upper, the
rest is not changed. Examples:

o
'CORE_FORMULAR_PAGE_FIELD' -> 'COREFORMULARPAGEFIELD'
o
'bruttoNettoSpecification' -> 'BruttoNettoSpecification'
o
'_FIELDLONGDATA_' -> 'FIELDLONGDATA'
RULE_DEFAULT_WITHOUT_FIRST = 3, Default, without the first tail before the first
underscore (for legacy programs). Examples :

o
'CORE_FORMULAR_PAGE_FIELD' -> 'FormularPageField'
o
'bruttoNettoSpecification' -> 'BruttoNettoSpecification'
o
'_FIELDLONGDATA_' -> 'Fieldlongdata'
RULE_NO_UNDERSCORE_FIRST_UPPER_REST_LOWER = 4, No underscore, first
char is upper, rest is lower. Examples :

o
'CORE_FORMULAR_PAGE_FIELD' -> 'CoreFormularPageField'
o
'bruttoNettoSpecification' -> 'Bruttonettospecification'
o
'_FIELDLONGDATA_' -> 'Fieldlongdata'
RULE_NO_UNDERSCORE_FIRST_UPPER_ALL_REST_LOWER = 5, No underscore,
first char is upper, all rest is lower. Examples:

o
'CORE_FORMULAR_PAGE_FIELD' -> 'Coreformularpagefield'
o
'bruttoNettoSpecification' -> 'Bruttonettospecification'
o
'_FIELDLONGDATA_' -> 'Fieldlongdata’
RULE_NO_CHANGE = 6, No change
4.5.2.2 <Project> Tag
Dieses Element versorgt den Generator mit den projektspezifischen Daten. Die Attribute für
diesen Tag sind in der Tabelle 11 aufgeführt. Die verwendeten <Project> Attribute können nach
der Generierung in die „log“ Dateien ersichtlich sein.
Anmerkung: Sind die „no“-Pflichfelder nicht in der Konfigurationsdatei vorhanden, werden die
Standardwerte verwendet.
Tabelle 11: Attribute für den Projekt-Tag
Nr.
Attribute Name
Pflicht
feld
Default/Beispiel-Wert
Kommentar
1
name
no
Project StarData Demo
Project Name
2
initialcontext
yes
jnp://localhost:9099
Conditioned from the
App.Server
TLGen
104
StarData Gmb
V 2.8
3
initialcontextfactory
yes
org.jnp.interfaces.NamingC
ontextFactory
Conditioned from the
App.Server
4
initialcontextpkgprefix
yes
org.jboss.naming:org.jnp.int
erfaces
Conditioned from the
App.Server
5
contextkey
no
jboss.naming.client.ejb.cont
ext
JBoss7
6
contextvalue
no
true
JBoss7
7
optionskey
no
Extra parameter für config
JBoss7
8
optionvalue
no
false
JBoss7
9
managermethods
no
Asset, Product, etc.
List with all managers
10
methods
no
public
11
sequencegen
yes
SEQ_STORE
Type from generator for
primary key
13
format
no
0 or 1
Default is 0 and is used “C”
formatter style (siehe Listing
75) and by 1 is code formatter
in “Java” style (siehe Listing
76)
14
import
no
true(default)
Default is ‘false’. Do not use
import in the class and all
name is full qualified
15
data
no
false(default)
Default is ‘false’. TLGen
generates classes and
interfaces data by default, if
‘true’, then only data classes.
16
list
no
true(default)
Default is ‘true’, For Lists the
class List is used, if ‘false’
arrays are used.
17
testRelation
no
true,true,true,true
Relations in Test classes
18
earname
yes
demo
The name from ear file
19
MappedNameRemote
no
Examples in the text
Overwrites the standard
generated attribute
mappedname of the EJB3
annotation
@Stateless/@Statefull in the
Session-Beans
20
JNDIName
no
Examples in the text
Overwrites the standard
generated attribute name of
the EJB3 annotation
@Stateless/@Statefull in the
Session-Beans.
21
JNDINameRemote
no
Examples in the text
Overwrites the standard
generated JNDI name for the
Session-Beans and will be
stored in the client Interface of
the Session-Beans to call the
remote Session-Bean.
22
level
no
Verwendet level Attribute
für die lesefunktion
0, nur das Objekt selber, 1
auch seine Kinder, 2…
TLGen
105
StarData Gmb
V 2.8
23
persistence
no
True(default)
true = value all domain will
assume in persistence
24
persistenceUnit
no
false(default)
Bei „true“ generiert nur rein
persistence.xml auf der
höchsten Ebene, false(default)
generiert eine persistence.xml
auf jede design Ebene
25
security
no
Ggeneriert security xmy
26
pathTest
no
“C:/Projects/ProjectRMA/source/help”
Wenn vorhanden, generiert
die Test Klasse an dieser
Adresse
27
pathCriteria
no
„C:/Projects/ProjectRMA/source/criteria”
Wenn vorhanden, generiert
die Callback Klasse für
Criteria an dieser Addresse
28
pathInterceptor
no
"C:/Projects/ProjectRMA/source/interceptor"
Wenn vorhanden, generiert
die Interceptor Klasse an
dieser Addresse
29
enumsString
no
false(default)
false – speichert die enums in
der Datenbank als integer
(standard) ab
true – speichert die enums als
String in der Datenbank ab
Note ! in Default XML config
file muss beim Tag
<UmlControl den Attribut
‚enumType ‘ =
VARCHAR2(Länge)
eingetragen sein
30
createTyp
no
0
0-(default) wird nach create
die Daten lesen
1-wird flush(); und dann
refresh(entity); aufgerufen
Bei „true“ werden alle Metaund Callback Klassen für
Criteria generiert.
31
criteria
no
32
pathJsonData
no
33
jsonData
no
false(default)
Bei „true“ werden die JSon
Dataobjects, die REST
interface und die Callback
Klassen für diese Interfaces
generiert.
34
jsonLocking
no
false(default)
Bei „true“ werden in JSon
Data Objekt und auch die
Variable von Versionierung
(Locking) generiert, bei „false“
nicht
35
mappedByOtM
no
false(default)
Der „true“-Parameter aktiviert
die „mappedBy“-Annotation
für „OneToMany“- und
„MannyToMany“-Relationen in
TLGen
false(default)
Wenn vorhanden, generieren
die Callback Klassen für
REST interfacess an dieser
Adresse
106
StarData Gmb
V 2.8
der Entity-Generierung.
36
restPort
no
8080(default)
Wenn vorhanden, wird für
REST die Test Klasse als port
verwendet, wenn nicht
vorhanden, wird das Post
„8080“ verwendet
37
foreignKeyIndex
no
false(default)
false = no foreign key is not a
index, true yes
38
jsonLocking
no
false(default)
false = version variable (for
locking) from data class in not
generate in JSon data class,
by true yes.
39
mapping
no
true(default)
true = mapping the data
classes with the JSon classes
if this is generates, false = no
40
getManager
no
true(default)
true = generate in “entity
manager” class the method
getEntityManager() for
instance a
“javax.persistence.EntityManager
”
public class MyIntStack {
private final LinkedList fStack;
public MyIntStack() {
fStack = new LinkedList();
}
public int pop() {
return ((Integer) fStack.removeFirst()).intValue();
}
public void push(int elem) {
fStack.addFirst(new Integer(elem));
}
public boolean isEmpty() {
return fStack.isEmpty();
}
}
Listing 75: „Java“ Code style
public class MyIntStack
{
private final LinkedList fStack;
public MyIntStack()
{
fStack = new LinkedList();
}
public int pop()
{
return ((Integer) fStack.removeFirst()).intValue();
}
public void push(int elem)
TLGen
107
StarData Gmb
V 2.8
{
fStack.addFirst(new Integer(elem));
}
public boolean isEmpty()
{
return fStack.isEmpty();
}
}
Listing 76: „C“ Code style
Die JNDI-Namen der Session Beans werden von TLGen anhand der Attribute
appserver=“{jboss|weblogic|websphere}“ (Generator-Tag), earname (Project-Tag) sowie der
Package-Namen automatisch zusammengestellt und in den Attributen name und mappedName
der Annotationen @Stateless/@Statefull gespeichert. Der JNDI-Name der Session-Bean sowie
falls nötig, der Remote-JNDI-Name (jeder Application Server generiert beim „deployen“ andere
Namen), werden in den Client-Interfaces der Session-Beans als statische Variablen
gespeichert.
Z.B. reicht bei einem bestimmten Application Server nur der Interface-Name der Session Bean,
um diesen lokal im Application Server zu finden. Für einen Remote-Aufruf ist aber der Name
aus dem EAR-Namen, seinem Package-JAR, dem Session-Bean Namen und dem InterfaceNamen nötig. Dies wird für die drei oben genannten Application Server automatisch generiert
und mit der Klasse ServiceLocator aus den Commons Code-Beispielen automatisch bei einem
Remote-Aufruf beachtet.
Doch die automatischen Namen können mit Hilfe der Attribute MappedNameRemote, JNDIName
und JNDINameRemote des Projekt Tags mit eigenen Definitionen überschrieben werden. Im
Folgenden einige Beispiele womit der Generator die Ersetzungsnamen innerhalb von %...%
ersetzt:
-
MappedNameRemote= "%earname%/%jndiname%/%remote%"
-
JNDIName="de.stardata.test.server.persistence.%package%.%classname%SessionBean"
-
JNDINameRemote="ejb/%earname%/%package%.jar/%interfacemanager%#%clientdata%"
-
JNDINameRemote="ejb/%earname%/%package%.jar/%classname%SessionBean#%clientdata%"
-
JNDINameRemote="ejb/%earname%/%package%.jar/de.stardata.test.server.persistence.%package%.
%classname%SessionBean#de.stardata.test.client.bci.%package%.%classname%Bci"
Ersetzungsnamen:
-
%interfacemanager% entspricht hier folgender Ersetzung:
de.stardata.test.server.persistence.%package%.%classname%SessionBean
-
%interfacemanagershort% entspricht hier folgender Ersetzung:
%classname%SessionBean
-
%clientdata% entspricht hier folgender Ersetzung:
de.stardata.test.client.bci.%package%.%classname%Bci
TLGen
108
StarData Gmb
V 2.8
-
%package% oder %classname% wird aus den jeweiligen Designs und der StandardKonfigurationsdatei bestimmt (siehe entsprechende Kapitel, Fehler! Verweisquelle
konnte nicht gefunden werden.).
4.5.2.3 <Locator> Tag
Diese Daten überschreiben die Daten von 4.4.2.3.
4.5.2.4 <Design> Tag
<Design>-Elemente sind eine logische Fachgruppe innerhalb eines Projektes und können beliebig viele sein. Eine Design Komponente ist als eine fachspezifische logische Einheit gedacht.
Kinder-Elemente können mehrere Session Beans, Datenobjekte, Manager- und Entity Beans
sein. Der <Design>-Tag hat folgendes Attribut:

name, ist der Name für Design Komponente

archive, ist ein int und hat folgende Werte:

o
0 = archive für diese als „jar“ Datei
o
1 = archive als „war“ Datei
o
2 = archive als „jar“ und „war“ Datei
criteria (dfault false), wenn „true“ generiert für dieses design alle criteria und meta
Klassen.
4.5.2.4.1 Regel für package Generierung
Empfohlene path Struktur ist:
"Netz“.“Firma-Name“.%project%.Komponent.%package%.%classname%Endung
Wo:






„Netz“ ist das nationale Netz, z.B. für Deutschland „de“
„Firma-Name“ ist der Name der Firma, z.B. für „Demo“ Beispiel ist „stardata“
„Komponent“ ist eine Programmkomponente, z.B „business“ oder „server.persistence“
„%package%“ ist eine Fach-Logik definierte Komponente, z.B, „product“, „user“
„%classname%“ ist der Java Klassen Name, z.B. „Product“
„Endung“ ist eine vordefinierte Endung, die Hilfe für eine bessere Codestrukturierung ist
g, z.B. „Entity“, „Session“
4.5.2.4.2 <Commentary> Tag
Siehe Kap. 3.12
TLGen
109
StarData Gmb
V 2.8
4.5.2.4.3 <Class> Tag
Dieser Tag wird zur Generierung von Business Daten-Klassen verwendet. Dessen Daten
überschreiben die Daten von 4.4.2.4.
Ist ein optionales Element. Dieses Element generiert Daten-Klassen und Interfaces und hat
folgende Attribute:

name = "de.stardata.demo.business.product..data.%classname%Data|
de.stardata.demo.business.product.dataif.%classname%DataIf" hat zwei Teile, einen für
die Klassen und einen für die Interfaces, getrennt durch „|“Für die automatischen
Namen sind Platzhalter verwendet worden:
o

%classname% dieses Attribut wird automatisch vom Generator durch den
Objekt Namen aus dem Domain Modell ersetzt oder den Tabellen-Namen oder
geänderten Tabellen-Namen (durch Rules), welche aus der Datenbank gelesen
wurden (z.B. bei einem Legacy-Projekt).
type = „public“, d.h. Klassen und Interfaces sollen public sein.
Dieser Tag hat zwei Kinder-Elemente-, die optional sind, und folgende Standard-Einstellungen:

<Extends name="com.tlgen.common.data.BaseData"/>, kann eigene super Class
verwenden.

<Extends name="com.tlgen.common.data.BaseDataIf" type="interface"/>
4.5.2.4.4 <Entity> Tag
Dieser Tag wird verwendet, um den Generator mit Informationen über die Entities zu versorgen.
Er ist optional und überschreibt die Daten von 4.4.2.5, falls vorhanden.
Der Entity-Tag hat folgende Attribute:

name = "de.stardata.server.persistence.product.entity.%classname%Entity"
(Beschreibung wie in 4.5.4.2.1)

seqstrategy="SEQUENCE" ist Default-Wert. Dieses Attribut ist für die automatische
Generierung von Primary Key notwendig (z.B. Oracle).
Dieser Tag hat folgende Kinder-Tags, die optional sind:

<Implements> mit Attribute name="java.io.Serializable"

<Extends> mit Attribut name="com.tlgen.common.ejb.entity.BaseEntityBean"

<Annotation>, dieser Tag ist optional und der Generator generiert folgende
Annotationen für die Entities:
o
TLGen
"javax.persistence.Entity"
110
StarData Gmb
V 2.8
o
"javax.persistence.Table" der Generator übernimmt automatisch den TabellenNamen
o
"javax.persistence.SequenceGenerator"
Folgende Kinder-Tags sind möglich (mit Beispiel der Standard-Klasse):
<Extends name="com.tlgen.common.ejb.entity.BaseEntityBean"/>
4.5.2.4.5 <Manager> Tag
Dieser Tag versorgt den TLGen Generator mit Informationen für die Generierung von ManagerBeans und hat folgende Attribute:

name="eu.stardata.server.persistence.product.manager.%classname%Manager
(Beschreibung wie in 4.5.4.2.1)

transactiontype = "JTA“(Standard-Wert)
exception = "com.tlgen.common.exception.PersistenceException" (Standard-Wert)
Dieser Tag hat folgende Kinder-Tags, die optional sind:

<Extends> (Standard-Attribut name=" com.tlgen.common.ejb.manager.BaseManager ")

<Annotation>, dieser Tag ist optional und der Generator generiert z.B. folgende
Annotationen für die Entities:
o
"javax.ejb.Stateless"
o
"javax.ejb.Local"
Die Manager Fields-Beschreibung siehe unter Kap 4.5.2.6
4.5.2.4.5.1 Feldern (Variable) für Entity Manager
Folgende Felder (siehe auch 4.5.2.6) werden für eine Manager Klasse generiert:

m_manager mit Type „javax.persistence.EntityManager“. Dieses Field hat eine
Annotation von type (javax.persistence.PersistenceContext) und ein Parameter von type
String (MANAGER_NAME) (siehe 4.5.2.4.5).

m_“SQL Name“, sind die Fields, die die generierte „Native“ oder „Neimed“ SQL
beinhalten, siehe Listing 77: SQL Fields
private String m_countCustomer = "select count(o) from CustomerEntity o";
private String m_NativeQuery00 = "SELECT * FROM CUSTOMER WHERE CUSTOMER_ID = ?";
private String m_findByName = "select o from CustomerEntity o where o.lastName = :lastName";
Listing 77: SQL Fields
TLGen
111
StarData Gmb
V 2.8
4.5.2.4.5.2 Methoden für Entity Manager
Wie in 3.4.1 bereits erwähnt, gibt es drei Möglichkeiten bzw. Methoden um die Manager zu
generieren, auch die internen Methoden des Managers, Standard Remote-Methoden oder eine
user definierte Methode für die Persistente-Datenverwaltung. Die ersten zwei sind in 4.5.2.5
beschrieben.
Die dritte Art von Manager Methoden sind die Methoden mit Methodentyp methodtype=6, 7, 8
und 9 (siehe ab 4.5.2.4.5.2.1 bis 4.5.2.4.5.2.6). Diese Methoden definieren ein SQL Query und
brauchen eine oder mehrere <Parameter>-Tags für die Beschreibung der Input-Daten sowie
ein <Sql>-Tag.
Für diese Methoden sind folgende Attribute notwendig:

name=“NamedQuery01“, ist der Methoden Name

manager=“Formular“, benennt den Manager und wo die Methode generiert wird.

mapping=“false“, besagt, ob eine Mapping notwendig ist oder nicht (Default ist „false“,
aber für die Native-SQLs ist fast immer eine Mapping nötig)

return=“java.util.List<%interfacedata%>“, ist der erwartete Return Type. Dieser
Platzhalter wird vom Generator durch das richtige Interface ersetzt.

methodtype= „6“, „7“, „8“, „9“, „10“ oder „11“.
Im Folgenden erfolgt die Beschreibung der Methoden-Typen.
4.5.2.4.5.2.1 Entity Menager Methoden Typ 6
Method-Typ 6 sind Methoden, die für EJB-SQL gedacht sind (Listing 78)
<Method name="findByNameAndOffer" parameter="java.lang.String" return="%interfacedata%[]" manager="Product"
methodtype="6">
<Parameter name="name" fullName="name" type="java.lang.String" />
<Parameter name="productOfferingId" fullName="productOfferingId" type="java.lang.String" />
<Sql name="getNameAndOffer" sql="select u from ProductEntity u where u.name = :name and
u.productOfferingId = :productOfferingId" />
</Method>
Listing 78: Methode Type „6“ in der Konfigurationsdatei
In Beispiel, Listing 78 wird bzw. werden eine oder mehrere Product Objekt(e) nach dem
Produkt-Namen und einer ID productOfferingId gesucht.
TLGen
112
StarData Gmb
V 2.8
TLGen generiert daraus im Manager Bean der Klasse Product Manager ein Feld und eine
Zugriffsmethode:
private String m_getNameAndOffer = "select u from ProductEntity u where u.name = :name and u.productOfferingId
= :productOfferingId";
/**
* Manager method "findByNameAndOffer()"
* @param name
* @param productOfferingId
* @return
* @throws PersistenceException
*/
public ProductDataIf[] findByNameAndOffer(String name, String productOfferingId) throws PersistenceException {
try {
ProductDataIf[] arrayData = null;
List<?> list = m_manager.createQuery(m_getNameAndOffer).setParameter("name",name).
setParameter("productOfferingId",productOfferingId).getResultList();
if(list != null && list.size() > 0) {
arrayData = new ProductDataIf[list.size()];
int idx = 0;
for(Object entity : list) {
if(entity != null) {
arrayData[idx++] = ((ProductEntity)entity).callProduct();
}
}
}
return arrayData;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
Listing 79: Methode Typ “6” in Entity Manager-Klasse
4.5.2.4.5.2.2 Entity Menager Methoden Typ 7
Methoden von Typ 7 sind fürNamed SQLs gedacht (siehe Listing 8080).
<Method name="NamedQuery02" manager="Formular" return="java.util.List<%interfacedata%>"
methodtype="7">
<Parameter name="developName" type="java.lang.String" />
<Sql name="Formulartest" sql="SELECT f FROM FormularEntity f WHERE f.developer LIKE
:developName" />
</Method>
Listing 80: Methode Type “7” in der Konfigurationsdatei
TLGen
113
StarData Gmb
V 2.8
TLGen generiert daraus eine Methode in der Manager-Klasse (Listing 81) und eine Annotation
@javax.persistence.NamedQueries in der dazugehörigen Entity-Klasse (Listing 82):
/**
* Manager method "NamedQuery02()"
* @param developName
* @return
* @throws PersistenceException
*/
public List<CoFormularDataIf> NamedQuery02(String developName) throws PersistenceException {
try {
List<CoFormularDataIf> list = null;
List<?> entityList = m_manager.createNamedQuery("sqlFormulartest").
setParameter("developName",developName).getResultList();
if(entityList != null && entityList.size() > 0) {
list = new ArrayList<CoFormularDataIf>();
for(Object entity : entityList) {
if(entity != null) {
list.add(((FormularEntity)entity).callFormular());
}
}
}
return list;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
Listing 81: Methode Type “7” Entity Manager-Klasse
@NamedQueries
({
@NamedQuery( name = "sqlFormulartest", query = "SELECT f FROM FormularEntity f WHERE f.developer
LIKE :developName")
})
Listing 82: Methode Typ “7” in der Entity-Klasse
4.5.2.4.5.2.3 Entity Menager Methoden Typ 8
Methoden von Typ „8“ werden für die Native SQL Queries verwendet. Ein Beispiel für den
Eintrag in die Konfigurationsdatei befindet sich in Listing 83.
<Method name="NativeQuery02" manager="Formular" mapping="true"
return="java.util.List<%interfacedata%>" methodtype="8">
<Sql sql="SELECT * FROM CORE_FORMULAR, CORE_PAGE WHERE CORE_FORMULAR.
FORMULAR_ID = CORE_PAGE.FORMULAR_ID AND CORE_FORMULAR.FORMULAR_ID = ?" />
</Method>
Listing 83: Methode Typ „8“ in der Konfigurationsdatei
TLGen
114
StarData Gmb
V 2.8
Der notwendigen Parameter für diese Methode werden von TLGen automatisch aus den
Datenbank-Informationen heraus generiert. TLGen generiert aus diesem Eintrag in der
Konfigurationsdatei eine Entity-Class (Listing 84) und die dazugehörige Daten-Klasse sowie
deren Interfaces (fals verwendet) (Listing 85).
package eu.stardata.server.persistence.formular.entity;
import eu.stardata.business.form.dataif.CoPageDataIf;
import javax.persistence.NamedNativeQueries;
import javax.persistence.SqlResultSetMapping;
import eu.stardata.business.form.dataif.CoNativeQuery02DataIf;
import javax.persistence.NamedNativeQuery;
import javax.persistence.EntityResult;
import javax.persistence.SqlResultSetMappings;
import javax.persistence.Column;
import eu.stardata.server.persistence.formular.entity.FormularEntity;
import eu.stardata.server.persistence.formular.entity.PageEntity;
import eu.stardata.business.form.dataif.CoFormularDataIf;
import javax.persistence.Id;
import javax.persistence.Entity;
@Entity
@NamedNativeQueries
({
@NamedNativeQuery( name = "NativeQuery02", query = "SELECT * FROM CORE_FORMULAR,
CORE_PAGE WHERE CORE_FORMULAR.FORMULAR_ID = CORE_PAGE.FORMULAR_ID AND
CORE_FORMULAR.FORMULAR_ID = ?", resultSetMapping = "NativeQuery02")
})
@SqlResultSetMappings
({
@SqlResultSetMapping(name = "NativeQuery02",
entities =
{
@EntityResult(entityClass = FormularEntity.class ),
@EntityResult(entityClass = PageEntity.class )
}
)
})
public class NativeQuery02Entity {
private static final long serialVersionUID = 597104846;
// Entity data field
private CoNativeQuery02DataIf m_nativeQuery02 = null;
// constructors
/**
* Default Constructor
*/
public NativeQuery02Entity() {
}
/**
* Constructor
* @param arg
*/
public NativeQuery02Entity(CoNativeQuery02DataIf arg) {
m_nativeQuery02 = arg;
fillNativeQuery02();
}
TLGen
115
StarData Gmb
V 2.8
// Helper methods
/**
* Helper Method "makeNativeQuery02()"
*/
public CoNativeQuery02DataIf makeNativeQuery02() {
if(m_nativeQuery02 == null) {
m_nativeQuery02 = new eu.stardata.business.form.data.CoNativeQuery02Data();
}
return m_nativeQuery02;
}
/**
* Helper Method "fillNativeQuery02()"
*/
public void fillNativeQuery02() {
}
/**
* Helper Method "addNativeQuery02()"
*/
public void addNativeQuery02() {
}
/**
* Helper Method "callNativeQuery02()"
*/
public CoNativeQuery02DataIf callNativeQuery02() {
// return the data object
return makeNativeQuery02();
}
// Methods from class
public CoFormularDataIf getFormular() {
return makeNativeQuery02().getFormular();
}
public void setFormular(CoFormularDataIf arg) {
makeNativeQuery02().setFormular(arg);
}
public CoPageDataIf getPage() {
return makeNativeQuery02().getPage();
}
public void setPage(CoPageDataIf arg) {
makeNativeQuery02().setPage(arg);
}
@Id
@Column(name = "FORMULAR_ID")
public long getFormularId() {
return makeNativeQuery02().getFormularId();
}
public void setFormularId(long arg) {
makeNativeQuery02().setFormularId(arg);
}
}
Listing 84: Methode Typ „8“ in Entiy-Klasse
TLGen
116
StarData Gmb
V 2.8
package eu.stardata.business.form.data;
import eu.stardata.business.form.dataif.CoPageDataIf;
import eu.stardata.business.form.dataif.CoFormularDataIf;
import eu.stardata.business.form.dataif.CoNativeQuery02DataIf;
import com.tlgen.common.data.BaseData;
public class CoNativeQuery02Data extends BaseData implements CoNativeQuery02DataIf {
private static final long serialVersionUID = 883471837;
// Methods from columns
private long m_formularId;
// Methods from class
private CoFormularDataIf m_formular;
private CoPageDataIf m_page;
// Methods from columns
public long getFormularId() {
return m_formularId;
}
public void setFormularId(long arg) {
m_formularId = arg;
}
// Methods from class
public CoFormularDataIf getFormular() {
return m_formular;
}
public void setFormular(CoFormularDataIf arg) {
m_formular = arg;
}
public CoPageDataIf getPage() {
return m_page;
}
public void setPage(CoPageDataIf arg) {
m_page = arg;
}
}
und Daten interface:
package eu.stardata.business.form.dataif;
import eu.stardata.business.form.dataif.CoPageDataIf;
import eu.stardata.business.form.dataif.CoFormularDataIf;
import com.tlgen.common.data.BaseDataIf;
public interface CoNativeQuery02DataIf extends BaseDataIf {
// Methods from columns
public abstract long getFormularId();
public abstract void setFormularId(long arg);
// Methods from class
public abstract CoFormularDataIf getFormular();
public abstract void setFormular(CoFormularDataIf arg);
public abstract CoPageDataIf getPage();
public abstract void setPage(CoPageDataIf arg);
}
Listing 85: Daten-Klasse für die Methode Typ „8“
TLGen
117
StarData Gmb
V 2.8
4.5.2.4.5.2.4 Entity Menager Methoden Typ 9
Liste Objekte in DB mit createQuery() EntityManager Methode.
4.5.2.4.5.2.5 Entity Menager Methoden Typ 10
Liste Objekte in DB mit createNativeQuery() EntityManager Methode.
4.5.2.4.5.2.6 Entity Menager Methoden Typ 11
Methoden von Typ „11“ werden für die Criteria verwendet. Ein Beispiel für den Eintrag in die
Konfigurationsdatei und in Entity Manager befindet sich in Listing 45.
4.5.2.4.5.3 Manager Interfaces
TLGen generiert für jede Manager-Klasse automatisch ein Interface, notwendig für die
Verwendung von Entity Manager Beans (siehe 3.4.2).
4.5.2.4.6 <Session> Tag
Dieser Tag versorgt den Generator mit allgemeinen Informationen für die Generierung einer
Session Bean. Diese Daten überschreiben die Daten aus 4.4.2.10. TLGen kann in zwei
Varianten verwendet werden:
1. Die Code-Generierung aus einem UML Domain-Modell ist besonders für neue Projekte
geeignet. Um den Zeit- und Kostenaufwand zu minimieren, sollten für die Generierung
die meisten Informationen über die Standard Konfigurationsdatei und nur die
spezifischen Informationen wie Name, Native Queries und Test Klassen über die Konfigurationsdatei erfolgen.
2. Für die Code-Generierung aus einer existierenden Datenbank ist die Verwendung der
Konfigurationsdatei intensiver nötig als die der Standard Konfigurationsdatei, da die
gelesenen Daten über die Tabellen aus der Datenbank auf fachlogische Kriterien über
die Design Session Beans verteilt werden müssen.
Das Session Bean-Element kann folgende Attribute verwenden:
TLGen
118
StarData Gmb
V 2.8

name="de.stardata.demo.server.persistence.product.ProductSessionBean", ist der
vollständige Klassenname (Pfad und mit Platzhalter für alle Session Beans).

managername="managerProduct", gibt Informationen dem manager, die für die
„persistence.xml“-Datei notwendig sind (siehe 4.5.2.4.5).

transactiontype="JTA" gibt die Information für die Transaction-Typ.
Session Bean hat z.B. folgende mögliche Annotationen:

name="javax.ejb.Stateless", oder „javax.ejb.Stateful“

name="javax.ejb.Remote"

name=” javax.interceptor.Interceptors”, nur wenn die Session Beans eine InterceptorKlasse verwenden.
Wenn die Session Bean als Web Service oder als Timer Service verwendet wird, können auch
andere Annotationen verwendet werden (siehe 4.5.2.4.6.4, 4.5.2.4.6.5).
4.5.2.4.6.1 Methoden für Session Bean
Session Bean übernimmt alle oder nur die auserwählten Methoden von Entity Manager, die
über die Session Bean aufgerufen werden (Details in 4.5.2.4.5).
Diese Methoden haben den Namen der Methode und dazu noch den Manager-Name; z.B. die
Methode „findByPrimaryKey“ für das Manager Formular hat den Namen
„findByPrimaryKeyFormular“. Diese Zusammensetzung von Namen ist notwendig, weil der
Name „findByPrimaryKey“ in mehrere Manager-Beans, verwaltet über diese Session Beans,
vorhanden sein kann.
Dieser Name wird bis zum Client hindurch gleichbleibend verwendet.
4.5.2.4.6.2 <Client> tag
Ist ein Kindelement der Session Beans und dient zur Generierung von Client-Aufrufen. Auch
dieser Tag ist optional.
Dieser Tag hat folgende Attribute mit folgenden Standard Werten:

name="de.stardata.demo.client.bci.product.ProductBci"

exception = "com.tlgen.common.exception.PersistenceException"
Aus diesen Informationen generiert TLGen ein Interface (Listing 86: Client Interface), notwendig
für eine Session Bean, und eine Factory Klasse, welche den Aufruf seitens Client erleichtert
(Listing 87):
package de.stardata.demo.client.bci.product;
TLGen
119
StarData Gmb
V 2.8
import javax.ejb.Remote;
import de.stardata.demo.business.product.dataif.ProductPriceDataIf;
import de.stardata.demo.business.product.dataif.ProductAttributeDataIf;
import java.lang.String;
import de.stardata.demo.business.product.dataif.ClassificationDataIf;
import de.stardata.demo.business.product.dataif.ProductRelationDataIf;
import com.tlgen.common.exception.PersistenceException;
import de.stardata.demo.business.product.dataif.ProductDataIf;
@Remote
public interface ProductBci {
// Client interface Fields
public final static String JNDI_NAME = "de.stardata.demo.server.persistence.
product.ProductSessionBean";
public final static String MANAGER_NAME = "managerProduct";
public final static String EAR_NAME = "demo";
…..
public ProductDataIf createProduct(ProductDataIf arg) throws PersistenceException;
public ProductDataIf findByPrimaryKeyProduct(ProductDataIf arg) throws PersistenceException;
public void removeProduct(ProductDataIf arg) throws PersistenceException;
….
}
Listing 86: Client Interface
package de.stardata.demo.client.bci.product;
import de.stardata.demo.client.bci.product.ProductBci;
import com.tlgen.common.exception.PersistenceException;
import com.tlgen.common.bci.BciFactory;
public class ProductBciFactory extends BciFactory {
private static final long serialVersionUID = 1033431309;
/**
* getProductBci()
*/
public static synchronized ProductBci getProductBci() throws PersistenceException {
return (ProductBci)getBciImplementation(ProductBci.class);
}
}
Listing 87: Factory Client Class
Mit Hilfe des Interface und der Factory-Klasse ist der Aufruf seitens Client sehr einfach (Listing
88):
ProductDataIf m_clProduct = new ProductData();
// Versorgung von Product Attribute mit Werten
…..
ProductBci factory = ProductBciFactory.getProductBci();
// Speichern von Product Object in die Datenbank
m_clProduct = factory.createProduct(m_clProduct);
// Lesen von den Product Object für ein Id
clProduct.setProductId(10);
TLGen
120
StarData Gmb
V 2.8
ProductDataIf product = factory.findByPrimaryKeyProduct(m_clProduct);
Listing 88: Client call‘s
4.5.2.4.6.3 <Xml-persistence> Tag
Der Tag setzt die Properties der persistence.xml, z.B. notwendig in einer EAR, um die eigene
Applikation in einem Application Server zu installieren. Diese Werte sind vom Applikation
Server abhängig. Statt der Attribute value wird hier type für <Property> verwendet.
<Property name="hibernate.dialect" type="org.hibernate.dialect.Oracle10gDialect" />
Beispiel: JBoss Version 5.x brauchte bei Verwendung der Oracle-Datenbank Version 11.x die
folgende Information, um eine Datenbank-Verbindung aufzubauen:
<Property name="hibernate.dialect" type="org.hibernate.dialect.Oracle10gDialect" />
Diese Daten überschreiben komplett oder nur teilweise die Daten aus 4.4.2.10.3.
4.5.2.4.6.4 < Timerservice> Tag
Ein Timer Service kann mit einer Session Bean oder Message Driven Bean verwendet werden.
Damit kann eine Methode entweder an einem bestimmten Tag und zu einer bestimmten Zeit
aufgerufen werden oder aber alle n Sekunden. Diese Methode über eine Callback Class kann
einen Prozess steuern, starten, periodisch aufrufen oder stoppen.
Timer Service kann in drei unterschiedlichen Varianten verwendet werden:

Voll automatisch, in diesem Fall sollten Start, Stopp-Zeit und die periodische
Wiederholung initialisiert werden (Attribut type=“auto“).

Start und Stopp-Zeit wird durch einen Client-Aufruf gesteuert (Attribut type=“manuell“,
das ist die Default–Einstellung).

Man verwendet die automatische und die manuelle Steuerungsmöglichkeit (Attribut
type=“merge“) (siehe 3.8).
Es folgt eine Beschreibung der notwendigen Konfigurationsdaten.
Folgende Kinderelemente sind für diesen Tag notwendig:

<Variable> (Daten-Struktur dieses Tags siehe 4.5.2.6) für folgende Felder:
o
TLGen
timerService, mit der Annotation „javax.annotation.Resource“ und dem vartype
= "javax.ejb.Timerservice", wird für die Zeit-Steuerungs Methoden benötigt.
121
StarData Gmb
V 2.8
o

<Method> (Daten-Struktur dieses Tags siehe 4.5.2.5) sind Methoden, die der Timer
Service benötigt. Folgende Methoden sind notwendig:
o

Eine Kommando Variable mit folgende Daten: vartype = „string“, um den
Timerservice zu beenden.
name = „init%Name%“, notwendig für die automatische Verwendung von Timer
Service und dessen Initialisierung mit folgenden notwendigen Parameter (siehe
Listing 43):

<Parameter> name=“start“, definiert den Beginn dieser Service,
type=“date“ ist die Start-Zeit

<Parameter> name=“stop“, definiert das Ende dieser Service,
type=“date“, ist die Ende-Zeit

<Parameter> name=“repeat“, definiert die Wiederholungsrate;
type=“long“, ist die Wiederholung von Zeit in Sekunden.
o
name = „timeout“, wird bei beiden Varianten der Timer Service-Verwendung
benötigt. Diese hat eine Annotation „@javax.ejb.Timeout“ und ruft die Callback
Methode „timeout“ auf.
o
name = „start%Name%“, startet diese Service nach einem Client-Aufruf, ist für
die manuelle Timer Service-Verwendung notwendig
o
name=“stop%Name%“, stoppt manuell den Prozess.
<Callback> ist eine Klasse, deren Methoden von Timer Service Methoden aufgerufen
werden, um Prozesse zu steuern. Werden mehrere Methoden verwendet, sollen die
Namen dieser Methoden mit den Namen der Timer Service-Methoden identisch sein.
Diese Klasse wird vom Generator generiert. Die Inhalte dieser Methoden müssen per
Hand programmiert werden. Dieser Tag hat folgende Attribute und Kinderelemente:
o
Name (Attribute) = „eu.stardata.client.monitor.CallBackServiceMonitor“, ist der
Callback Klassenname
o
Path (Attribute) = “C:/Project-TLGen-2.8/source/test”, ist der Ort, wo diese
Klasse generiert wird.<Method> (Kindelement); ist die aufzurufende Methode
und kann mehrmals vorkommen.
<Method type="public void" name="initMonitor">
<Parameter type="15.04.2011 10:30" name="start"/>
<Parameter type="16.05.2011 9:30" name="stop"/>
<Parameter type="600" name="repeat"/>
</Method>
Listing 89: Konfigurationsdatei-Eintrag für eine Timer Service-Klasse
4.5.2.4.6.5 < Web Service> Tag
Ein Web Service ist ein beliebiger Service (z. B. eine Session Bean), der von einem Client über
z.B. das Internet aufgerufen werden kann.
Es werden zwei Arten von Web Service unterschieden, RPC (Remote Procedure Call) und
DOCUMENT. RPC , ein Aufruf einer Methode (z. B. eine Methode von einem Session-Bean)
über Web.
TLGen
122
StarData Gmb
V 2.8
TLGen generiert für diese Services den Client, den Web Service und eine Callback-Klasse
(siehe 3.8), falls diese nötig ist.
4.5.2.4.6.6 <Interceptor> Tag
Dieser Tag wird für die Generierung von Session Bean Interceptoren verwendet und hat folgende Attribute:

name=“eu.stardata.server.persistence.formular.TimeFormular“, ist der Interceptor
Klassen-Name

path=” C:/Project-TLGen-2.8/source/generated”, ist der Ort, wo die Interceptor Klasse
generiert wird.
Ein Interceptor kann eine oder mehrere Methoden haben (siehe 4.4.2.10.4).
4.5.2.4.6.7 <Freeclass> Tag
Dieses Element wird für die Generierung einer Klasse, die als Schnittstelle zu dem Programmteil, welcher die Fachlogik beinhaltet, verwendet. Der Inhalt dieser Klasse muss selber
implementiert werden. Falls der Generator diese Klasse in dem angegebenen Pfad findet,
generiert er, abhängig vom Attribut „merge“, die Differenz aus beiden, ohne die vorhandenen
Methoden zu löschen.
Folgende Attribute werden für diesen Tag verwendet:

name=“eu.stardata.server.persistence.user.MappingEngine“, ist der Klassen-Name mit
Pfad.

path=” C:/Project-TLGen-2.8/source/user”, ist der Ort, wo diese Klasse generiert wird.

merge, dieses Attribut hat folgende Werte:
o
merge = 0, TLGen generiert diese Klasse immer wieder neu.
o
merge = 1, diese Klasse wird, nur wenn sie nicht existiert, generiert.
o
merge = 2, wird eine neue Klasse generiert und mit dem vorhandenen per Hand
implementierten Code zusammengefasst.
Diese Klasse kann eine oder mehrere Methoden haben.
4.5.2.4.6.8 <Callback> Tag
Eine <Callback> Tag (siehe) kann folgende Attribute verwenden:


TLGen
name ist der komplette Klassen-Name, z.B. „eu.stardata.demo.rest.CallBackRest“
callbackType kann folgende Inhaltswerte (Strings) haben
o „Session“, für alle „Timerservice“, “REST“, und „Web Service“
o „Class“ ist der Default-Wert
123
StarData Gmb
V 2.8


path ist die Adresse wo diese Klasse generiert wird, z.B. „C:/Projects/demo“
merge, siehe 3.8
4.5.2.4.7 < Message Driven> Tag
TLGen verwendet die Daten in diesem Element für die Generierung von Message Driven Bean.
Diese hat ein einziges Attribut; name = “Chat“ und zwei Kinderelemente <Client> (siehe
4.5.2.4.7.1) und <Bean> (siehe 4.5.2.4.7.2).
Ein Beispiel für die Konfigurationsdatei ist in Fehler! Verweisquelle konnte nicht gefunden
werden. und für den generierten Code in 7.12 zu finden.
4.5.2.4.7.1 <Client> Tag für Message Driven Bean
Der Client-Tag hat folgende Attribute:

name=“eu.stardata.client.bci.chat.ChatBci|
eu.stardata.client.message.chat.ChatMessageClient“, hat zwei Teile, der erste Teil
beinhaltet den vollständigen Namen für das Client-Interface und der zweite Teil für die
Client-Klasse.
Der <Client> Tag benötigt zwei Kinderelemente:
1. <Commentary>, wird benutzt, um die Message Driven Bean zu beschreiben,
2. <Variable> (für die Daten Struktur siehe 4.4.2.14), beschreibt mehrere Felder:
a. name=“JNDI_NAME_SENDER“, ist das Senderfeld und braucht noch ein
Attribut content=“gueue/queueA“, JNDI für den Sender (der Inhalt ist frei
wählbar) und ein Attribut comtype=“0“. Dieses Feld ist Pflicht.
b. name=“JNDI_NAME_RECEIVER“, ist das Senderfeld und braucht noch ein
Attribut content=“topic/topicA“, JNDI für den Receiver (der Inhalt ist frei wählbar)
und ein Attribut comtype=“1“. Dieses Feld wird, nur wenn eine Antwort vom
Server notwendig ist, verwendet.
c. name=“ACKNOWLEDGE_MODE“, dieses Field bestimmt wie der App.Server
diese Nachricht quittiert oder überhaupt nicht. Im Attribut content sind zwei
Eintragungen möglich, „Auto-acknowledge“ als Standard, bei diesem quittiert der
APP.Server sofort die erhaltene Nachricht und „Dups-ok-acknowledge“, bei
diesem lässt sich der Server für die Quittierung etwas Zeit.
Bemerkung: comtype Attribut kann folgenden Inhalt haben: „0“ oder „queue“ für „Point-ToPoint“ Kommunikation und „1“ oder „topic“ für eine „Publish-and-Subscribe“ Kommunikation.
4.5.2.4.7.2 <Bean> Tag für Message Driven Bean
TLGen
124
StarData Gmb
V 2.8
Dieser Tag hat ein Attribut und mehrere Kinder-Tags. Dessen Attribut ist ein vollständiger
Name, z.B. name=“eu.stardata.server.message.chat.ChatMessageBean“. Die Message Driven
Bean braucht eine Annotation, „@javax.ejb.Messag, um die Kommunikationeigenschaften zu
definieren. Diese Informationen können über die Konfigurationsdatei dem Generator übergeben
werden.
<Annotation name="javax.ejb.ActivationConfigProperty">
<Parameter type="MessageFormat = 'ChatMessage'" name="messageSelector"/>
</Annotation>
Listing 90: Message Driven Bean
Folgende Parameter werden in der Konfigurationsdatei nach dem Muster von Listing 44
definiert werden:
1. Parameter type = "%connectclass%" name = "destinationType". Das Attribut type
kann “javax.jms.Queue” oder “javax.jms.Topic” sein und der Platzhalter wird vom
Generator mit dem comtype Attribut vom Client ersetzt.
2. Parameter type = "%connect%" name = "destination"; der Platzhalter wird vom
Generator mit Variable “JNDI_NAME_SENDE ” Inhalt ersetzt, in unserem Beispiel mit
„gueue/queueA“.
3. Parameter type = " MessageFormat = 'ChatMessage' " name = "messageSelector";
über diesen Parameter für Kommunikation-Properties kann bestimmt werden, welche
Nachrichten der Bean zugestellt werden.
4. Parameter type="Auto-acknowledge" name = "acknowledgeMode" sind optional.
5. Parameter type="NonDurable" name="subscriptionDurability" sind Standard und für
wichtige Nachrichten, die unbedingt zugestellt werden müssen, sollte der type =
“Durable” gewählt werden.
Die Namen der zuvor beschriebenen Parameter sind nicht wählbar.
4.5.2.4.7.3 <Callback> Tag für Message-Driven Bean
Dieser Tag hilft dem Generator eine Callback-Klasse zu generieren, wo dann die Fachlogik
programmiert werden kann: Diese Klasse wird jederzeit, wenn ein Message zugestellt wird,
aufgerufen. Folgende Attribute sind für diesen Tag zu verwenden:
o
name (Attribute) = „eu.stardata.client.chat.CallBackServerChatMessage“, ist der
Callback Klassen-Name.
o
path (Attribute) = “C:/Project-TLGen-2.5/source/test”, ist der Ort, wo diese
Klasse generiert wird.
o
merge (Attribute) siehe 3.8
Die Callback Class kann eine oder mehrere Methoden haben (Listing 91):
TLGen
125
StarData Gmb
V 2.8
<Method name="callBackChat" return="javax.jms.Message">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="message" type="javax.jms.Message"/>
</Method>
Listing 91: Callback-Klasse für eine Message Driven Bean
4.5.2.4.8 <Test> Tag
Mit Hilfe des <Test>-Tags generiert TLGen eine Test-Klasse, abgeleitet vom
„junit.framework.TestCase“. Folgende Attribute können für diesen Tag verwendet werden:

name = „eu.stardata.client.test.formular.FormularWriteReadTest“ ist der Name der TestKlasse und ein Pflicht-Feld,

filename = “eu.stardata.client.test.formular.TestDataForFormular”; Ist dieses Attribut
vorhanden, wird eine XML Datei mit der Datenstruktur der Test-Klasse generiert.
Existiert diese Datei schon, werden die dort gespeicherten Daten für die Initialisierung
der Attribute der Testklasse für die „create“-Test-Methode verwendet (z.B. ein
Datenbank-Insert).
4.5.2.4.8.1 Generierung von Methoden für Test-Klassen
Über die Test-Methoden werden die Aktionen „create“ für die Speicherung eines neuen Objekts
in der Datenbank, „update“ für die Änderung eines Objekts, „find%Name%“ für das Lesen
eines oder mehrerer Objekt bzw. Objekte und „delete“ für das Löschen eines Objekts in der
Datenbank gesteuert. Die Daten-Struktur der Methoden siehe 4.5.2.5.
4.5.2.4.9 <Dbtable> Tag
Dieser Tag wird nur für die Generierung von Code auf Basis einer Datenbank verwendet und
hilft zur Gruppierung bestimmter Tabellen einer Design/Session Bean.
Das einzige Attribut ist name, welches gleich mit dem Tabellen-Namen sein muss. TLGen liest
alle anderen Informationen über dieseTabelle. Für jede Tabelle werden seitens TLGen eine
Daten-Klasse und deren Interface generiert (siehe 3.1).
In diesem Tag können Methoden, die nicht für die Datenpersistenz sondern nur für die
Fachlogik verwendet werden, mit Hilfe von <Method>-Tag definiert werden (4.4.2.13).
Hier können auch die Relationen zwischen den Tabellen mit Hilfe des <Relation>-Tags definiert
werden (4.5.2.4.9.1).
4.5.2.4.9.1 <Relation> Tag, Verwendung von Relationen
TLGen
126
StarData Gmb
V 2.8
Ein Relation Tag hat folgende Attribute:
1. name = „OneToMany“ definiert einen von der vier Relation-Typen: „OneToOne“,
„OneToMany“, „ManyToOne“ und „ManyToMany“,
2. table = „Table-Name“ ist der Tabellen-Name mit dem diese Relation durchgeführt wird
3. cascade = „Cascade-Type“; Folgende mögliche Cascade-Typen: „PERSIST“,
„MERGE“, „REMOVE“, „REFRESH“ oder „ALL“.
4. optional = „true“ oder „false“, (siehe 1)
5. fetchType = „EAGER“ oder „LAZY“ (siehe 1)
6. direction = „true“, „false“ ist eine Standard-Einstellung und gilt nur für die Relationen
„OneToOne“ und „ManyToMany“, wo ersichtlich ist, was für eine Tabelle die „Main“Table (Master/Slave-Prinzip) ist.
Der <Relation>-Tag hat zwei Kinder-Tags:
1. <JoinColumn> versorgt den Generator mit den Daten über die beteiligten Spalten
(Columns) zu dieser Relation. Dieser hat folgende Attribute:
a. name = „Column-Name“ ist der eigene Spalten-Name für diese Relation.
b. referencedColumnNam = „Column-Name“ ist der Spalten-Name anderer
Tabellen, beteiligt bei dieser Relation.
c. insertable = „true/false“
d. updatable = „true/false“
e. nullable = „true/false“
2. <JoinTable> versorgt den Generator mit Informationen über die dritte Tabelle
(notwendig für eine „ManyToMany“ Relation). Dieser hat folgende Attribute:
a. name ist der Tabellen-Name
b. catalog ist der Datenbank-Katalog
c. schema ist das Datenbankschema des Users
Dieser Tag hat zwei Kinderelemente:
1. <JoinColumn>, siehe Punkt 1, wo name der Spaltenname ist.
2. <InverseJoinColumn> die Spalte der anderen Tabelle.
4.5.2.5 <Method> Tag
Der Element <Method> hat folgende Attribute:

name ist der Methode-Name

return legt den Rückgabewert der Methode fest. Dieser kann neben den Standardtypen
wie String, int, lont, boolean etc. auch ein Array des Interface der aufrufenden Klasse
sein, z.B. %interfacedata%[] (TLGen ersetzt den Platzhalter automatisch).

manager ist der Manager Bean - Name

client ist der Client Name (nur für die Test-Klassen) über welchen diese Methode
aufgerufen werden kann.
TLGen
127
StarData Gmb
V 2.8

typerwd ist für den Datenbankzugriff-Typ (nur für die Test-Klassen). Dieses Attribut
kann folgende Werte haben: 0 für die Abspeicherung eines Objekts in der Datenbank, 1
für das Lesen, 2 für das Ändern und 3 für das Löschen.

methodtype ist eine Zahl und gibt dem Generator Informationen über Methode-Type.
Folgende Typen sind erlaubt:
o
METHOD_TYPE_ERROR = -1; method build is not possible
o
METHOD_TYPE_FREE = 0; free methods, SQL free methods
o
METHOD_TYPE_COLUMN = 1; methods generate from columns
o
METHOD_TYPE_RELATION = 2; methods generate from relation
o
METHOD_TYPE_CLASS = 3; from configuration file (user method)
o
METHOD_TYPE_STANDARD = 4; standard method
o
METHOD_TYPE_SQL_STANDARD = 5; Query SQL-EJB Format (Default, from configdefault XML, Methods createQuery)
o
METHOD_TYPE_SQL_EJB = 6; Query SQL-EJB Format (from config XML file, Method
createQuery())
o
METHOD_TYPE_SQL_NAMED = 7; Query SQL-Named (Method createNamedQuery(),
EJB named query type)
o
METHOD_TYPE_SQL_NATIVE = 8; Query SQL-Native (Method createNativeQuery(),
EJB native query type)
o
METHOD_TYPE_SQL_OBJECT = 9; Query SQL method over "QuereyObject" for
(Method create query)
o
METHOD_TYPE_SQL_NATIVE = 10; Query SQL method over "QuereyObject" for
(Method create Native Query)
o
METHOD_SQL_CRITERIA = 11; SQL Criteria generate
o
METHOD_TYPE_SQL_MAPPINGS = 12; annotations for SQL Mapping in Entity Beans
o
METHOD_TYPE_PRIMKEY = 13; method for primary key
o
METHOD_TYPE_CONSTRUCTOR = 14; method for class constructor
o
METHOD_TYPE_HELPER = 15; helper method
o
METHOD_TYPE_FACTORY = 16; factory method
o
METHOD_TYPE_SET_DATA= 17; method for set data object
o
METHOD_TYPE_SQL_VIEW = 18; Query SQL view
Bemerkung:
Soll eine Methode Callback-Klassen übernehmen, dann sollte in der Seasion Bean MethodeType = 0
sein
4.5.2.6 <Variable> Tag
Das Element <Variable>. hat folgende Attribute:

name, Name des Elements

vartype definiert den Field-Typ
TLGen
128
StarData Gmb
V 2.8

content = Ein „Platzhalter“, welcher durch den Generator mit den notwendigen
Informationen ersetzt wird.

fieldtype, mögliche Werte 0,1 oder 2. 0= Field wird in eine Klasse generiert, 1 in dessen
Interface und 2 in beide. 0 ist Standard-Wert.

abstract = true oder false (true ist der Standard-Wert) ist nur intern für den Generator.
Falls Field-Content eine Klasse ist, wird der Klassen-Pfad im import-Bereich der Klasse
hinein generiert.
TLGen
129
StarData Gmb
V 2.8
5
Verwendung von TLGen bei Softwarentwicklung (Bedingungsanleitung) und das
Beispiel „Demo“-Beschreibung
Die Verwendung von TLGen, Code-Generator, für die IT-Projektentwicklung basiert auf die
RUP (Rational Unified Process)-Vorgehensweise für Softwareentwicklung. Als Technische
Unterstützung wird empfohlen, das UML (Unified Modeling Language) als Modellierungsprache
zu verwenden.
TLGen, wie schon in Kap. 1 und 2 erwähnt, kann für eine vorhandene Datenbank (geeignet für
Legacy Projekten) oder für ein komplett neues IT Projekt verwendet werden.
Bei neuen Projekten ist Folgendes zu beachten:
1. Auf Grund von Fachdaten wird ein Domain-Modell mit Hilfe von UML entwickelt. Wichtig
im DM ist, dass die Klassen „persistent“ als persistent gekennzeichnet werden, wobei
alle anderen Klassen als „transient“. TLGen generiert ein SQL Skript (und die
dazugehörige Datenbank) nur für die Persistenten Klassen als Tabellen (siehe Kap.
3.9). Dieses Domain-Model wird als XMI Datei gespeichert und ist für TLGen wichtige
Grundlage für die Generierung (siehe Kap. 5.1).
2. Entwicklung von Konfigurationsdateien (siehe Kap. 4). Kann die Konfigurationsdateien
mit den notwendigen Anpassungen, projektabhängig, verwenden. In Demo Beispiel sind
Konfiguratiosdateien für die Verwendung einer „Oracle“- und einer „MySql“-Datenbank:
a. für
„Oracle“,
„config_tlgen_demo.xml-Oracle”
und
“config_tlgen_demo_default.xml-Oracle“
b. für
„MySql“,
„config_tlgen_demo.xml-MySql“
und
„config_tlgen_demo_default.xml-MySql“
3. Entwicklung eines „ant“ „build“ Skripts. Auch in diesem Fall kann das „ant“ Skript von
dem Beispiel als Grundlage verwendet und angepasst werden.
4. Generierung von Java Code.
5. Kodierung von Fachlogik in den von TLGen „callback“ generierten Klassen.
6. Projekt-Teste mit Hilfe von generierten JUnit Test Klassen.
7. Wiederholung der Punkte 1 bis 6, um ein optimales Projekt zu schaffen.
Für ein Lagacy Projekt gilt die gleiche zuvor genannte Vorgehensweise ausser Punkt 1 und die
Konfigurationsdateien müssen mehrere Informationen beinhalten (Beispiel vom Kap. 5.2).
TLGen-Verwendung in einem neuen IT Projekt, „Demo“ Beispiel
5.1
Das „Demo“ Beispiel basiert auf das Domain Modell, dargestelt in Abbildung 4.
Für die Generierung sind folgende Dateien notwendig:



TLGen
config. config_tlgen_demo_default.xml und config. config_tlgen_demo.xml, sind die
Konfigurationsdateien
build.build.xml, build.build_generator und build.properties, sind die “ant” Dateien
doc.model.DomainModel01.xml, ist die UML Domain Modell-Datei. In unserem Beispiel
verwenden wir für die Erzeugung dieser Datei den „EnterpriseArchitekt“ Tool von der
Firma „Sparks Systems“.
130
StarData Gmb
V 2.8

TLGen und fremde Jars (siehe Kap. 6.1)
Die Generierung wird mit folgendem Befehl im Folder „build“ gestartet.
…\build\ant
In diesem Beispiel werden alle notwendigen Klassen generiert und einige (die Fachlogik im
Beispiel) per Hand angepasst. Folgende Folder beinhalten nur generierte Klassen, die bei jeder
Generierung neu erstellt werden:



source.generated, in diesem Folder werden die Daten-, Json Daten- und MappingKlassen zwischen Daten und Json-Klassen, Session Beans mit eigenen Interfaces,
Entity Beans und Entity Manager-Klassen generiert. All diese generierten Klassen darf
man nicht mit einem Editor ändern und sind komplett funktionsfähig.
source.help, hier befinden sich die JUnit generiertenTest Klassen
source.interceptor, da werden die „Interceptor“ Klassen generiert, welche die runing Zeit
messen
Im Folder „common“ sind einige„super“ Klassen, notwendig für EJB 3. Diese Klassen sind nur
ein Vorschlag für die „Demo“ und können geändert werden, wobei dies nicht notwendig ist, weil
sie in allen IT Projekten gleich sein können.
Folgende Folder beinhalten veränderbare Dateien und jede kann eine eigene Fachlogik bauen:




source.criteria, beinhaltet die Dateien für den Kriteria Java Code. Im „Demo“ Beispiel
sind nur die Klassen von „eu.stardata.demo.server.criteria.user.UserCriteria“ mit
funktionalem Code.
source.test, hier befinden sich die per Hand angepassten Klassen der generierten JUnit
Test-Klassen aus dem Folder „source.help“
source.rest, da ist ein Beispiel für die Verwendung von „REST“ call’s, zwei Dateien,
„eu.stardata.demo.server.rest.CallBackRest“ und
„eu.stardata.demo.server.rest.CallBackRestBean“
sourde.soap, hier ein Beispiel für die Verwendung von „Web Service“ Technik
Das „Demo“ Beispiel benötigt noch folgende Folder:




result, beinhaltet die von „ant“ generierte „jars“, „wars“ „XML“ und „ears“ Dateien.
resource, hier sind einige Hilfsdateien.
lib, hier die für die Generierung notwendigen „jar“ Dateien
log, hier werden die „log“ Dateien gespeichert.
Folgendes ist für die Verwendung des„Demo“ Beispiels notwendig
1.
2.
3.
4.
TLGen
Entpackung der „demo.zip“ Datei
Starten des Projekts „Project-Demo“ in ein Elipse Tool
Eventuelle Änderungen von „paths“ in der Datei „build.properties“
Datenbank-Vorbereitung:
o Einrichten eines Users mit dessen Zugriffsrechte
131
StarData Gmb
V 2.8
Erstellung eines oder besser zweier „Tablespaces“ und Eintragung der Namen in
die Konfigurationsdatei beim Tag <Generator>, Attributen „indexTablespace“ und
„dataTablespace“
o Anpassen des Attributs „databaseConnect“ an den richtigen Werten in der
Konfigurationsdatei
Starten einer „Oracle“ v-11 Datenbank oder einer anderer Datenbank (falls eine andere
Datenbank verwendet werden soll) im Tag <Generator>, Attribut „databaseConect“ den
Inhalt, z.B. für MySql Datenbank ist dort einzutragen:
„jdbc:mysql://localhost:3306/demo?characterEncoding=UTF8&characterSetResults=UTF8&autoReconnect=true&zeroDateTimeBehavior=convertToNull“)
Starten des „ant“ build. Dieser generiert die „SQL“ Skripts, Java Klasse, erstellt eine
neue Datenbank (so lange im Attribut <Generator… makeDatenbase=true..> ist),
generiert eine „ear“ Datei mit dessen Dateien und kopiert diese auf den Application
Server
Starten des Application Servers „JBoss-7.1.1“
Von Eclipse starten der Test call’s für die Abspeicherung und das Datenlesen in der
Datenbank in folgender Reihenfolge:
o Vom „useRole“ die Test Klasse „eu.stardata.test.user.RoleWriteRead“ starten
und in der Datenbank die User Rollen abspeichern. In Eclipse bei „console“
sollten folgende Ausgaben erscheinen:
o
5.
6.
7.
8.
New primary key is = 4
RoleName :SuperAdmin
Ejb3Optlock :0
UserRoleID :1
Description :Description from role :SuperAdmin
ModifyDate :2013-02-13 11:36:30.002
RoleName :Admin
Ejb3Optlock :0
UserRoleID :2
Description :Description from role :Admin
ModifyDate :2013-02-13 11:36:30.425
RoleName :System
Ejb3Optlock :0
UserRoleID :3
Description :Description from role :System
ModifyDate :2013-02-13 11:36:30.446
RoleName :User
Ejb3Optlock :0
UserRoleID :4
Description :Description from role :User
ModifyDate :2013-02-13 11:36:30.46
o
und von „user“ test Klasse „eu.stardata.test.user.UserWriteRead“:
New primary key is = 1
UserID
:1
Ejb3Optlock :0
Email
:[email protected]
PassWord :789
FirstName :Georg
UserName :yyy-01
LastName :Fisher
TLGen
132
StarData Gmb
V 2.8
ModifyDate :2013-02-13 11:45:06.001
RoleName :System
Ejb3Optlock :0
UserRoleID :3
Description :Description from role :System
ModifyDate :2013-02-13 11:36:30.446
o
Wenn drei oder mehrere „users“ gespeichert sind, kann die „REST“ Test Klasse
„eu.stardata.test.rest.TestRestUser“ aufgerufen werden. Auf den Application
Server erscheint folgende Anzeige:
11:56:04,669 INFO
11:56:04,733 INFO
11:56:04,735 INFO
11:56:04,791 INFO
11:56:04,793 INFO
11:56:04,837 INFO
11:56:04,839 INFO
11:56:04,878 INFO
[stdout] (http--127.0.0.1-8080-1) ------- createUser -------[stdout] (http--127.0.0.1-8080-1) ------- fetchUser -------[stdout] (http--127.0.0.1-8080-1) Name :yyy-01
[stdout] (http--127.0.0.1-8080-1) ------- countUsers -------[stdout] (http--127.0.0.1-8080-1) Name :xxx-01
[stdout] (http--127.0.0.1-8080-1) ------- deleteUser -------[stdout] (http--127.0.0.1-8080-1) userId :4
[stdout] (http--127.0.0.1-8080-1) ------- updateUser --------
und auf der Eclispe „console“ folgendes (Die Daten für Users können unterschiedlich
sein, abhängig vom Abgespeicherten):
----------- testcreateUser() ----------strResponse
:{"ejb3Optlock":0,"email":"[email protected]","passWord":"xyz","firstName":"Cris","userID":4,"userName":"us
er03","lastName":"Smith","modifyDate":null,"product":null,"userRole":[{"roleName":null,"ejb3Optlock":0,"userRoleID":2
,"description":null,"modifyDate":null,"user":null}]}
Ejb3Optlock :0
Email
:[email protected]
PassWord :xyz
FirstName :Cris
UserID
:4
UserName :user03
LastName :Smith
ModifyDate :null
RoleName :null
Ejb3Optlock :0
UserRoleID :2
Description :null
ModifyDate :null
----------- testfetchUser() ----------Response
:{"requestParameters":{},"totalResultSize":0,"result":[{"ejb3Optlock":0,"email":"[email protected]","passWo
rd":"789","firstName":"Georg","userID":1,"userName":"yyy01","lastName":"Fisher","modifyDate":null,"product":null,"userRole":[{"roleName":"System","ejb3Optlock":0,"userRoleI
D":3,"description":"Description from role
:System","modifyDate":1360751790446,"user":null}]},{"ejb3Optlock":0,"email":"[email protected]","pass
Word":"123","firstName":"John","userID":2,"userName":"yyy01","lastName":"Johnson","modifyDate":null,"product":null,"userRole":[{"roleName":"System","ejb3Optlock":0,"userRo
leID":3,"description":"Description from role :System","modifyDate":1360751790446,"user":null}]}]}
----------- testcountUsers() ----------strResponse :1
----------- testdeleteUser() ----------strResponse :OK
----------- testupdateUser() ----------strResponse :{"ejb3Optlock":0,"email":"[email protected]","passWord":"xyzabc","firstName":"John","userID":3,"userName":"userupdate","lastName":"Johnson","modifyDate":1360756564866,"product":null,"userRole":[{"roleName":null,"ejb3Optlock
":0,"userRoleID":2,"description":null,"modifyDate":null,"user":null}]}
o
TLGen
Es kann auch die Test-Klasse „eu.stardata.test.soap.TestSoapUser“ für Web
Service aufgerufen werden. Auf den Application Server sollte folgende Anzeige
erscheinen:
133
StarData Gmb
V 2.8
13:29:17,775 INFO [stdout] (http--127.0.0.1-8080-2) ------- retrieveUser -------13:29:17,777 INFO [stdout] (http--127.0.0.1-8080-2) Name :yyy-01
13:29:18,233 INFO [stdout] (http--127.0.0.1-8080-2) ------- updateUser --------
Und auf der Eclispe „console“ folgendes:
------------ Response Retrive User ----------------Ejb3Optlock :1
Email
:[email protected]
PassWord :xyz$abc
FirstName :Stefan
UserID
:1
UserName :yyy-01
LastName :Stefanson
ModifyDate :Wed Feb 13 13:23:02 CET 2013
RoleName :Admin
Ejb3Optlock :0
UserRoleID :2
Description :Description from role :Admin
ModifyDate :Wed Feb 13 12:38:04 CET 2013
Ejb3Optlock :0
Email
:[email protected]
PassWord :789
FirstName :John
UserID
:3
UserName :yyy-01
LastName :Johnson
ModifyDate :Wed Feb 13 12:42:11 CET 2013
RoleName :SuperAdmin
Ejb3Optlock :0
UserRoleID :1
Description :Description from role :SuperAdmin
ModifyDate :Wed Feb 13 12:38:03 CET 2013
----------- Send Update User ---------------------- Response Update User ----------------Ejb3Optlock :0
Email
:[email protected]
PassWord :xyz$abc
FirstName :Stefan
UserID
:2
UserName :test
LastName :Stefanson
ModifyDate :Wed Feb 13 13:29:18 CET 2013
RoleName :null
Ejb3Optlock :0
UserRoleID :2
Description :null
ModifyDate :null
Bei Verwendung von ein JBoss v.7.1.1 sollten folgende Eintragungen in der Datei
„standalone.xml“, abhängig von der verwendeten Datenbank, erfolgen:

für „Oracle“ Datenbank:
………………….
<datasource jta="true" jndi-name="java:/vmsPool" pool-name="vmsPool" enabled="true" use-java-context="true"
use-ccm="true">
<connection-url>jdbc:oracle:thin:@localhost:1521:SDW6ORCL</connection-url>
<driver>oracle</driver>
<security>
<user-name>vms</user-name>
<password>vms</password>
</security>
</datasource>
TLGen
134
StarData Gmb
V 2.8
………………………….
<drivers>
<driver name="oracle" module="oracle.jdbc">
<driver-class>oracle.jdbc.OracleDriver</driver-class>
</driver>
…………………………

und für “MySql”:
………………………..
<datasource jta="true" jndi-name="java:/demoPool" pool-name="demoPool" enabled="true" use-java-context="true"
use-ccm="true">
<connection-url>jdbc:mysql://localhost:3306/demo?characterEncoding=UTF8&characterSetResults=UTF8&autoReconnect=true&zeroDateTimeBehavior=convertToNull</connection-url>
<driver>mysql</driver>
<transaction-isolation>TRANSACTION_REPEATABLE_READ</transaction-isolation>
<pool>
<min-pool-size>10</min-pool-size>
<max-pool-size>250</max-pool-size>
<prefill>true</prefill>
<use-strict-min>false</use-strict-min>
<flush-strategy>FailingConnectionOnly</flush-strategy>
</pool>
<security>
<user-name>demo</user-name>
<password>demo</password>
</security>
<validation>
<check-valid-connection-sql>SELECT 1</check-valid-connection-sql>
</validation>
<timeout>
<blocking-timeout-millis>30000</blocking-timeout-millis>
<idle-timeout-minutes>5</idle-timeout-minutes>
</timeout>
<statement>
<prepared-statement-cache-size>200</prepared-statement-cache-size>
<share-prepared-statements>true</share-prepared-statements>
</statement>
</datasource>
…………………………
<drivers>
<driver name="oracle" module="oracle.jdbc">
<driver-class>oracle.jdbc.OracleDriver</driver-class>
</driver>
……………………………
Bemerkung:
Wir empfehlen eine Übung mit dem Einbau eigener Klassen, mit Verwendung der restlich generierten Klassen „product“, „production“ und dann die Erweiterung des Domain-Modells mit
eigenen Klassen durchzuführen.
5.2 Verwendung von TLGen in ein Legacy IT Projekt, „Legacy“ - Beispiel
Das „Legacy“-Beispiel basiert auf das Daten-Modell aus Abbildung 5.
Dieses Beispiel kann von www.tlgen.com heruntergeladen werden.
Die Beschreibung für dieses TLGen Beispiel befindet sich in der „Readme.txt“ Datei.
TLGen
135
StarData Gmb
V 2.8
6 TLGen Installation
TLGen wird als eine JAR Datei geliefert. Zu deren Verwendung gibt es keine Besonderheiten.
In source/common sind ein paar Klassen (Super-, Exception- oder Client Remote-Service-Klassen), die TLGen als Standard Klassen in der Generierung verwendet. Diese können erweitert
oder geändert werden und sind optional.
Der TLGen Generierungsvorgang kann über Apache ANT verwendet werden, da TLGen einen
eigenen Tag „tlgen“ besitzt (siehe Listing 92)
<target name="generator" depends="generator-init" description="--> generate helper file">
<tlgen configFile = "${output}/config/config_tlgen_demo.xml"
configStandardFile = "${output}/config/config_tlgen_demo_default.xml"
databaseConnect = "jdbc:oracle:thin:@localhost:1521:ORCL"
databaseDriver = "oracle.jdbc.driver.OracleDriver"
userPwd = "Demo/demo"
database = "Oracle"
logFile = "${output}/log/generator_demo.log"
logTest = "${output}/log/test_demo.log"
logEntity = "${output}/log/entity_demo.log"
pathToGenerate = "${output}/source/generated"
debugValue = "debug"
classpathref = "tlgen.class.path" >
<fileset dir="${src.server}">
<include name="**/${subsystem.dir}/**/*SessionBean.java"/>
</fileset>
</tlgen>
</target>
Listing 92: Verwendung von <tlgen> Tag
Der Tag „generator“ benötigt folgende Attribute:

configFile ist die Konfigurationsdatei mit deren Adresse

configStandardFile ist die Standard Konfigurationsdatei mit deren Adresse

databaseConnec, ist der Connect String für eine Datenbank

databaseDriver ist der Datenbank-Treiber

userPwd ist der User und dessen Passwort für die Access zur Datenbank

database ist die Datenbank (z. B „Oracle“)

logFile Datei-Name für den Platz, wo alle Informationen über die Generierung
geschrieben werden sollten

logTest für die generierten Test-Klassen

logEntity für die generierten Entity-Klassen,

logManager für die generierten Manager-Klassen

logSession, für die generierten Session Bean-Klassen

pathToGenerate ist die Adresse, wo der generierte Code gespeichert werden sollte
TLGen
136
StarData Gmb
V 2.8

debugValue ist „debug“, hier werden die Debug Prints auf der Konsole geschrieben

classpathref ist die Adresse, wo sich die benötigten JARS befinden (siehe Liste von
6.1)
Eine komplette ANT Datei ist im TLGen Example Paket ersichtlich.
6.1 Verwendete Tools und Externe Programme
Liste von verwendeten TLGen JAR’s für die Generierung (siehe auch das Code Beispiel):

„Tlgen28.jar“, beinhaltet den TLGen Generator

„base.jar“, beinhaltet einige Helper methods

„common.jar“, „super“ Klassen, die von jeden Benutzer gändert werden (sind geliefert
auch in Java Code) können
und fremde JAR’s:


für den Application-Server „JBoss v.7“:
o „jboss-annotations-api_1.1_spec-1.0.0.Final.jar“
o “jboss-client.jar”
o “cdi-api-1.0-SP4.jar”
o “hibernate-core-4.0.1.Final.jar”,
o “hibernate-jpa-2.0-api-1.0.1.Final.jar”
o “javax.inject-1.jar”
o “jboss-ejb-api_3.1_spec-1.0.1.Final.jar”
o “jboss-interceptors-api_1.1_spec-1.0.0.Final.jar”
o “jboss-jaxrs-api_1.1_spec-1.0.0.Final.jar”
Für Verwendung von „Oracle“ Datenbank (von der Firma Oracle) Version 11:
o


„ojdbc6_g.jar“ oder „ojdbc6.jar“
Für Vervendung von „MySQL“ Datenbank (von der Firma Oracle:)
o „mysql-connector-java-5.1.6-bin.jar“
Für REST call’s:
o
„async-http-servlet-3.0-2.3.2.Final.jar“
o
„async-http-servlet-3.0-2.3.2.Final-jandex.jar“
o
„gson-2.2.2.jar“
o
„jackson-core-asl-1.9.2.jar“
o
„jackson-jaxrs-1.9.2.jar“
o
„jackson-mapper-asl-1.9.2.jar“
o
„resteasy-jaxrs-2.3.2.Final.jar“
o
„resteasy-jaxrs-2.3.2.Final-jandex.jar“

„ant.jar“ für Generierung mit Hilfe von „ant“

„junit-4.5.jar“ für Test Klassen
TLGen
137
StarData Gmb
V 2.8
Bemerkung:
Andere jars, z.B. Datenbank-Verbindung oder Application Server Client/Server sind von der
Datenbank bzw vom Application Server, der verwendet wird, abhängig.
6.2 Verwendung von „ant“ für die Generierung von Java Code
Für die Verwendung von „ant“ für die Code Generierung besitzt TLGen einen eigenen Taget
„generator“ (Sihe Kap. 5.1, und 5.2). Der Target „generator“ hat folgende Attribute (siehe Table
12: Attribute- für den „ant“ <target> „genertor“):
Table 12: Attribute- für den „ant“ <target> „genertor“
Attribut
Value
configFile
Mandatory
Kommentar
yes
Konfigurationsdatei-Name
encoding
„Cp1252“
no
„Cp1252“ ist Default-Wert für die Generierung von SQL
Skripts
logFile
Datei Name
no
Generator main Log-Datei
logTest
Datei Name
no
Log-Datei für die Generierung von Test-Klassen
logEntity
Datei Name
no
Log-Datei für die Generierung von Entity BeansKlassen
debugValue
debug
no
TLGen läuft in Debug Modus
classpathref
classpath
no
relativePath
true
no
Default ist „true“ und verwendet für die Generierung
relative Paths, bei „false“ werden die absolute Paths
verwendet
logManager
Datei Name
no
Log-Datei für die Generierung von Manager Entity
Beans-Klassen
logSession
Datei Name
no
Log-Datei für die Generierung von Session BeansKlassen
logClassIf
Datei Name
no
Log-Datei für die Generierung von Daten- und JSonKlassen
6.3 Verwendung von „Maven“ für die Generierung von Java Code
Für die Verwendung von „Maven“ innerhalb eines Java Projekts ist in der Code Generierung mit
TLGen folgende Eintragung notwendig „pom.xms“ (siehe Listing 93). Dieses Beispiel basiert auf
dieVerwendung von TLGen „ant“ Tergent <generator> (siehe auch 6.2).
TLGen
138
StarData Gmb
V 2.8
<build>
<resources>
<resource>
<directory>src/main/tlgen/config</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>filter-binding</id>
<phase>process-resources</phase>
<configuration>
<failOnError>true</failOnError>
<target>
<taskdef name="tlgen" classname="eu.stardata.tlgen.ant.TlgAntTask"
classpathref="maven.plugin.classpath" />
<tlgen configFile="${project.build.directory}/classes/config_tlgen_vms.xml"
configStandardFile="${project.build.directory}/classes/config_tlgen_vms_default.xml"
databaseConnect="${testdb.url}" databaseDriver="oracle.jdbc.OracleDriver"
userPwd="${testdb.user}/${testdb.password}" database=""
logFile="${project.build.directory}/generator_vms.log" logTest="${project.build.directory}/test_vms.log"
logEntity="${project.build.directory}/entity_vms.log"
pathToGenerate="${project.build.directory}/generated-sources/tlgen">
</tlgen>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
……………………………………
Listing 93: Maven „pon.xml“ Datei
Folgende Eintragungen sind in “pom.xml” durchzuführen:



<directory>src/main/config<directory>, Bei dieser Adresse sind beide
Konfigurationsdateien vorhanden
<taskdef name="tlgen" classname="eu.stardata.tlgen.ant.TlgAntTask", TLGen
Generator Aufruf
Definierung von Variablen:
o ${project.build.directory}, Build Folder Adresse
o "${testdb.url}", für Database Connect
o "${testdb.user}/${testdb.password}", Database-Zugriffsrechte
Alle drei „jar“ Dateien, “tlgen.jar”, „base.jar“ und „common.jar“, welcheTLGen Generator
benötigt, sollten mit Hilfe eines Repository imProjekt eingebunden werden.
TLGen
139
StarData Gmb
V 2.8
7 Beispiele von generiertem Code
Es folgen Beispiele für den generierten Code aus dem „Demo“-Beispiel.
7.1 Standard Konfigurationsdatei
<?xml version="1.0" encoding="UTF-8"?>
<!-- ======================================================================= -->
<!-config standard file for Project-Demo
-->
<!-- ********************************************************************* -->
<!-Titus Livius Rosu, Titus Rosu, StarData GmbH
-->
<!-2013/01/18
-->
<!-- ======================================================================= -->
<Standard name="Standard-Demo"
company="StarData GmbH"
path="eu.stardata.%project%"
commentary="**** do not change with a file editor *****"
>
<Project testRelation="false,true,false,false"/>
<!--Locator name="eu.stardata.server.common.ejb.ServiceLocator"
instance="getInstance"
local="getLocalReference"
remote="getRemoteReference">
</Locator-->
<Class path="eu.stardata.demo.business"
name="eu.stardata.%project%.business.%package%.%classname%Data|eu.stardata.%project%.business.%package%.%classname%DataIf"
classType="Class">
<!--pathEnum="eu.stardata.%project%.business.enums.%package%.%classname%"
pathType="eu.stardata.%project%.business.types.%package%.%classname%"-->
<Implements name="java.io.Serializable"/>
<!--Extends name="com.tlgen.common.data.BaseData"/-->
<!--Extends name="com.tlgen.common.data.BaseDataIf" type="interface"/-->
</Class>
<Entity path="eu.stardata.%project%.server.persistence"
name="eu.stardata.%project%.server.persistence.%package%.entity.%classname%Entity" seqstrategy="SEQUENCE"
classType="Entity">
<Implements name="java.io.Serializable" type="interface"/>
<!--Extends name="com.tlgen.common.ejb.entity.BaseEntityBean"/-->
<!--Annotation name="javax.persistence.Entity"/>
<Annotation name="javax.persistence.Table"/>
<Annotation name="javax.persistence.SequenceGenerator"/-->
<Annotation name="org.hibernate.annotations.GenericGenerator" replacement="javax.persistence.SequenceGenerator"/>
</Entity>
<Mapping name="eu.stardata.%project%.business.%package%.%classname%Map" classType="Mapping">
</Mapping>
<Criteria name="eu.stardata.%project%.server.criteria.%package%.%classname%Criteria" classType="Criteria">
</Criteria>
<JSon name="eu.stardata.%project%.business.%package%.%classname%JSon" classType="JSon">
</JSon>
<Manager name="eu.stardata.%project%.server.persistence.%package%.manager.%classname%Manager" classType="Manager"
transactiontype="JTA"
container="false"
exception="com.tlgen.common.exception.PersistenceException">
<!--Extends name="com.tlgen.common.ejb.manager.BaseManager"/-->
<Implements name="eu.stardata.%project%.server.persistence.%package%.managerif.%classname%ManagerIf"/>
<!--Annotation name="javax.ejb.Stateless"/>
<Annotation name="javax.ejb.Local"/-->
<!--Variable name="JNDI_NAME" vartype="string" content="%interfacemanager%" fieldtype="1" abstract="true"/>
<Variable name="EAR_NAME" vartype="string" content="%earname%" fieldtype="1" abstract="true"/>
<Variable name="m_manager" vartype="javax.persistence.EntityManager">
<Annotation name="javax.persistence.PersistenceContext">
<Parameter name="properties" type="Text-Prop"/>
<Parameter name="unitName" type="%clientdata%.MANAGER_NAME"/>
</Annotation>
</Variable-->
<!--Method name="getManager" return="%interfacemanager%" methodtype="4">
TLGen
140
StarData Gmb
V 2.8
<Exception name="com.tlgen.common.exception.PersistenceException"/>
</Method>
<Method name="create" return="%interfacedata%" methodtype="4">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter type="%interfacedata%" />
</Method>
<Method name="update" methodtype="4" return="void">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter type="%interfacedata%" />
</Method>
<Method name="remove" methodtype="4" return="void">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter type="%interfacedata%" />
</Method>
<Method name="flush" methodtype="4" return="void">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
</Method>
<Method name="close" methodtype="4" return="void">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
</Method>
<Method name="clear" methodtype="4" return="void">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
</Method>
<Method name="findByPrimaryKey" return="%interfacedata%" methodtype="5">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter type="%interfacedata%" />
</Method>
<Method name="findAll" return="%interfacedata%[]" methodtype="5">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Sql name="SQL_FIND_ALL" sql="select o from %classname%Entity o" />
</Method>
<Method name="getEntityByPrimaryKey" return="%classentity%" methodtype="5">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter type="%interfacedata%" />
</Method-->
</Manager>
<Session name="eu.stardata.%project%.server.persistence.%package%.%classname%SessionBean" classType="Session"
managername="manager%classname%"
transactiontype="JTA">
<!--Extends name="com.tlgen.common.ejb.session.BaseSessionBean"/-->
<!--Annotation name="javax.annotation.security.RolesAllowed">
<Parameter name="ADMIN"/>
</Annotation-->
<!--Annotation name="javax.ejb.Stateless"/>
<Annotation name="javax.ejb.Remote"/-->
<Client name="eu.stardata.%project%.client.bci.%package%.%classname%Bci" type="public"
exception = "com.tlgen.common.exception.PersistenceException">
<!--Extends name="eu.stardata.server.common.bci.BciFactory"/-->
<!--Annotation name="javax.ejb.Remote"/-->
<!--Variable type="public final static" vartype="string" name="MANAGER_NAME" content="%sessionmanagername%"
fieldtype="1" abstract="true"/>
<Variable type="public final static" vartype="string" name="EAR_NAME" content="%earname%" fieldtype="1"
abstract="true"/>
<Variable type="public final static" vartype="string" name="JNDI_NAME" content="%interfacemanager%" fieldtype="1"
abstract="true"/-->
</Client>
<Interceptor name="eu.stardata.%project%.server.persistence.%package%.TimeCore" path ="C:/Projects/ProjectDemo/source/generated" merge="1">
<Method name="timeTrace" return="java.lang.Object" finally="C:/Projects/Project-Demo/resources/FinallyTime.xml">
<!--Annotation name="javax.interceptor.AroundInvoke"/-->
<!--Parameter type="javax.interceptor.InvocationContext" name="invocation"/-->
<!--Exception name="com.tlgen.common.exception.PersistenceException"/-->
</Method>
</Interceptor>
<Xml-persistence type="persistence">
<Property name="show_sql" type="true" />
</Xml-persistence>
</Session>
<Message name="eu.stardata.%project%.server.persistence.%package%.message" classType="Message" >
</Message>
<UmlControl name="DomainModel"
lenString="255"
versionDb="EJB3_OPTLOCK"
versionDbType="NUMBER(12,0)"
enumType="VARCHAR2(32)"
primKeyType="long"
endPrimKey="_ID"
TLGen
141
StarData Gmb
V 2.8
endSequence="_1SQ"
sequenceType="1"
sequenceCache="10"
sequenceInit="1"
sequenceIncrement="1"
dataTablespace="ADMDATA"
indexTablespace="ADMINDEX">
<Column name="EJB3_OPTLOCK" type="long" dbType="NUMBER" dataLen="16" locking="true"/>
<Column name="MODIFY_DATE" type="Date" dbType="TIMESTAMP" dataLen="6" locking="false" nullable="true"
defaultValue="SYSDATE"/>
<!--Column name="DB_VERSION" type="long" dbType="NUMBER" dataLen="16" locking="true"/-->
<!--Column name="ID" type="String" dbType="VARCHAR2" dataLen="255" unique="true"/-->
<!--ColType name="char" type="CHAR"/>
<ColType name="Date" type="TIMESTAMP(6)"/>
<ColType name="String" type="VARCHAR2"/>
<ColType name="DbType" type="NUMBER(10,0)"/>
<ColType name="byte[]" type="BLOB"/>
<ColType name="int" type="NUMBER(12,0)"/>
<ColType name="Integer" type="NUMBER(12,0)"/>
<ColType name="long" type="NUMBER(24,0)"/>
<ColType name="Long" type="NUMBER(24,0)"/>
<ColType name="double" type="NUMBER(28,4)"/>
<ColType name="Double" type="NUMBER(28,4)"/>
<ColType name="float" type="NUMBER(12,2)"/>
<ColType name="Float" type="NUMBER(12,2)"/>
<ColType name="short" type="SMALLINT"/>
<ColType name="Short" type="SMALLINT"/>
<ColType name="boolean" type="NUMBER(1,0)"/>
<ColType name="Boolean" type="NUMBER(1,0)"/-->
<NameChange name="Order" type="OrderTable"/>
<NameChange name="User" type="UserTable"/>
<!-##################################################
-->
<!-Settings for Relation
-->
<!-##################################################
-->
<Relation type="recursiv" name="recursiv" value="true"/>
<!-if no linkname is assigned
-->
<!--Relation type="recursiv" name="recursivName" value="Parent"/>
<Relation type="sameRelationDirection" name="sameRelationDirection" value="true"/-->
<!-if no linkname is assigned
-->
<!--Relation type="sameRelationDirection" name="sameRelationDirectionName" value="Parent"/>
<Relation type="backRelationDirection" name="backRelationDirection" value="true"/>
<Relation type="backRelationDirection" name="backRelationDirectionAdd" value="true"/-->
<!-if no linkname is assigned
-->
<!--Relation type="backRelationDirection" name="backRelationDirectionName" value=""/-->
<!-- #### -->
<!-- ALGO -->
<!-- #### -->
<!-- Relation: "<#>=====" | Direction: "Source -> Destination" | Navigation: "<= to Source" -->
<!--Association type="Composition" name="Composition:Source -> Destination|toSource" position="Source" navigable="Source"
optional="false" nullable ="false" /-->
<!-- Relation: "<#>====>" | Direction: "Source -> Destination" | Navigation: "=> to Destination" -->
<!--Association type="Composition" name="Composition:Source -> Destination|toTarget" position="Source" navigable="Target"
optional="false" nullable ="true" insertable="true" updateable="true" cascade="PERSIST,MERGE,REMOVE" /-->
>
<!-- Relation: "< >=====" | Direction: "Source -> Destination" | Navigation: "<= to Source" -->
<!--Association type="Shared" name="Shared:Source -> Destination|toSource" position="Source" navigable="Source" nullable ="true" /--
<!-- Relation: "< >====>" | Direction: "Source -> Destination" | Navigation: "=> to Destination" -->
<!--Association type="Shared" name="Shared:Source -> Destination|toTarget" position="Source" navigable="Target" nullable ="true"
insertable="true" updateable="true" cascade="PERSIST,MERGE" /-->
<!-- Relation: "<#>====="" | Direction: "Destination -> Source" | Navigation: "<= to Destination" -->
<!--Association type="Composition" name="Composition:Destination -> Source|toTarget" position="Target" navigable="Target"
optional="false" nullable ="false" /-->
<!-- Relation: "<#>====>" | Direction: "Destination -> Source" | Navigation: "=> to Source" -->
<!--Association type="Composition" name="Composition:Destination -> Source|toSource" position="Target" navigable="Source"
optional="false" nullable ="true" insertable="true" updateable="true" cascade="PERSIST,MERGE,REMOVE" /-->
<!-- Relation: "< >=====" | Direction: "Destination -> Source" | Navigation: "<= to Destination" -->
<!--Association type="Shared" name="Shared:Destination -> Source|toTarget" position="Target" navigable="Target" nullable ="true" /-->
<!-- Relation: "< >====>" | Direction: "Destination -> Source" | Navigation: "=> to Source" -->
<!--Association type="Shared" name="Shared:Destination -> Source|toSource" position="Target" navigable="Source" nullable ="true"
insertable="true" updateable="true"/-->
TLGen
142
StarData Gmb
V 2.8
<!-- Changes "Destination -> Source" from ManyToOne in OneToMany and OneToMany in ManyToOne -->
<!-If: "sourceNavigability == UML_CONNECTION_END_NAVIGABLE_TYPE.navigable OR direction ==
UML_CONNECTION_END_TYPE.DestinationToSource" -->
<!--Relation type="ChangeDirection" name="0" value="true" /-->
<!-If: "(targetAssociation == UML_ASSSOCIATION_TYPE.composition OR targetAssociation ==
UML_ASSSOCIATION_TYPE.shared) AND (sourceNavigability == UML_CONNECTION_END_NAVIGABLE_TYPE.navigable && direction ==
UML_CONNECTION_END_TYPE.DestinationToSource)" -->
<!--Relation type="ChangeDirection" name="1" value="true" /-->
<!-- Overwrites the results computed from the association tags above!!! -->
<!--Association type="OneToOne" name="OneToOne" overwrite="true" direction="true" optional="true" insertable="true"
updateable="true" />
<Association type="OneToMany" name="OneToMany" overwrite="true" direction="true"
insertable="true" updateable="true" />
<Association type="ManyToOne" name="ManyToOne" overwrite="true" direction="true" optional="true" insertable="true"
updateable="true" />
<Association type="ManyToMany" name="ManyToMany" overwrite="true" direction="true" optional="true" insertable="true"
updateable="true" cascade="PERSIST,MERGE,REMOVE" /-->
<!-##################################################
<!-Property Values for the Relations - DO NOT CHANGE!!!
-->
<!-##################################################
<!--RelationType name="mStandard" type="RELATION_TYPE" return="One" value="1"/>
<RelationType name="mNull" type="RELATION_TYPE" return="One" value="null"/>
<RelationType name="m0" type="RELATION_TYPE" return="One" value="0"/>
<RelationType name="m1" type="RELATION_TYPE" return="One" value="1"/>
<RelationType name="m0_1" type="RELATION_TYPE" return="One" value="0..1"/>
<RelationType name="m0_n" type="RELATION_TYPE" return="Many" value="0..n"/>
<RelationType name="m0_infinite" type="RELATION_TYPE" return="Many" value="0..*"/>
<RelationType name="m0_infinite" type="RELATION_TYPE" return="Many" value="*"/>
<RelationType name="m1_n" type="RELATION_TYPE" return="Many" value="1..n"/>
<RelationType name="m1_infinite" type="RELATION_TYPE" return="Many" value="1..*"/>
<RelationType name="mm_n" type="RELATION_TYPE" return="Many" value="m..n"/>
-->
-->
<AggregationType name="None" type="UML_ASSSOCIATION_TYPE" return="association" value="none"/>
<AggregationType name="Shared" type="UML_ASSSOCIATION_TYPE" return="shared" value="shared"/>
<AggregationType name="Composition" type="UML_ASSSOCIATION_TYPE" return="composition" value="composite"/>
Destination"/>
Source"/>
<DirectionType name="Unspecified" type="UML_CONNECTION_END_TYPE" return="unspecified" value="Unspecified"/>
<DirectionType name="SourceToDest" type="UML_CONNECTION_END_TYPE" return="sourceToDestination" value="Source ->
<DirectionType name="DestToSource" type="UML_CONNECTION_END_TYPE" return="DestinationToSource" value="Destination ->
<DirectionType name="BiDirectional" type="UML_CONNECTION_END_TYPE" return="bidirectional" value="Bi-Directional"/>
<AssociationType name="Association" type="UML_ASSSOCIATION_TYPE" return="association" value="Association"/>
<AssociationType name="Aggregation" type="UML_ASSSOCIATION_TYPE" return="aggregation" value="Aggregation"/>
<AssociationSubType name="Association" type="UML_ASSSOCIATION_TYPE" return="association" value="null"/>
<AssociationSubType name="Strong" type="UML_ASSSOCIATION_TYPE" return="composition" value="Strong"/>
<AssociationSubType name="Weak" type="UML_ASSSOCIATION_TYPE" return="shared" value="Weak"/>
<Navigability name="None" type="UML_CONNECTION_END_NAVIGABLE_TYPE" return="none" value="None"/>
<Navigability name="Navigable" type="UML_CONNECTION_END_NAVIGABLE_TYPE" return="navigable" value="Navigable"/>
<Navigability name="NonNavigable" type="UML_CONNECTION_END_NAVIGABLE_TYPE" return="none" value="Non-Navigable"/>
<Navigability name="Unspecified" type="UML_CONNECTION_END_NAVIGABLE_TYPE" return="unspecified" value="Unspecified"/>
<Compare name="manytomany" type="RELATION_TYPE" return="ManyToMany" value="Many" />
<Compare name="manytomany" type="RELATION_TYPE" return="ManyToMany" value="Many" />
<Compare name="onetomany" type="RELATION_TYPE" return="OneToMany" value="One" />
<Compare name="onetomany" type="RELATION_TYPE" return="OneToMany" value="Many"/>
<Compare name="manytoone" type="RELATION_TYPE" return="ManyToOne" value="Many" />
<Compare name="manytoone" type="RELATION_TYPE" return="ManyToOne" value="One"/>
<Compare name="onetoone" type="RELATION_TYPE" return="OneToOne" value="One"/>
<Compare name="onetoone" type="RELATION_TYPE" return="OneToOne" value="One"/-->
</UmlControl>
</Standard>
TLGen
143
StarData Gmb
V 2.8
7.2 Konfigurationsdatei
<?xml version="1.0" encoding="UTF-8"?>
<!-- ======================================================================= -->
<!-config file for Project-Demo
-->
<!-- ********************************************************************* -->
<!-Titus Livius Rosu, Titus Rosu, StarData GmbH
-->
<!-2013/01/18
-->
<!-- ======================================================================= -->
<!-- (JBoss) datasource = "java:/demoPool";
(Glasfish) datasource = "jdbc/demoPool";
(Weblogic) datasource = "demoPool"
(Websphere)datasource = "jdbc/demoPool"
datasource = "java:comp/env/jdbc/demoPool"
databaseConnect="jdbc:oracle:thin:@localhost:1521:sdw6orcl"
indexTablespace="CCPINDEX"
dataTablespace="CCPDATA"
-->
<Generator name="demo"
inputsource="database"
datasource="java:/demoPool"
appserver="JBoss7"
location="C:/Projects/Project-Demo/project"
standardConfigFile="C:/Projects/Project-Demo/config/config_tlgen_demo_default.xml"
umlFile="C:/Projects/Project-Demo/doc/model/DomainModel01.xml"
databaseConnect="jdbc:oracle:thin:@localhost:1521:sdw6orcl"
database="ORACLE"
userPwd="demo/demo"
type="guml"
mapping="true"
databaseScript="C:/Projects/Project-Demo/doc/db/demo_schema.sql"
makeDatabase="false"
makeJavaCode="true"
makeDatabaseDiff="false"
indexTablespace="COINDEX"
dataTablespace="CODATA"
initProgram="eu.stardata.base.config.InitProgramm"
keyName="eu.stardata.base.config.ConfigKeyNames"
reference="true" >
<!-- Glasfish
-->
<!-- Weblogic
org.omg.CORBA.ORBInitialHost=localhost
org.omg.CORBA.ORBInitialPort=3700
initialcontextfactory="java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory"
java.naming.factory.url.pkgs=com.sun.enterprise.naming
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl
initialcontext = "t3://localhost:7001"
initialcontextfactory="weblogic.jndi.WLInitialContextFactory"
initialcontextpkgprefix=" "
-->
<!-- JBoss
initialcontext = "jnp://localhost:9099"
initialcontext = "jnp://localhost:1099"
initialcontextfactory="org.jnp.interfaces.NamingContextFactory"
initialcontextpkgprefix="org.jboss.naming:org.jnp.interfaces"
JBOSS6
JBOSS7
initialcontext = "jnp://localhost:1099"
initialcontextfactory="org.jboss.iiop.naming.ORBInitialContextFactory"
initialcontextpkgprefix="org.jboss.naming:org.jnp.interfaces"
initialcontext = "remote://localhost:4447"
initialcontextfactory = "org.jboss.naming.remote.client.InitialContextFactory.class.getName"
contextkey = "jboss.naming.client.ejb.context"
contextvalue = "true"
optionskey = "jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT"
optionvalue = "false"
-->
<!-- IBM Websphere
TLGen
144
StarData Gmb
V 2.8
initialcontext = "iiop://localhost:2809"
initialcontextfactory="com.ibm.websphere.naming.WsnInitialContextFactory"
initialcontextpkgprefix=" "
-->
<Project name="Project Demo for DomainModel"
initialcontext = "remote://localhost:4447"
initialcontextfactory = "org.jboss.naming.remote.client.InitialContextFactory.class.getName()"
contextkey = "jboss.naming.client.ejb.context"
contextvalue = "true"
optionskey = "jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT"
optionvalue = "false"
managermethods="Order,ProductPrice,User,UserRole"
type="guml"
methods="public"
sequencegen="SEQ_STORE"
format="0"
import="true"
data="true"
level="true"
testRelation="true,true,true,true"
persistence="false"
persistenceUnit="true"
multiReturnType="0"
earname="demo"
security="demo"
enumsString="true"
createTyp="0"
restPort="8080"
pathTest="C:/Projects/Project-Demo/source/help"
pathCriteria="C:/Projects/Project-Demo/source/criteria"
pathInterceptor="C:/Projects/Project-Demo/source/interceptor"
criteria="true"
mappedByOtM="true"
foreignKeyIndex="true"
jsonData="true"
jsonLocking="true"
>
<!-- ================================================= -->
<!-- Design von user Session
-->
<!-- ================================================= -->
<Design name="user" >
<Commentary name="This is a generate package for 'user'"/>
<!-- init the Manager Classes -->
<Manager>
<Method name="findByName" parameter="java.lang.String" return="%interfacedata%[]" manager="User"
methodtype="6">
<Parameter name="name" type="java.lang.String"/>
<Sql sql="select o from UserEntity o where o.userName = :name" />
</Method>
<Method name="findByLastName" manager="User" mapping="true" methodtype="8">
<Parameter name="name" type="java.lang.String"/>
<Sql sql="SELECT * FROM User WHERE username = ? ORDER BY LastName" />
</Method>
<Method name="countUserTyp9" return="java.util.List<Object>" manager="User" methodtype="9">
<Sql name="countUserTyp9" sql="select count(o) from UserEntity o" />
</Method>
<Method name="demoUserFunction" return="java.util.List<Object>" manager="User" mapping="true"
methodtype="10">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Sql sql="select rawtohex(sys_guid()) from dual" />
</Method>
</Manager>
<Manager criteria="true" merge="1">
<Method name="countUserTyp11" return="java.lang.Long" criteria="true" manager="User" methodtype="11">
<Parameter name="name" type="java.lang.String"/>
</Method>
</Manager>
<!-- init the Session Classes -->
<!--Session>
</Session-->
<!-- init the Test Classes -->
<Test name="eu.stardata.demo.client.test.user.RoleWriteRead" type="public" client="User">
<Extends name="junit.framework.TestCase"/>
<Import name="com.tlgen.common.trace.Trace"/>
<Method name="create" parameter="User" client="User" manager="UserRole" typerwd="0">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
TLGen
145
StarData Gmb
V 2.8
<Parameter type="%interfacedata%" />
</Method>
<Method name="findByPrimaryKey" return="%interfacedata%" client="User" manager="UserRole"
typerwd="1">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter type="%interfacedata%" />
<Parameter name="level" type="int" />
</Method>
</Test>
<Test name="eu.stardata.demo.client.test.user.UserWriteRead" type="public" client="User">
<Extends name="junit.framework.TestCase"/>
<Import name="com.tlgen.common.trace.Trace"/>
<Method name="create" parameter="User" client="User" manager="User" typerwd="0">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter type="%interfacedata%" />
</Method>
<Method name="findByPrimaryKey" return="%interfacedata%" client="User" manager="User" typerwd="1">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter type="%interfacedata%" />
<Parameter name="level" type="int" />
</Method>
<Method name="findByName" return="%interfacedata%[]" client="User" manager="User" typerwd="1">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="name" type="java.lang.String" />
<Parameter name="level" type="int" />
</Method>
</Test>
<Test name="eu.stardata.demo.client.test.user.UserTestMethods" type="public" client="User">
<Extends name="junit.framework.TestCase"/>
<Import name="com.tlgen.common.trace.Trace"/>
<Method name="findByLastName" return="%interfacedata%[]" client="User" manager="User" typerwd="13">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="lastName" type="java.lang.String" />
<Parameter name="level" type="int" />
</Method>
<Method name="countUserTyp9" return="long" client="User" manager="User" typerwd="13">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
</Method>
<Method name="demoUserFunction" return="java.util.List<Object>" client="User" manager="User"
typerwd="13">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
</Method>
<Method name="countUserTyp11" return="java.lang.Long" client="User" manager="User" typerwd="13">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="name" type="java.lang.String"/>
</Method>
</Design>
methodtype="6">
</Test>
<!-- ================================================= -->
<!-- Design von Product Session
-->
<!-- ================================================= -->
<Design name="product" methodreference="false">
<Commentary name="This is a generate package for 'product'"/>
<!-- init the Manager Classes -->
<Manager>
<Method name="findByName" parameter="java.lang.String" return="%interfacedata%[]" manager="Product"
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="name" fullName="name" type="java.lang.String" />
<Sql name="getName" sql="select o from ProductEntity o where o.name = :name" />
manager="Product" methodtype="6">
</Method>
<Method name="findByNameAndOffer" parameter="java.lang.String" return="%interfacedata%[]"
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="name" fullName="name" type="java.lang.String" />
<Parameter name="productOfferingId" fullName="productOfferingId" type="java.lang.String" />
<Sql name="getNameAndOffer" sql="select u from ProductEntity u where u.name = :name and
u.productOfferingId = :productOfferingId" />
</Method>
<Method name="findByMaterialnumber" parameter="java.lang.String" return="%interfacedata%[]"
manager="Product" methodtype="6">
:materialNumber" />
TLGen
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="materialNumber" fullName="materialNumber" type="java.lang.String" />
<Sql name="getOffer" sql="select n from ProductEntity n where n.materialNumber =
</Method>
146
StarData Gmb
V 2.8
<Method name="FindByProductName" manager="Product" mapping="true" methodtype="8">
<Parameter name="name" type="java.lang.String"/>
<Sql sql="SELECT * FROM Product WHERE name = ? ORDER BY Name" />
</Method>
</Manager>
<!-- init the Session Classes -->
<!--Session>
</Session-->
<!-- init the Test Classes -->
<Test name="eu.stardata.demo.client.test.product.ProductWriteRead" type="public" num="3"
fileName="eu.stardata.demo.client.test.product.TestDataForProduct">
<Extends name="junit.framework.TestCase"/>
<Import name="com.tlgen.common.trace.Trace"/>
<Method name="create" client="Product" manager="Product" typerwd="0">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter type="%interfacedata%" manager="Product"/>
</Method>
<Method name="findByPrimaryKey" client="Product" return="%interfacedata%" manager="Product"
typerwd="1">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter type="%interfacedata%" manager="Product"/>
<Parameter name="level" type="int" />
</Method>
<Method name="findByName" client="Product" return="%interfacedata%[]" manager="Product" typerwd="1">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="name" type="java.lang.String" />
<Parameter name="level" type="int" />
</Method>
<Method name="findByNameAndOffer" client="Product" return="%interfacedata%[]" manager="Product"
typerwd="1">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="name" type="java.lang.String" />
<Parameter name="offer" type="java.lang.String" />
<Parameter name="level" type="int" />
</Method>
</Test>
<Test name="eu.stardata.demo.client.test.product.ProductReadAll" type="public">
<Extends name="junit.framework.TestCase"/>
<Import name="com.tlgen.common.trace.Trace"/>
<Method name="findAll" return="%interfacedata%[]" manager="Product" client="Product" typerwd="1">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="von" type="int" />
<Parameter name="bis" type="int" />
<Parameter name="level" type="int" />
</Method>
</Test>
<Test name="eu.stardata.demo.client.test.product.ProductUpdate" type="public">
<Extends name="junit.framework.TestCase"/>
<Import name="com.tlgen.common.trace.Trace"/>
<Method name="update" manager="Product" client="Product" typerwd="2">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter type="%interfacedata%" manager="Product"/>
</Method>
</Test>
<Test name="eu.stardata.demo.client.test.product.ProductDelete" type="public">
<Extends name="junit.framework.TestCase"/>
<Import name="com.tlgen.common.trace.Trace"/>
<Method name="delete" manager="Product" client="Product" typerwd="3">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
</Method>
</Test>
<Test name="eu.stardata.demo.client.test.product.ProductAttributeDelete" type="public">
<Extends name="junit.framework.TestCase"/>
<Import name="com.tlgen.common.trace.Trace"/>
<Method name="delete" manager="ProductAttribute" client="Product" typerwd="3">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
</Method>
</Test>
</Design>
<!-- ================================================= -->
<!-- Design von production Session
-->
<!-- ================================================= -->
<Design name="production">
<Commentary name="This is a generate package for 'production'"/>
<!-- init the Manager Classes -->
<!--Manager>
TLGen
147
StarData Gmb
V 2.8
</Manager-->
<!-- init the Session Classes -->
<!--Session>
</Session-->
<!-- init the Test Classes -->
<!-- init the free Classes -->
<!--Freeclass>
</Freeclass-->
</Design>
<!-- ================================================= -->
<!-- Design von soap Session
-->
<!-- ================================================= -->
<Design name="soap" >
<Commentary name="This is a generate package for 'soap' for a Web Service"/>
<!-- init the Manager Classes -->
<!--Manager>
</Manager-->
<!-- init the Session Classes -->
<Session name="eu.stardata.demo.server.persistence.soap.SoapSessionBean" transactiontype="JTA" sessionType="Web
Service" inject="true">
methodtype="0">
<Extends name="com.tlgen.common.ejb.session.BaseSessionBean"/>
<Client name="eu.stardata.demo.client.bci.soap.SoapBci"/>
<Method name="updateUser" return="eu.stardata.demo.business.user.UserData" client="Soap" methodtype="0">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="user" type="eu.stardata.demo.business.user.UserData"/>
</Method>
<Method name="retrieveUser" return="java.util.List<eu.stardata.demo.business.user.UserData>" client="Soap"
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="name" type="java.lang.String"/>
</Method>
<Callback name = "eu.stardata.demo.server.persistence.soap.CallBackWeb ServiceUser" path
="C:/Projects/Project-Demo/source/soap" merge="1"/>
</Session>
<!-- init the Test Classes -->
<Test name="eu.stardata.demo.client.test.soap.TestWeb ServiceUser" client="Soap">
<Method name="updateUser" return="eu.stardata.demo.business.user.UserData" client="Soap">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="update" type="eu.stardata.demo.business.user.UserData"/>
</Method>
<Method name="retrieveUser" return="java.util.List<eu.stardata.demo.business.user.UserData>" client="Soap">
<Exception name="com.tlgen.common.exception.PersistenceException"/>
<Parameter name="name" type="java.lang.String"/>
</Method>
</Test>
</Design>
<!-- ================================================================ -->
<!-- Design von rest Session
-->
<!-- Archive = 0 -> make in application.xml a jar file
-->
<!-1 -> make in application.xml a war file
-->
<!-2 -> make in application.xml a rar file
-->
<!-3 -> make in application.xml a jar and a war file file -->
<!-- ================================================================ -->
<Design name="rest" archive="3" methodreference="false">
<Commentary name="This is a transient file"/>
<Commentary name="Session bean is a web service session bean for REST"/>
<!-- init the Manager Classes -->
<!--Manager>
</Manager-->
<!-- init the Session Classes -->
<Session name="eu.stardata.demo.server.persistence.rest.RestSessionBean" transactiontype="JTA" sessionType="REST"
intercep="false" inject="true" appPath="restApp" restPath="restSession">
<Extends name="com.tlgen.common.ejb.session.BaseSessionBean"/>
<Annotation name="javax.ejb.TransactionAttribute">
<Parameter type="javax.ejb.TransactionAttributeType" content="REQUIRES_NEW"/>
</Annotation>
<Annotation name="org.jboss.resteasy.annotations.cache.NoCache"/>
<Method name="createUser" return="eu.stardata.demo.business.user.UserJSon" client="Rest" rest="POST"
methodtype="0">
<Exception name="java.lang.Exception"/>
<Parameter name="user" type="eu.stardata.demo.business.user.UserJSon"/>
</Method>
<Method name="updateUser" return="eu.stardata.demo.business.user.UserJSon" client="Rest" rest="PUT"
methodtype="0">
<Exception name="java.lang.Exception"/>
TLGen
148
StarData Gmb
V 2.8
<Parameter name="user" type="eu.stardata.demo.business.user.UserJSon"/>
</Method>
<Method name="deleteUser" return="java.lang.String" client="Rest" rest="DELETE" methodtype="0">
<Exception name="java.lang.Exception"/>
<Parameter value="path" name="userId" type="long"/>
</Method>
<Method name="fetchUser"
return="com.tlgen.common.rest.TlgListResponse<eu.stardata.demo.business.user.UserJSon>" client="Rest" rest="GET" methodtype="0">
<Exception name="java.lang.Exception"/>
<Parameter default="" value="path" name="name" final="true" type="java.lang.String"/>
</Method>
<Method name="countUsers" return="long" client="Rest" rest="GET" methodtype="0">
<Exception name="java.lang.Exception"/>
<!--Parameter value="path" name="userId" type="long"/-->
<Parameter default="" value="query" name="name" final="true" type="java.lang.String"/>
</Method>
<Callback name = "eu.stardata.demo.server.rest.CallBackRest" callbackType="Session" path
="C:/Projects/Project-Demo/source/rest" merge="1"/>
</Session>
<!-- init the Test Classes -->
<Test name="eu.stardata.demo.client.test.rest.TestRestUser" sessionType="REST"/>
</Design>
</Project>
</Generator>
7.3 SQL Skript
-- --------- Drop all Tables ----------DROP TABLE Product CASCADE CONSTRAINTS;
DROP TABLE ServiceCost CASCADE CONSTRAINTS;
DROP TABLE ProductRelation CASCADE CONSTRAINTS;
DROP TABLE UserRole_UserTable CASCADE CONSTRAINTS;
DROP TABLE ProductPrice CASCADE CONSTRAINTS;
DROP TABLE UserRole CASCADE CONSTRAINTS;
DROP TABLE CustomerServiceAttribute CASCADE CONSTRAINTS;
DROP TABLE Classification CASCADE CONSTRAINTS;
DROP TABLE UserTable CASCADE CONSTRAINTS;
DROP TABLE CustomerService CASCADE CONSTRAINTS;
DROP TABLE OrderTable CASCADE CONSTRAINTS;
DROP TABLE ProductAttribute CASCADE CONSTRAINTS;
DROP TABLE UserTable_Product CASCADE CONSTRAINTS;
-- --------- Create Tables ----------CREATE TABLE Product (
Product_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'Product'; auto-generated by the DB
EJB3_OPTLOCK NUMBER(16) NULL,
-- EJB3 uses this value to realize the locking
MODIFY_DATE TIMESTAMP(6) DEFAULT SYSDATE NULL,
-- timestamp at which the table 'Product' has changed
description VARCHAR2(255) NULL,
-- /
isVisibleInCustomerOfferOrInvo NUMBER(1,0) NULL,
materialNumber VARCHAR2(255) NULL,
name VARCHAR2(255) NULL,
productOfferingId VARCHAR2(255) NULL,
shortName VARCHAR2(255) NULL,
CustomerService_ID NUMBER(24,0) NULL,
-- connection to the table 'CustomerService' (foreign key)
OrderTable_ID NUMBER(24,0) NULL,
-- connection to the table 'OrderTable' (foreign key)
CONSTRAINT Product_PK PRIMARY KEY (Product_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
CREATE TABLE ServiceCost (
ServiceCost_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'ServiceCost'; auto-generated by the DB
EJB3_OPTLOCK NUMBER(16) NULL,
-- EJB3 uses this value to realize the locking
MODIFY_DATE TIMESTAMP(6) DEFAULT SYSDATE NULL,
-- timestamp at which the table 'ServiceCost' has changed
allowanceUnitOfMeasure VARCHAR2(32) NULL,
allowanceValue NUMBER(24,0) NULL,
costType VARCHAR2(32) NULL,
costValue NUMBER(28,4) NULL,
-- /
currency VARCHAR2(32) NULL,
periodOfPaymentUnitOfMeasure VARCHAR2(32) NULL,
validityPeriod TIMESTAMP(6) NULL,
amount NUMBER(12,0) NULL,
CustomerService_ID NUMBER(24,0) NULL,
-- connection to the table 'CustomerService' (foreign key)
CONSTRAINT ServiceCost_PK PRIMARY KEY (ServiceCost_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
TLGen
149
StarData Gmb
V 2.8
CREATE TABLE ProductRelation (
ProductRelation_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'ProductRelation'; auto-generated by the DB
EJB3_OPTLOCK NUMBER(16) NULL,
-- EJB3 uses this value to realize the locking
MODIFY_DATE TIMESTAMP(6) DEFAULT SYSDATE NULL,
-- timestamp at which the table 'ProductRelation' has changed
name VARCHAR2(255) NULL,
relationType VARCHAR2(32) NULL,
Product_ID NUMBER(24,0) NULL,
-- connection to the table 'Product' (foreign key)
Parent_ID NUMBER(24,0) NULL,
-- connection to the table 'Parent' (foreign key)
CONSTRAINT ProductRelation_PK PRIMARY KEY (ProductRelation_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
CREATE TABLE UserRole_UserTable (
UserRole_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'UserRole'; auto-generated by the DB
UserTable_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'UserTable'; auto-generated by the DB
CONSTRAINT UserRole_UserTable_PK PRIMARY KEY (UserRole_ID, UserTable_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
CREATE TABLE ProductPrice (
ProductPrice_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'ProductPrice'; auto-generated by the DB
EJB3_OPTLOCK NUMBER(16) NULL,
-- EJB3 uses this value to realize the locking
MODIFY_DATE TIMESTAMP(6) DEFAULT SYSDATE NULL,
-- timestamp at which the table 'ProductPrice' has changed
allowancePeriod TIMESTAMP(6) NULL,
currency VARCHAR2(32) NULL,
periodOfPaymentUnitOfMeasure VARCHAR2(32) NULL,
priceType VARCHAR2(32) NULL,
productOfferingPrice NUMBER(28,4) NULL,
amount NUMBER(12,0) NULL,
unitOfMeasure VARCHAR2(32) NULL,
Product_ID NUMBER(24,0) NULL,
-- connection to the table 'Product' (foreign key)
CONSTRAINT ProductPrice_PK PRIMARY KEY (ProductPrice_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
CREATE TABLE UserRole (
UserRole_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'UserRole'; auto-generated by the DB
EJB3_OPTLOCK NUMBER(16) NULL,
-- EJB3 uses this value to realize the locking
MODIFY_DATE TIMESTAMP(6) DEFAULT SYSDATE NULL,
-- timestamp at which the table 'UserRole' has changed
RoleName VARCHAR2(32) NOT NULL,
-- the name of the role as enum
Description VARCHAR2(1024) NULL,
-- description of the role
CONSTRAINT UserRole_PK PRIMARY KEY (UserRole_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
CREATE TABLE CustomerServiceAttribute (
CustomerServiceAttribute_ID NUMBER(24,0) NOT NULL, -- the primary key of 'CustomerServiceAttribute'; auto-generated by the DB
EJB3_OPTLOCK NUMBER(16) NULL,
-- EJB3 uses this value to realize the locking
MODIFY_DATE TIMESTAMP(6) DEFAULT SYSDATE NULL,
-- timestamp at which the table 'CustomerServiceAttribute' has
changed
description VARCHAR2(255) NULL,
-- /
name VARCHAR2(255) NULL,
unit VARCHAR2(255) NULL,
value VARCHAR2(255) NULL,
CustomerService_ID NUMBER(24,0) NULL,
-- connection to the table 'CustomerService' (foreign key)
CONSTRAINT CustomerServiceAttribute_PK PRIMARY KEY (CustomerServiceAttribute_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
CREATE TABLE Classification (
Classification_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'Classification'; auto-generated by the DB
EJB3_OPTLOCK NUMBER(16) NULL,
-- EJB3 uses this value to realize the locking
MODIFY_DATE TIMESTAMP(6) DEFAULT SYSDATE NULL,
-- timestamp at which the table 'Classification' has changed
classificationSpecificationId VARCHAR2(255) NULL,
classSpecificationId VARCHAR2(255) NULL,
name VARCHAR2(255) NULL,
Product_ID NUMBER(24,0) NULL,
-- connection to the table 'Product' (foreign key)
CustomerService_ID NUMBER(24,0) NULL,
-- connection to the table 'CustomerService' (foreign key)
CONSTRAINT Classification_PK PRIMARY KEY (Classification_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
-- This table contains the internal accounts which are permitted to access the Demo system.
CREATE TABLE UserTable (
UserTable_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'UserTable'; auto-generated by the DB
EJB3_OPTLOCK NUMBER(16) NULL,
-- EJB3 uses this value to realize the locking
MODIFY_DATE TIMESTAMP(6) DEFAULT SYSDATE NULL,
-- timestamp at which the table 'UserTable' has changed
Email VARCHAR2(512) NULL,
-- the email of the user
FirstName VARCHAR2(255) NULL,
-- the first name(s) of the user
LastName VARCHAR2(255) NULL,
-- the last name of the user
UserName VARCHAR2(24) NOT NULL,
-- the username of the according Demo account
PassWord VARCHAR2(24) NOT NULL,
-- the pasword to access to the Demo program
TLGen
150
StarData Gmb
V 2.8
CONSTRAINT UserTable_PK PRIMARY KEY (UserTable_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
CREATE TABLE CustomerService (
CustomerService_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'CustomerService'; auto-generated by the DB
EJB3_OPTLOCK NUMBER(16) NULL,
-- EJB3 uses this value to realize the locking
MODIFY_DATE TIMESTAMP(6) DEFAULT SYSDATE NULL,
-- timestamp at which the table 'CustomerService' has changed
customerFacingServiceSpecId VARCHAR2(255) NULL,
description VARCHAR2(255) NULL,
materialNumber VARCHAR2(255) NULL,
name VARCHAR2(255) NULL,
shortName VARCHAR2(255) NULL,
status VARCHAR2(255) NULL,
version VARCHAR2(255) NULL,
CONSTRAINT CustomerService_PK PRIMARY KEY (CustomerService_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
-- the order class
CREATE TABLE OrderTable (
OrderTable_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'OrderTable'; auto-generated by the DB
EJB3_OPTLOCK NUMBER(16) NULL,
-- EJB3 uses this value to realize the locking
MODIFY_DATE TIMESTAMP(6) DEFAULT SYSDATE NULL,
-- timestamp at which the table 'OrderTable' has changed
OrderNumber VARCHAR2(32) NOT NULL,
-- the order number
Created TIMESTAMP(6) NULL,
-- the date of order created
OrderQuantity NUMBER(12,0) NOT NULL,
CONSTRAINT OrderTable_PK PRIMARY KEY (OrderTable_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
CREATE TABLE ProductAttribute (
ProductAttribute_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'ProductAttribute'; auto-generated by the DB
EJB3_OPTLOCK NUMBER(16) NULL,
-- EJB3 uses this value to realize the locking
MODIFY_DATE TIMESTAMP(6) DEFAULT SYSDATE NULL,
-- timestamp at which the table 'ProductAttribute' has changed
description VARCHAR2(255) NULL,
name VARCHAR2(255) NULL,
-- /
specificationCharacteristicId VARCHAR2(255) NULL,
unitOfMeasure VARCHAR2(255) NULL,
value VARCHAR2(255) NULL,
-- /
Product_ID NUMBER(24,0) NULL,
-- connection to the table 'Product' (foreign key)
CONSTRAINT ProductAttribute_PK PRIMARY KEY (ProductAttribute_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
CREATE TABLE UserTable_Product (
UserTable_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'UserTable'; auto-generated by the DB
Product_ID NUMBER(24,0) NOT NULL,
-- the primary key of 'Product'; auto-generated by the DB
CONSTRAINT UserTable_Product_PK PRIMARY KEY (UserTable_ID, Product_ID) USING INDEX TABLESPACE COINDEX
) Tablespace CODATA;
-- --- Foreign key -----ALTER TABLE Product ADD CONSTRAINT Product_1FK FOREIGN KEY (CustomerService_ID) REFERENCES CustomerService;
ALTER TABLE Product ADD CONSTRAINT Product_2FK FOREIGN KEY (OrderTable_ID) REFERENCES OrderTable;
ALTER TABLE ServiceCost ADD CONSTRAINT ServiceCost_1FK FOREIGN KEY (CustomerService_ID) REFERENCES CustomerService;
ALTER TABLE ProductRelation ADD CONSTRAINT ProductRelation_1FK FOREIGN KEY (Product_ID) REFERENCES Product;
ALTER TABLE ProductRelation ADD CONSTRAINT ProductRelation_2FK FOREIGN KEY (Parent_ID) REFERENCES ProductRelation;
ALTER TABLE ProductPrice ADD CONSTRAINT ProductPrice_1FK FOREIGN KEY (Product_ID) REFERENCES Product;
ALTER TABLE CustomerServiceAttribute ADD CONSTRAINT CustomerServiceAttribute_1FK FOREIGN KEY (CustomerService_ID) REFERENCES
CustomerService;
ALTER TABLE Classification ADD CONSTRAINT Classification_1FK FOREIGN KEY (Product_ID) REFERENCES Product;
ALTER TABLE Classification ADD CONSTRAINT Classification_2FK FOREIGN KEY (CustomerService_ID) REFERENCES CustomerService;
ALTER TABLE ProductAttribute ADD CONSTRAINT ProductAttribute_1FK FOREIGN KEY (Product_ID) REFERENCES Product;
-- --------- Drop all Sequences ----------DROP SEQUENCE Product_Product_ID_1SQ;
DROP SEQUENCE ServiceCost_ServiceCost_ID_1SQ;
DROP SEQUENCE ProductRelation_ProductRel_1SQ;
DROP SEQUENCE UserRole_UserTable_UserRol_1SQ;
DROP SEQUENCE ProductPrice_ProductPrice__1SQ;
DROP SEQUENCE UserRole_UserRole_ID_1SQ;
DROP SEQUENCE CustomerServiceAttribute_C_1SQ;
DROP SEQUENCE Classification_Classificat_1SQ;
DROP SEQUENCE UserTable_UserTable_ID_1SQ;
DROP SEQUENCE CustomerService_CustomerSe_1SQ;
DROP SEQUENCE OrderTable_OrderTable_ID_1SQ;
DROP SEQUENCE ProductAttribute_ProductAt_1SQ;
DROP SEQUENCE UserTable_Product_UserTabl_1SQ;
-- --------- Create Sequences ----------CREATE SEQUENCE Product_Product_ID_1SQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
TLGen
151
StarData Gmb
V 2.8
CREATE SEQUENCE ServiceCost_ServiceCost_ID_1SQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
CREATE SEQUENCE ProductRelation_ProductRel_1SQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
CREATE SEQUENCE UserRole_UserTable_UserRol_1SQ;
CREATE SEQUENCE ProductPrice_ProductPrice__1SQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
CREATE SEQUENCE UserRole_UserRole_ID_1SQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
CREATE SEQUENCE CustomerServiceAttribute_C_1SQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
CREATE SEQUENCE Classification_Classificat_1SQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
CREATE SEQUENCE UserTable_UserTable_ID_1SQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
CREATE SEQUENCE CustomerService_CustomerSe_1SQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
CREATE SEQUENCE OrderTable_OrderTable_ID_1SQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
CREATE SEQUENCE ProductAttribute_ProductAt_1SQ START WITH 1 INCREMENT BY 1 CACHE 10 MINVALUE 1;
CREATE SEQUENCE UserTable_Product_UserTabl_1SQ;
-- ------- Constraints ---------- ------- Foreign key index --------create index Product_1UQ on Product (CustomerService_ID) tablespace COINDEX;
create index Product_2UQ on Product (OrderTable_ID) tablespace COINDEX;
create index ServiceCost_1UQ on ServiceCost (CustomerService_ID) tablespace COINDEX;
create index ProductRelation_1UQ on ProductRelation (Product_ID) tablespace COINDEX;
create index ProductRelation_2UQ on ProductRelation (Parent_ID) tablespace COINDEX;
create index ProductPrice_1UQ on ProductPrice (Product_ID) tablespace COINDEX;
create index CustomerServiceAttribute_1UQ on CustomerServiceAttribute (CustomerService_ID) tablespace COINDEX;
create index Classification_1UQ on Classification (Product_ID) tablespace COINDEX;
create index Classification_2UQ on Classification (CustomerService_ID) tablespace COINDEX;
create index ProductAttribute_1UQ on ProductAttribute (Product_ID) tablespace COINDEX;
-- --- Table, Columns and Sequences was changes ------
7.4 Klassen und Interfaces
7.4.1 Data-Klassen
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.business.user;
import eu.stardata.demo.business.user.UserRoleData;
import java.util.Date;
import java.lang.String;
import java.io.Serializable;
import eu.stardata.demo.business.product.ProductData;
import java.util.List;
/**
* This is a generate package for 'user'
*
* This table contains the internal accounts which are permitted to access the Demo system.
*/
public class UserData implements Serializable {
private static final long serialVersionUID = 319770677;
// Methods from columns
private long m_ejb3Optlock;
private String m_email;
private String m_passWord;
private String m_firstName;
private long m_userID;
private String m_userName;
private String m_lastName;
private Date m_modifyDate;
// Methods from relations tables
private List<ProductData> m_product;
private List<UserRoleData> m_userRole;
// Methods from columns
public long getEjb3Optlock() {
return m_ejb3Optlock;
}
TLGen
152
StarData Gmb
V 2.8
public void setEjb3Optlock(long arg) {
m_ejb3Optlock = arg;
}
/**
* the email of the user
*/
public String getEmail() {
return m_email;
}
public void setEmail(String arg) {
m_email = arg;
}
/**
* the pasword to access to the Demo program
*/
public String getPassWord() {
return m_passWord;
}
public void setPassWord(String arg) {
m_passWord = arg;
}
/**
* the first name(s) of the user
*/
public String getFirstName() {
return m_firstName;
}
public void setFirstName(String arg) {
m_firstName = arg;
}
public long getUserID() {
return m_userID;
}
public void setUserID(long arg) {
m_userID = arg;
}
/**
* the username of the according Demo account
*/
public String getUserName() {
return m_userName;
}
public void setUserName(String arg) {
m_userName = arg;
}
/**
* the last name of the user
*/
public String getLastName() {
return m_lastName;
}
public void setLastName(String arg) {
m_lastName = arg;
}
public Date getModifyDate() {
return m_modifyDate;
}
public void setModifyDate(Date arg) {
m_modifyDate = arg;
}
// Methods from relations tables
TLGen
153
StarData Gmb
V 2.8
public List<ProductData> getProduct() {
return m_product;
}
public void setProduct(List<ProductData> arg) {
m_product = arg;
}
public List<UserRoleData> getUserRole() {
return m_userRole;
}
public void setUserRole(List<UserRoleData> arg) {
m_userRole = arg;
}
}
7.4.2 Interface-Data
Falls Verwendet
/**
* Generated by TLGEN - Do not edit!
* Version 2.8.002
*
* Legt alle Nutzer des Projekt fest.
*
*/
//======================================================================
package de.stardata.demo.business.user.dataif;
import de.stardata.demo.business.types.LockForLogin;
import de.stardata.demo.business.types.Authentification;
import de.stardata.demo.business.types.AccessHistoryConfig;
import com.tlgen.common.data.BaseDataIf;
import java.util.List;
import de.stardata.demo.business.user.dataif.UserRoleDataIf;
public interface UserDataIf extends BaseDataIf
{
// Methods from columns
public abstract Authentification getAuthentification();
public abstract void setAuthentification(Authentification arg);
/**
* Max. number of access entries to be stored for this user (in the table ACCESSHISTORY)
*
*/
public abstract AccessHistoryConfig getAccessHistoryConfig();
public abstract void setAccessHistoryConfig(AccessHistoryConfig arg);
public abstract long getUserID();
public abstract void setUserID(long arg);
public abstract LockForLogin getLock();
public abstract void setLock(LockForLogin arg);
public abstract long getDbVersion();
public abstract void setDbVersion(long arg);
}
TLGen
// Methods from relations tables
public abstract List<UserRoleDataIf> getUserRole();
public abstract void setUserRole(List<UserRoleDataIf> arg);
154
StarData Gmb
V 2.8
7.4.3 JSon Data-Klasse
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.business.user;
import javax.xml.bind.annotation.XmlRootElement;
import eu.stardata.demo.business.product.ProductJSon;
import eu.stardata.demo.business.user.UserRoleJSon;
import java.util.Date;
import java.lang.String;
import java.io.Serializable;
import java.util.List;
/**
* This is a generate package for 'user'
*
* This table contains the internal accounts which are permitted to access the Demo system.
*/
@XmlRootElement(name = "user")
public class UserJSon implements Serializable {
private static final long serialVersionUID = 741075541;
// Methods from columns
private long ejb3Optlock;
private String email;
private String passWord;
private String firstName;
private long userID;
private String userName;
private String lastName;
private Date modifyDate;
// Methods from relations tables
private List<ProductJSon> product;
private List<UserRoleJSon> userRole;
// Methods from columns
public long getEjb3Optlock() {
return ejb3Optlock;
}
public void setEjb3Optlock(long arg) {
ejb3Optlock = arg;
}
public String getEmail() {
return email;
}
public void setEmail(String arg) {
email = arg;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String arg) {
passWord = arg;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String arg) {
firstName = arg;
}
public long getUserID() {
return userID;
}
public void setUserID(long arg) {
TLGen
155
StarData Gmb
V 2.8
}
userID = arg;
public String getUserName() {
return userName;
}
public void setUserName(String arg) {
userName = arg;
}
public String getLastName() {
return lastName;
}
public void setLastName(String arg) {
lastName = arg;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date arg) {
modifyDate = arg;
}
// Methods from relations tables
public List<ProductJSon> getProduct() {
return product;
}
public void setProduct(List<ProductJSon> arg) {
product = arg;
}
public List<UserRoleJSon> getUserRole() {
return userRole;
}
}
public void setUserRole(List<UserRoleJSon> arg) {
userRole = arg;
}
7.4.4 Mapping zwischen Data-Klassen und JSon Klasse
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.business.user;
import eu.stardata.demo.business.user.UserRoleData;
import eu.stardata.demo.business.product.ProductJSon;
import eu.stardata.demo.business.user.UserRoleJSon;
import eu.stardata.demo.business.product.ProductMap;
import eu.stardata.demo.business.user.UserRoleMap;
import eu.stardata.demo.business.user.UserJSon;
import java.util.ArrayList;
import eu.stardata.demo.business.user.UserData;
import java.io.Serializable;
import eu.stardata.demo.business.product.ProductData;
import java.util.List;
/**
* This class map the class data to JSon class data and inverse
*/
public class UserMap implements Serializable {
private static final long serialVersionUID = 95856718;
// Mapping methods between class data and JSon data objects
/**
TLGen
156
StarData Gmb
V 2.8
* Map "UserData" object to "UserJSon" object data
* @param json
* @return
*/
public static UserData mapJSonToData(UserJSon json) {
UserData data = new UserData();
data.setEjb3Optlock(json.getEjb3Optlock());
data.setEmail(json.getEmail());
data.setPassWord(json.getPassWord());
data.setFirstName(json.getFirstName());
data.setUserID(json.getUserID());
data.setUserName(json.getUserName());
data.setLastName(json.getLastName());
data.setModifyDate(json.getModifyDate());
data.setProduct(getProductJSonList(json.getProduct()));
data.setUserRole(getUserRoleJSonList(json.getUserRole()));
return data;
}
/**
* Map "UserJSon" object to "UserData" object data
* @param data
* @return
*/
public static UserJSon mapDataToJSon(UserData data) {
UserJSon json = new UserJSon();
json.setEjb3Optlock(data.getEjb3Optlock());
json.setEmail(data.getEmail());
json.setPassWord(data.getPassWord());
json.setFirstName(data.getFirstName());
json.setUserID(data.getUserID());
json.setUserName(data.getUserName());
json.setLastName(data.getLastName());
json.setModifyDate(data.getModifyDate());
json.setProduct(getProductDataList(data.getProduct()));
json.setUserRole(getUserRoleDataList(data.getUserRole()));
}
return json;
/**
* Helper method for mapping
* @param data
* @return
*/
private static List<ProductData> getProductJSonList(List<ProductJSon> list) {
List<ProductData> listProduct = null;
if(list != null && !list.isEmpty()) {
listProduct = new ArrayList<ProductData>();
for(ProductJSon json : list) {
if(json != null) {
ProductData data = ProductMap.mapJSonToData(json);
listProduct.add(data);
}
}
}
return listProduct;
}
/**
* Helper method for mapping
* @param data
* @return
*/
private static List<UserRoleData> getUserRoleJSonList(List<UserRoleJSon> list) {
List<UserRoleData> listUserRole = null;
if(list != null && !list.isEmpty()) {
listUserRole = new ArrayList<UserRoleData>();
for(UserRoleJSon json : list) {
if(json != null) {
UserRoleData data = UserRoleMap.mapJSonToData(json);
listUserRole.add(data);
TLGen
157
StarData Gmb
V 2.8
}
}
}
return listUserRole;
}
/**
* Helper method for mapping
* @param data
* @return
*/
private static List<ProductJSon> getProductDataList(List<ProductData> list) {
List<ProductJSon> listProduct = null;
if(list != null && !list.isEmpty()) {
listProduct = new ArrayList<ProductJSon>();
for(ProductData data : list) {
if(data != null) {
ProductJSon json = ProductMap.mapDataToJSon(data);
listProduct.add(json);
}
}
}
return listProduct;
}
}
/**
* Helper method for mapping
* @param data
* @return
*/
private static List<UserRoleJSon> getUserRoleDataList(List<UserRoleData> list) {
List<UserRoleJSon> listUserRole = null;
if(list != null && !list.isEmpty()) {
listUserRole = new ArrayList<UserRoleJSon>();
for(UserRoleData data : list) {
if(data != null) {
UserRoleJSon json = UserRoleMap.mapDataToJSon(data);
listUserRole.add(json);
}
}
}
return listUserRole;
}
7.5 Session Bean
7.5.1 Session Bean-Klassen
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.server.persistence.user;
import eu.stardata.demo.business.user.UserRoleData;
import eu.stardata.demo.server.persistence.user.managerif.OrderManagerIf;
import java.lang.Long;
import javax.persistence.NamedNativeQueries;
import javax.persistence.SqlResultSetMapping;
import eu.stardata.demo.business.user.FindByLastNameData;
import eu.stardata.demo.server.persistence.user.TimeCore;
import eu.stardata.demo.server.persistence.user.managerif.UserManagerIf;
import eu.stardata.demo.business.user.OrderData;
import javax.persistence.NamedNativeQuery;
import eu.stardata.demo.business.user.UserData;
import javax.persistence.SqlResultSetMappings;
import javax.interceptor.Interceptors;
import eu.stardata.demo.server.persistence.user.TimeCore;
import javax.ejb.Stateless;
import eu.stardata.demo.client.bci.user.UserBci;
import eu.stardata.demo.server.persistence.user.managerif.UserRoleManagerIf;
import javax.ejb.Remote;
TLGen
158
StarData Gmb
V 2.8
import java.lang.String;
import javax.ejb.EJB;
import com.tlgen.common.exception.PersistenceException;
import java.util.List;
/**
* This is a generate package for 'user'
*
* A session bean encapsulates business logic that can be invoked programmatically
* by a client over local, remote, or web service client views.
*/
@Stateless(name = UserBci.JNDI_NAME, mappedName = "demo/"+UserBci.JNDI_NAME+"/remote")
@Remote(UserBci.class)
@Interceptors(TimeCore.class)
public class UserSessionBean implements UserBci {
// Session annotations and fields for local manager
@EJB
private UserManagerIf m_UserManagerIf;
@EJB
private UserRoleManagerIf m_UserRoleManagerIf;
@EJB
private OrderManagerIf m_OrderManagerIf;
/**
* Default Constructor
*/
public UserSessionBean() {
super();
}
// Session class methods
/**
* Session method "findByLastNameUser()"
* @param name
* @param level
* @return
* @throws PersistenceException
*/
public List<FindByLastNameData> findByLastNameUser(String name, int level) throws PersistenceException {
try {
return m_UserManagerIf.findByLastName(name, level);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "clearUserRole()"
* @throws PersistenceException
*/
public void clearUserRole() throws PersistenceException {
try {
m_UserRoleManagerIf.clear();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "clearOrder()"
* @throws PersistenceException
*/
public void clearOrder() throws PersistenceException {
try {
m_OrderManagerIf.clear();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "findAllUser()"
* @param from
TLGen
159
StarData Gmb
V 2.8
* @param to
* @param level
* @return
* @throws PersistenceException
*/
public UserData[] findAllUser(int from, int to, int level) throws PersistenceException {
try {
return m_UserManagerIf.findAll(from, to, level);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "findAllUserRole()"
* @param from
* @param to
* @param level
* @return
* @throws PersistenceException
*/
public UserRoleData[] findAllUserRole(int from, int to, int level) throws PersistenceException {
try {
return m_UserRoleManagerIf.findAll(from, to, level);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "closeUser()"
* @throws PersistenceException
*/
public void closeUser() throws PersistenceException {
try {
m_UserManagerIf.close();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "findByNameUser()"
* @param name
* @param level
* @return
* @throws PersistenceException
*/
public UserData[] findByNameUser(String name, int level) throws PersistenceException {
try {
return m_UserManagerIf.findByName(name, level);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "demoUserFunctionUser()"
* @throws PersistenceException
*/
public List<Object> demoUserFunctionUser() throws PersistenceException {
try {
return m_UserManagerIf.demoUserFunction();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "detachUser()"
* @param arg
* @return
* @throws PersistenceException
*/
public void detachUser(UserData arg) throws PersistenceException {
try {
m_UserManagerIf.detach(arg);
TLGen
160
StarData Gmb
V 2.8
}
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
/**
* Session method "flushUser()"
* @throws PersistenceException
*/
public void flushUser() throws PersistenceException {
try {
m_UserManagerIf.flush();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "removeUserRole()"
* @param arg
* @return
* @throws PersistenceException
*/
public void removeUserRole(UserRoleData arg) throws PersistenceException {
try {
m_UserRoleManagerIf.remove(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "flushUserRole()"
* @throws PersistenceException
*/
public void flushUserRole() throws PersistenceException {
try {
m_UserRoleManagerIf.flush();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "countUserTyp9User()"
* @throws PersistenceException
*/
public List<Object> countUserTyp9User() throws PersistenceException {
try {
return m_UserManagerIf.countUserTyp9();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "readUpdateUserRole()"
* @param arg
* @return
* @throws PersistenceException
*/
public void readUpdateUserRole(UserRoleData arg) throws PersistenceException {
try {
m_UserRoleManagerIf.readUpdate(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "detachOrder()"
* @param arg
* @return
* @throws PersistenceException
*/
public void detachOrder(OrderData arg) throws PersistenceException {
try {
TLGen
161
StarData Gmb
V 2.8
m_OrderManagerIf.detach(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "removeUser()"
* @param arg
* @return
* @throws PersistenceException
*/
public void removeUser(UserData arg) throws PersistenceException {
try {
m_UserManagerIf.remove(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "updateUserRole()"
* @param arg
* @return
* @throws PersistenceException
*/
public void updateUserRole(UserRoleData arg) throws PersistenceException {
try {
m_UserRoleManagerIf.update(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "createUserRole()"
* @param arg
* @return
* @throws PersistenceException
*/
public UserRoleData createUserRole(UserRoleData arg) throws PersistenceException {
try {
return m_UserRoleManagerIf.create(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "readUpdateUser()"
* @param arg
* @return
* @throws PersistenceException
*/
public void readUpdateUser(UserData arg) throws PersistenceException {
try {
m_UserManagerIf.readUpdate(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "flushOrder()"
* @throws PersistenceException
*/
public void flushOrder() throws PersistenceException {
try {
m_OrderManagerIf.flush();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "fullUpdateUser()"
* @param arg
TLGen
162
StarData Gmb
V 2.8
* @return
* @throws PersistenceException
*/
public void fullUpdateUser(UserData arg) throws PersistenceException {
try {
m_UserManagerIf.fullUpdate(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "clearUser()"
* @throws PersistenceException
*/
public void clearUser() throws PersistenceException {
try {
m_UserManagerIf.clear();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "updateOrder()"
* @param arg
* @return
* @throws PersistenceException
*/
public void updateOrder(OrderData arg) throws PersistenceException {
try {
m_OrderManagerIf.update(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "findAllOrder()"
* @param from
* @param to
* @param level
* @return
* @throws PersistenceException
*/
public OrderData[] findAllOrder(int from, int to, int level) throws PersistenceException {
try {
return m_OrderManagerIf.findAll(from, to, level);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "closeUserRole()"
* @throws PersistenceException
*/
public void closeUserRole() throws PersistenceException {
try {
m_UserRoleManagerIf.close();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "readUpdateOrder()"
* @param arg
* @return
* @throws PersistenceException
*/
public void readUpdateOrder(OrderData arg) throws PersistenceException {
try {
m_OrderManagerIf.readUpdate(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
TLGen
163
StarData Gmb
V 2.8
}
/**
* Session method "detachUserRole()"
* @param arg
* @return
* @throws PersistenceException
*/
public void detachUserRole(UserRoleData arg) throws PersistenceException {
try {
m_UserRoleManagerIf.detach(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "createOrder()"
* @param arg
* @return
* @throws PersistenceException
*/
public OrderData createOrder(OrderData arg) throws PersistenceException {
try {
return m_OrderManagerIf.create(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "fullUpdateUserRole()"
* @param arg
* @return
* @throws PersistenceException
*/
public void fullUpdateUserRole(UserRoleData arg) throws PersistenceException {
try {
m_UserRoleManagerIf.fullUpdate(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "createUser()"
* @param arg
* @return
* @throws PersistenceException
*/
public UserData createUser(UserData arg) throws PersistenceException {
try {
return m_UserManagerIf.create(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "findByPrimaryKeyOrder()"
* @param arg
* @param level
* @return
* @throws PersistenceException
*/
public OrderData findByPrimaryKeyOrder(OrderData arg, int level) throws PersistenceException {
try {
return m_OrderManagerIf.findByPrimaryKey(arg, level);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "findByPrimaryKeyUserRole()"
* @param arg
* @param level
TLGen
164
StarData Gmb
V 2.8
* @return
* @throws PersistenceException
*/
public UserRoleData findByPrimaryKeyUserRole(UserRoleData arg, int level) throws PersistenceException {
try {
return m_UserRoleManagerIf.findByPrimaryKey(arg, level);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "findByPrimaryKeyUser()"
* @param arg
* @param level
* @return
* @throws PersistenceException
*/
public UserData findByPrimaryKeyUser(UserData arg, int level) throws PersistenceException {
try {
return m_UserManagerIf.findByPrimaryKey(arg, level);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "closeOrder()"
* @throws PersistenceException
*/
public void closeOrder() throws PersistenceException {
try {
m_OrderManagerIf.close();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "removeOrder()"
* @param arg
* @return
* @throws PersistenceException
*/
public void removeOrder(OrderData arg) throws PersistenceException {
try {
m_OrderManagerIf.remove(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "fullUpdateOrder()"
* @param arg
* @return
* @throws PersistenceException
*/
public void fullUpdateOrder(OrderData arg) throws PersistenceException {
try {
m_OrderManagerIf.fullUpdate(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "updateUser()"
* @param arg
* @return
* @throws PersistenceException
*/
public void updateUser(UserData arg) throws PersistenceException {
try {
m_UserManagerIf.update(arg);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
TLGen
165
StarData Gmb
V 2.8
}
}
/**
* Session method "countUserTyp11User()"
* @param name
* @return
* @throws PersistenceException
*/
public Long countUserTyp11User(String name) throws PersistenceException {
try {
return m_UserManagerIf.countUserTyp11(name);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
}
7.5.2 Session Bean Interface
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.client.bci.user;
import eu.stardata.demo.business.user.UserRoleData;
import eu.stardata.demo.business.user.FindByLastNameData;
import javax.ejb.Remote;
import java.lang.String;
import eu.stardata.demo.business.user.OrderData;
import eu.stardata.demo.business.user.UserData;
import com.tlgen.common.exception.PersistenceException;
import java.util.List;
@Remote
public interface UserBci {
// Client interface Fields
public final static String JNDI_NAME_PREFIX = "demo";
public final static String JNDI_NAME = "eu.stardata.demo.server.persistence.user.UserSessionBean";
public final static String MANAGER_NAME = "managerDemo";
public final static String EAR_NAME = "demo";
public final static String PACKAGE_NAME = "user";
// Session - Client interface methods
public List<FindByLastNameData> findByLastNameUser(String name, int level) throws PersistenceException;
public void clearUserRole() throws PersistenceException;
public void clearOrder() throws PersistenceException;
public eu.stardata.demo.business.user.UserData[] findAllUser(int from, int to, int level) throws PersistenceException;
public eu.stardata.demo.business.user.UserRoleData[] findAllUserRole(int from, int to, int level) throws PersistenceException;
public void closeUser() throws PersistenceException;
public eu.stardata.demo.business.user.UserData[] findByNameUser(String name, int level) throws PersistenceException;
public List<Object> demoUserFunctionUser() throws PersistenceException;
public void detachUser(UserData arg) throws PersistenceException;
public void flushUser() throws PersistenceException;
public void removeUserRole(UserRoleData arg) throws PersistenceException;
public void flushUserRole() throws PersistenceException;
public List<Object> countUserTyp9User() throws PersistenceException;
public void readUpdateUserRole(UserRoleData arg) throws PersistenceException;
TLGen
166
StarData Gmb
V 2.8
public void detachOrder(OrderData arg) throws PersistenceException;
public void removeUser(UserData arg) throws PersistenceException;
public void updateUserRole(UserRoleData arg) throws PersistenceException;
public UserRoleData createUserRole(UserRoleData arg) throws PersistenceException;
public void readUpdateUser(UserData arg) throws PersistenceException;
public void flushOrder() throws PersistenceException;
public void fullUpdateUser(UserData arg) throws PersistenceException;
public void clearUser() throws PersistenceException;
public void updateOrder(OrderData arg) throws PersistenceException;
public eu.stardata.demo.business.user.OrderData[] findAllOrder(int from, int to, int level) throws PersistenceException;
public void closeUserRole() throws PersistenceException;
public void readUpdateOrder(OrderData arg) throws PersistenceException;
public void detachUserRole(UserRoleData arg) throws PersistenceException;
public OrderData createOrder(OrderData arg) throws PersistenceException;
public void fullUpdateUserRole(UserRoleData arg) throws PersistenceException;
public UserData createUser(UserData arg) throws PersistenceException;
public OrderData findByPrimaryKeyOrder(OrderData arg, int level) throws PersistenceException;
public UserRoleData findByPrimaryKeyUserRole(UserRoleData arg, int level) throws PersistenceException;
public UserData findByPrimaryKeyUser(UserData arg, int level) throws PersistenceException;
public void closeOrder() throws PersistenceException;
public void removeOrder(OrderData arg) throws PersistenceException;
public void fullUpdateOrder(OrderData arg) throws PersistenceException;
public void updateUser(UserData arg) throws PersistenceException;
}
public java.lang.Long countUserTyp11User(String name) throws PersistenceException;
7.5.3 Client Factory-Klasse
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.client.bci.user;
import eu.stardata.demo.client.bci.user.UserBci;
import com.tlgen.common.exception.PersistenceException;
import com.tlgen.common.bci.BciFactory;
/**
* This is a generate package for 'user'
*
* The client of an enterprise bean obtains a reference
* to an instance of an enterprise bean.
*/
public class UserBciFactory extends BciFactory {
/**
* getUserBci()
*/
public static synchronized UserBci getUserBci() throws PersistenceException {
return (UserBci)getBciImplementation(UserBci.class);
TLGen
167
StarData Gmb
V 2.8
}
}
7.5.4 Session Bean REST Interface
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.server.persistence.rest;
import java.lang.Exception;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.Path;
import javax.ws.rs.POST;
import javax.ws.rs.GET;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import java.lang.String;
import com.tlgen.common.rest.TlgListResponse;
import eu.stardata.demo.business.user.UserJSon;
import javax.ws.rs.Produces;
import javax.ws.rs.PUT;
@Path("/restSession")
public interface RestSession {
// Client interface Fields
public final static String JNDI_NAME_PREFIX = "demo";
public final static String JNDI_NAME = "eu.stardata.demo.server.persistence.rest.RestSessionBean";
public final static String MANAGER_NAME = "managerDemo";
public final static String EAR_NAME = "demo";
public final static String PACKAGE_NAME = "rest";
// Session - Client interface methods
@GET
@Path("/fetchUser/{name}")
@Produces("application/json")
public TlgListResponse<UserJSon> fetchUser(@PathParam("name") final @DefaultValue("") String name) throws Exception;
@POST
@Path("/createUser")
@Consumes("application/json")
@Produces("application/json")
public UserJSon createUser(UserJSon user) throws Exception;
@GET
@Path("/countUsers")
@Produces("application/json")
public long countUsers(@QueryParam("name") final @DefaultValue("") String name) throws Exception;
@DELETE
@Path("/deleteUser/{userId}")
@Produces("application/json")
public String deleteUser(@PathParam("userId") long userId) throws Exception;
@PUT
@Path("/updateUser")
@Consumes("application/json")
@Produces("application/json")
public UserJSon updateUser(UserJSon user) throws Exception;
}
7.6 Entity Manager Bean
7.6.1 Entity Manager Bean-Klasse
TLGen
168
StarData Gmb
V 2.8
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.server.persistence.user.manager;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.tlgen.common.bci.ServiceLocator;
import com.tlgen.common.exception.PersistenceException;
import eu.stardata.demo.business.user.FindByLastNameData;
import eu.stardata.demo.business.user.UserData;
import eu.stardata.demo.client.bci.user.UserBci;
import eu.stardata.demo.server.criteria.user.UserCriteria;
import eu.stardata.demo.server.persistence.product.managerif.ProductManagerIf;
import eu.stardata.demo.server.persistence.user.entity.UserEntity;
import eu.stardata.demo.server.persistence.user.managerif.UserManagerIf;
/**
* This is a generate package for 'user'
*
* Entities are managed by the entity manager,
* which is represented by javax.persistence.EntityManager instances.
* Each EntityManager instance is associated with a persistence context.
*/
@Stateless(name = UserManagerIf.JNDI_NAME)
@Local(UserManagerIf.class)
public class UserManager implements UserManagerIf {
// Manager class data fields
@PersistenceContext(unitName = UserBci.MANAGER_NAME)
public EntityManager m_manager = null;
private String m_findByLastName = "SELECT * FROM USERTABLE WHERE USERNAME = ? ORDER BY LASTNAME";
private String m_findByName = "select o from UserEntity o where o.userName = :name";
private String m_SQL_FIND_ALL = "select o from UserEntity o";
private String m_demoUserFunction = "select rawtohex(sys_guid()) from dual";
private String m_countUserTyp9 = "select count(o) from UserEntity o";
@EJB
private ProductManagerIf m_ProductManagerIf = null;
// Manager class methods
/**
* Manager method "findByLastName()"
* @param name
* @param level
* @return
* @throws PersistenceException
*/
public List<FindByLastNameData> findByLastName(String name, int level) throws PersistenceException {
try {
List<FindByLastNameData> list = null;
List<?> entityList =
m_manager.createNativeQuery(m_findByLastName,"findByLastName").setParameter(1,name).getResultList();
if(entityList != null && entityList.size() > 0) {
list = new ArrayList<FindByLastNameData>();
for(Object entity : entityList) {
if(entity != null) {
FindByLastNameData data = new FindByLastNameData();
if(entity instanceof UserEntity) {
data.setUser(((UserEntity)entity).callUser(level));
}
list.add(data);
}
}
}
return list;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
TLGen
169
StarData Gmb
V 2.8
/**
* Manager method "update()"
* @param arg
* @return
* @throws PersistenceException
*/
public void update(UserData arg) throws PersistenceException {
try {
UserEntity entity = new UserEntity();
if(entity != null) {
entity.updateUser(arg);
m_manager.merge(entity);
}
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "findByName()"
* @param name
* @param level
* @return
* @throws PersistenceException
*/
public UserData[] findByName(String name, int level) throws PersistenceException {
try {
UserData[] arrayData = null;
List<?> list = m_manager.createQuery(m_findByName).setParameter("name",name).getResultList();
if(list != null && list.size() > 0) {
arrayData = new UserData[list.size()];
int idx = 0;
for(Object entity : list) {
if(entity != null) {
arrayData[idx++] = ((UserEntity)entity).callUser(level);
}
}
}
return arrayData;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "detach()"
* @param arg
* @return
* @throws PersistenceException
*/
public void detach(UserData arg) throws PersistenceException {
try {
UserEntity entity = getEntityByPrimaryKey(arg);
if(entity != null && m_manager.contains(entity)) {
m_manager.detach(entity);
}
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "remove()"
* @param arg
* @return
* @throws PersistenceException
*/
public void remove(UserData arg) throws PersistenceException {
try {
UserEntity entity = getEntityByPrimaryKey(arg);
if(entity != null) {
m_manager.remove(entity);
}
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
TLGen
170
StarData Gmb
V 2.8
}
/**
* Manager method "findAll()"
* @param from
* @param to
* @param level
* @return
* @throws PersistenceException
*/
public UserData[] findAll(int from, int to, int level) throws PersistenceException {
try {
UserData[] listData = null;
List<?> list = m_manager.createQuery(m_SQL_FIND_ALL).setFirstResult(from).setMaxResults(to).getResultList();
if(list != null && list.size() > 0) {
listData = new UserData[list.size()];
int idx = 0;
for(Object entity : list) {
if(entity != null) {
listData[idx++] = ((UserEntity)entity).callUser(level);
}
}
}
return listData;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "findByPrimaryKey()"
* @param arg
* @param level
* @return
* @throws PersistenceException
*/
public UserData findByPrimaryKey(UserData arg, int level) throws PersistenceException {
try {
UserData classData = null;
UserEntity entity = m_manager.find(UserEntity.class, arg.getUserID());
if(entity != null) {
classData = entity.callUser(level);
}
return classData;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "demoUserFunction()"
* @throws PersistenceException
*/
public List<Object> demoUserFunction() throws PersistenceException {
try {
List<Object> listData = null;
List<?> list = m_manager.createNativeQuery(m_demoUserFunction).getResultList();
if(list != null && list.size() > 0) {
listData = new ArrayList<Object>();
for(Object object : list) {
if(object != null) {
listData.add(object);
}
}
}
return listData;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "create()"
* @param arg
* @return
* @throws PersistenceException
*/
TLGen
171
StarData Gmb
V 2.8
public UserData create(UserData arg) throws PersistenceException {
try {
UserEntity entity = new UserEntity(arg);
m_manager.persist(entity);
return entity.callUser(99);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "getManager()"
* @throws PersistenceException
*/
public UserManagerIf getManager() throws PersistenceException {
try {
return (UserManagerIf)ServiceLocator.getInstance().getLocalReference(UserManagerIf.class);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "close()"
* @throws PersistenceException
*/
public void close() throws PersistenceException {
try {
m_manager.close();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "clear()"
* @throws PersistenceException
*/
public void clear() throws PersistenceException {
try {
m_manager.clear();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "countUserTyp9()"
* @throws PersistenceException
*/
public List<Object> countUserTyp9() throws PersistenceException {
try {
List<Object> listData = null;
List<?> list = m_manager.createQuery(m_countUserTyp9).getResultList();
if(list != null && list.size() > 0) {
listData = new ArrayList<Object>();
for(Object object : list) {
if(object != null) {
listData.add(object);
}
}
}
return listData;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "readUpdate()"
* @param arg
* @return
* @throws PersistenceException
*/
public void readUpdate(UserData arg) throws PersistenceException {
try {
UserEntity entity = getEntityByPrimaryKey(arg);
TLGen
172
StarData Gmb
V 2.8
}
if(entity != null) {
entity.updateUser(arg);
m_manager.merge(entity);
}
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
/**
* Manager method "flush()"
* @throws PersistenceException
*/
public void flush() throws PersistenceException {
try {
m_manager.flush();
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "getEntityByPrimaryKey()"
* @param arg
* @return
* @throws PersistenceException
*/
public UserEntity getEntityByPrimaryKey(UserData arg) throws PersistenceException {
try {
UserEntity entity = m_manager.find(UserEntity.class, arg.getUserID());
return entity;
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "fullUpdate()"
* @param arg
* @return
* @throws PersistenceException
*/
public void fullUpdate(UserData arg) throws PersistenceException {
try {
UserEntity entity = new UserEntity();
if(entity != null) {
entity.updateUser(arg);
entity.addUser();
m_manager.merge(entity);
}
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "countUserTyp11()"
* @param name
* @return
* @throws PersistenceException
*/
public Long countUserTyp11(String name) throws PersistenceException {
try {
UserCriteria criteria = new UserCriteria();
return criteria.countUserTyp11(m_manager, name);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Manager method "getEntityManager()"
* @return
*/
public EntityManager getEntityManager() {
return m_manager;
}
TLGen
173
StarData Gmb
V 2.8
}
7.6.2 Entity Manager Bean Interface
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.server.persistence.user.managerif;
import javax.persistence.EntityManager;
import eu.stardata.demo.server.persistence.user.entity.UserEntity;
import eu.stardata.demo.business.user.FindByLastNameData;
import eu.stardata.demo.server.persistence.user.managerif.UserManagerIf;
import java.lang.String;
import eu.stardata.demo.business.user.UserData;
import com.tlgen.common.exception.PersistenceException;
import java.util.List;
/**
* This is a generate package for 'user'
*
* This is a interface for a entity manager.
*/
public interface UserManagerIf {
// Manager interface data fields
public String JNDI_NAME = "eu.stardata.demo.server.persistence.user.managerif.UserManagerIf";
public String EAR_NAME = "demo";
// Manager interface methods
public List<FindByLastNameData> findByLastName(String name, int level) throws PersistenceException;
public void update(UserData arg) throws PersistenceException;
public UserData[] findByName(String name, int level) throws PersistenceException;
public void detach(UserData arg) throws PersistenceException;
public void remove(UserData arg) throws PersistenceException;
public UserData[] findAll(int from, int to, int level) throws PersistenceException;
public UserData findByPrimaryKey(UserData arg, int level) throws PersistenceException;
public List<Object> demoUserFunction() throws PersistenceException;
public UserData create(UserData arg) throws PersistenceException;
public UserManagerIf getManager() throws PersistenceException;
public void close() throws PersistenceException;
public void clear() throws PersistenceException;
public List<Object> countUserTyp9() throws PersistenceException;
public void readUpdate(UserData arg) throws PersistenceException;
public void flush() throws PersistenceException;
public UserEntity getEntityByPrimaryKey(UserData arg) throws PersistenceException;
public void fullUpdate(UserData arg) throws PersistenceException;
public Long countUserTyp11(String name) throws PersistenceException;
public EntityManager getEntityManager() ;
}
TLGen
174
StarData Gmb
V 2.8
7.7 Entity Bean
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.server.persistence.user.entity;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Version;
import org.hibernate.annotations.GenericGenerator;
import eu.stardata.demo.business.user.UserData;
import eu.stardata.demo.business.user.UserRoleData;
import eu.stardata.demo.server.persistence.product.entity.ProductEntity;
/**
* This is a generate package for 'user'
*
* An entity is a lightweight persistence domain object.
* Typically, an entity represents a table in a relational database,
* and each entity instance corresponds to a row in that table.
*/
@Entity
@Table(name="UserTable",uniqueConstraints = {})
@GenericGenerator(name="SEQ_STORE_USER", strategy = "sequence", parameters = {@org.hibernate.annotations.Parameter(name = "sequence", value =
"USERTABLE_USERTABLE_ID_1SQ")})
public class UserEntity implements Serializable {
private static final long serialVersionUID = 47812459;
// Entity data field
private UserData m_user = null;
// Fields from relations tables
private List<ProductEntity> m_product = new ArrayList<ProductEntity>();
private List<UserRoleEntity> m_userRole = new ArrayList<UserRoleEntity>();
// constructors
/**
* Default Constructor
*/
public UserEntity() {
}
/**
* Constructor
* @param arg
*/
public UserEntity(UserData arg) {
m_user = arg;
fillUser();
addUser();
}
/**
* Helper Method "setUser()"
*/
public void setUser(UserData arg) {
m_user = arg;
}
TLGen
175
StarData Gmb
V 2.8
// Helper methods
/**
* Helper Method "makeUser()"
*/
public UserData makeUser() {
if(m_user == null) {
m_user = new eu.stardata.demo.business.user.UserData();
}
return m_user;
}
/**
* Helper Method "updateUser()", used for update data in the database,
* for relations "one to many" and "one to one"
*/
public void updateUser(UserData arg) {
m_user = arg;
fillUser();
}
/**
* Helper Method "fillUser()"
*/
public void fillUser() {
// Relation ManyToMany, save data for "User" child, "UserRole"
if(makeUser().getUserRole() != null) {
for(UserRoleData dataif : makeUser().getUserRole()) {
UserRoleEntity entity = new UserRoleEntity(dataif);
m_userRole.add(entity);
}
}
}
/**
* Helper Method "addUser()", used for create new objects in database,
* for relations "one to many" and "one to one"
*/
public void addUser() {
}
/**
* Helper Method "callUser()", used for read objects from the database,
* for relations "one to many", "one to one" and "many to one"
*/
public UserData callUser(int level) {
if(level > 0)
{
// Relation ManyToMany, save "UserRole" data object, in "User" object
if(m_userRole != null) {
List<UserRoleData> list1 = new ArrayList<UserRoleData>();
for(UserRoleEntity entity : m_userRole) {
if(entity != null) {
UserRoleData data = entity.callUserRole(level - 1);
list1.add(data);
}
}
makeUser().setUserRole(list1);
}
}
// return the data object
return makeUser();
}
// Methods from columns
@Id
@Column(name = "UserTable_ID", nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_STORE_USER")
public long getUserID() {
return makeUser().getUserID();
}
public void setUserID(long arg) {
makeUser().setUserID(arg);
}
TLGen
176
StarData Gmb
V 2.8
@Column(name = "EJB3_OPTLOCK")
@Version
public long getEjb3Optlock() {
return makeUser().getEjb3Optlock();
}
public void setEjb3Optlock(long arg) {
makeUser().setEjb3Optlock(arg);
}
@Column(name = "MODIFY_DATE")
public Date getModifyDate() {
return makeUser().getModifyDate();
}
public void setModifyDate(Date arg) {
makeUser().setModifyDate(arg);
}
@Column(name = "Email", length = 512)
public String getEmail() {
return makeUser().getEmail();
}
public void setEmail(String arg) {
makeUser().setEmail(arg);
}
@Column(name = "FirstName", length = 255)
public String getFirstName() {
return makeUser().getFirstName();
}
public void setFirstName(String arg) {
makeUser().setFirstName(arg);
}
@Column(name = "LastName", length = 255)
public String getLastName() {
return makeUser().getLastName();
}
public void setLastName(String arg) {
makeUser().setLastName(arg);
}
@Column(name = "UserName", length = 24, nullable = false)
public String getUserName() {
return makeUser().getUserName();
}
public void setUserName(String arg) {
makeUser().setUserName(arg);
}
@Column(name = "PassWord", length = 24, nullable = false)
public String getPassWord() {
return makeUser().getPassWord();
}
public void setPassWord(String arg) {
makeUser().setPassWord(arg);
}
// Methods from relations tables
@ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},mappedBy = "user",targetEntity =
ProductEntity.class)
public List<ProductEntity> getProduct() {
return m_product;
}
public void setProduct(List<ProductEntity> arg) {
m_product = arg;
}
@ManyToMany(targetEntity = UserRoleEntity.class)
TLGen
177
StarData Gmb
V 2.8
@JoinTable(name = "UserRole_UserTable",inverseJoinColumns = {@JoinColumn(name = "UserRole_ID",insertable = true, updatable = true,
nullable = true, unique = false)},joinColumns = {@JoinColumn(name = "UserTable_ID",insertable = true, updatable = true, nullable = true, unique = false)})
public List<UserRoleEntity> getUserRole() {
return m_userRole;
}
public void setUserRole(List<UserRoleEntity> arg) {
m_userRole = arg;
}
}
7.8 Interceptor-Klasse
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.server.persistence.user;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import com.tlgen.common.exception.PersistenceException;
/**
* This is a generate package for 'user'
*
* Interceptors are used in conjunction with Java EE managed classes
*/
public class TimeCore
{
// Session annotations and fields for interceptor
/**
* Default Constructor
*/
public TimeCore()
{
super();
}
// Session class methods
/**
* Interceptor method "timeTrace()"
* @param invocation
* @return
* @throws PersistenceException
*/
@AroundInvoke
public java.lang.Object timeTrace(InvocationContext invocation) throws PersistenceException
{
long start = 0;
boolean toTime = true;
try
{
if(toTime)
{
start = System.currentTimeMillis();
}
return invocation.proceed();
} catch(Exception ex)
{
throw new PersistenceException(ex.getMessage(),ex,1);
}
finally
{
if(toTime)
{
// Example to time
long ende = System.currentTimeMillis();
String klasse = invocation.getTarget().toString();
String methode = invocation.getMethod().getName();
System.out.println(klasse + ":" + methode + " -> " + (ende - start) + "ms");
TLGen
178
StarData Gmb
V 2.8
}
}
}
}
7.9 Timerservice-Klasse
/**
* This is a generated file by TLGEN.
* Do not change it with a file editor.
*
* Version 2.8.002
*/
//======================================================================
package eu.stardata.server.service.monitor;
import java.util.Date;
import javax.annotation.Resource;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.inject.Inject;
import com.tlgen.common.exception.PersistenceException;
import eu.stardata.client.bci.monitor.MonitorBci;
import eu.stardata.client.monitor.CallBackServiceMonitorIf;
/**
* This is a generate file
* Service timer test for Monitor
*
* This is a timer service class
*/
@Stateless(name = MonitorBci.JNDI_NAME, mappedName = "efp/"+MonitorBci.JNDI_NAME+"/remote")
@Remote(MonitorBci.class)
public class MonitorSessionBean implements MonitorBci
{
// Session annotations and fields for timer service
@Resource
private TimerService m_timerService;
private static final String KOMMAND = "TLG";
@Inject
private CallBackServiceMonitorIf m_callBack;
// Session class methods
/**
* Timer service method "initMonitor()"
* @param start
* @param stop
* @param repeat
* @return
* @throws PersistenceException
*/
public void initMonitor(Date start, Date stop, long repeat) throws PersistenceException
{
try
{
// time to start and repeat timer service
m_timerService.createTimer(start,repeat,KOMMAND);
// time to stop timer service
m_timerService.createTimer(stop,KOMMAND);
} catch(Exception ex)
{
throw new PersistenceException(ex.getMessage(),ex);
}
TLGen
179
StarData Gmb
V 2.8
}
/**
* Timer service method "stopMonitor()"
*/
public void stopMonitor()
{
for(Object obj : m_timerService.getTimers())
{
Timer timer = (Timer)obj;
String command = (String)timer.getInfo();
if(command.equals(KOMMAND))
{
timer.cancel();
}
}
}
}
/**
* Timer service method "timeoutMonitor()"
* @param timer
* @return
*/
@Timeout
public void timeoutMonitor(Timer timer)
{
String command = (String)timer.getInfo();
if(command.equals(KOMMAND))
{
m_callBack.checkEmails(this);
}
}
7.10 Web Service
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.server.persistence.soap;
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.jws.Web Service;
import com.tlgen.common.ejb.session.BaseSessionBean;
import com.tlgen.common.exception.PersistenceException;
import eu.stardata.demo.business.user.UserData;
import eu.stardata.demo.client.bci.soap.SoapBci;
/**
* This is a generate package for 'soap' for a Web Service
*/
@Stateless(name = SoapBci.JNDI_NAME, mappedName = "demo/"+SoapBci.JNDI_NAME+"/remote")
@Remote(SoapBci.class)
@Web Service(endpointInterface = "eu.stardata.demo.client.bci.soap.SoapBci", serviceName = "SoapSessionBeanService")
public class SoapSessionBean extends BaseSessionBean implements SoapBci {
// Session annotations and fields for local manager
@Inject
private CallBackWeb ServiceUserIf m_callBack;
/**
* Default Constructor
*/
public SoapSessionBean() {
super();
}
TLGen
180
StarData Gmb
V 2.8
// Session class methods
/**
* Session method "updateUser()"
* @param user
* @return
* @throws PersistenceException
*/
public UserData updateUser(UserData user) throws PersistenceException {
try {
return m_callBack.updateUser(user);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
/**
* Session method "retrieveUser()"
* @param name
* @return
* @throws PersistenceException
*/
public List<UserData> retrieveUser(String name) throws PersistenceException {
try {
return m_callBack.retrieveUser(name);
} catch(Exception ex) {
throw new PersistenceException(ex.getMessage(),ex);
}
}
}
7.11 REST-Klassen
7.11.1 Client Seite
/**
* **** do not change with a file editor *****
*/
package eu.stardata.test.rest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import junit.framework.TestCase;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.tlgen.common.rest.TlgListResponse;
import eu.stardata.demo.business.user.UserJSon;
import eu.stardata.demo.business.user.UserRoleJSon;
/**
* This is a transient file
* Session bean is a web service session bean for REST
*
* This is a test class derived from a JUnit,
* and is used to simplified the program develop and testing.
* This class is to changed.
TLGen
181
StarData Gmb
V 2.8
*/
public class TestRestUser extends TestCase
{
// Test class data fields
private final static int TIMEOUT = 30000;
private final static String CHARSET = "UTF-8";
private final static String REQ_PROP_CHARSET = "Accept-Charset";
private final static String REQ_PROP_CONTENT = "Content-Type";
private final static String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
/**
* Default Constructor
*/
public TestRestUser()
{
super();
}
// Test class methods
/**
* Test method "getHttpClient()"
* @param type
* @param strURL
* @param contenttype
* @param value
* @return
*/
protected java.lang.String getHttpClient(String type, String strURL, String contenttype, String value)
{
if(strURL != null && type != null)
{
try
{
URL url = new URL(strURL);
HttpURLConnection httpConnnection = (HttpURLConnection)url.openConnection();
httpConnnection.setDoOutput(true);
// set request method type: GET, POST, PUT, DELETE for REST and , HEAD, OPTIONS, TRACE
httpConnnection.setRequestMethod(type);
httpConnnection.setReadTimeout(TIMEOUT);
httpConnnection.setRequestProperty(REQ_PROP_CHARSET,CHARSET);
// set the contenttype
if(contenttype != null)
{
httpConnnection.setRequestProperty(REQ_PROP_CONTENT,contenttype);
}
if(type.equalsIgnoreCase("DELETE"))
{
httpConnnection.connect();
}
// set the content
else if(value != null)
{
// get the output stream writer and write the output to the server
OutputStreamWriter out = new OutputStreamWriter(httpConnnection.getOutputStream());
out.write(value);
out.close();
}
// read the response result from the server
BufferedReader reader = new BufferedReader(new InputStreamReader(httpConnnection.getInputStream()));
String line = null;
while((line = reader.readLine()) != null)
{
return line;
}
} catch (MalformedURLException e)
{
e.printStackTrace();
} catch (ProtocolException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
TLGen
182
StarData Gmb
V 2.8
}
}
return null;
}
/**
* Test method "testcreateUser()"
*/
public void testcreateUser()
{
try
{
System.out.println("----------- testcreateUser() -----------");
// Initialise input parameters
Gson gson0 = new GsonBuilder().setDateFormat(DATE_FORMAT).create();
UserJSon json0 = new UserJSon();
json0.setEmail("[email protected]");
json0.setPassWord("xyz");
json0.setFirstName("Cris");
json0.setUserName("user03");
json0.setLastName("Smith");
json0.setModifyDate(new Date(System.currentTimeMillis()));
fill the values for methods
json0.setProduct(eu.stardata.demo.business.product.ProductJSon);
UserRoleJSon role = new UserRoleJSon();
role.setUserRoleID(2L);
List<UserRoleJSon> list = new ArrayList<UserRoleJSon>();
list.add(role);
json0.setUserRole(list);
String strJSon = gson0.toJson(json0);
//
//
// REST call
String strResponse =
this.getHttpClient("POST","http://localhost:8080/rest/restApp/restSession/createUser","application/json",strJSon);
// print return data
if(strResponse != null)
{
System.out.println("strResponse :" + strResponse);
Type responseType = new TypeToken<UserJSon>(){}.getType();
UserJSon response = gson0.fromJson(strResponse, responseType);
if(response != null)
{
System.out.println("Ejb3Optlock :" + response.getEjb3Optlock());
System.out.println("Email
:" + response.getEmail());
System.out.println("PassWord :" + response.getPassWord());
System.out.println("FirstName :" + response.getFirstName());
System.out.println("UserID :" + response.getUserID());
System.out.println("UserName :" + response.getUserName());
System.out.println("LastName :" + response.getLastName());
System.out.println("ModifyDate :" + response.getModifyDate());
if(response.getUserRole() != null)
{
for(UserRoleJSon arg : response.getUserRole())
{
if(arg != null)
{
System.out.println(" RoleName :" + arg.getRoleName());
System.out.println(" Ejb3Optlock :" + arg.getEjb3Optlock());
System.out.println(" UserRoleID :" + arg.getUserRoleID());
System.out.println(" Description :" + arg.getDescription());
System.out.println(" ModifyDate :" + arg.getModifyDate());
}
}
}
}
}
else
{
System.out.println("ReturnObject is null !!!");
}
} catch(Exception ex)
{
ex.printStackTrace();
}
}
TLGen
183
StarData Gmb
V 2.8
/**
* Test method "testfetchUser()"
*/
public void testfetchUser()
{
try
{
System.out.println("----------- testfetchUser() -----------");
strContent,"application/json",null);
// REST call
String strContent = "/yyy-01";
String strResponse = this.getHttpClient("GET","http://localhost:8080/rest/restApp/restSession/fetchUser" +
// print return data
if(strResponse != null)
{
System.out.println("Response :" + strResponse);
// make the response type
Type responseType = new TypeToken<TlgListResponse<UserJSon>>(){}.getType();
// deserialize the response object
Gson gson = new GsonBuilder().setDateFormat(DateFormat.LONG).create();
TlgListResponse<UserJSon> response = gson.fromJson(strResponse, responseType);
if(response != null && response.getResult() != null)
{
for(UserJSon object : response.getResult())
{
System.out.println("Ejb3Optlock :" + object.getEjb3Optlock());
System.out.println("Email
:" + object.getEmail());
System.out.println("PassWord :" + object.getPassWord());
System.out.println("FirstName :" + object.getFirstName());
System.out.println("UserID :" + object.getUserID());
System.out.println("UserName :" + object.getUserName());
System.out.println("LastName :" + object.getLastName());
System.out.println("ModifyDate :" + object.getModifyDate());
System.out.println("Product :" + object.getProduct());
if(object.getUserRole() != null)
{
for(UserRoleJSon arg : object.getUserRole())
{
if(arg != null)
{
System.out.println(" RoleName :" +
arg.getRoleName());
System.out.println(" Ejb3Optlock :" +
arg.getEjb3Optlock());
System.out.println(" UserRoleID :" +
arg.getUserRoleID());
System.out.println(" Description :" +
arg.getDescription());
System.out.println(" ModifyDate :" +
arg.getModifyDate());
}
}
}
}
}
}
else
{
}
System.out.println("ReturnObject is null !!!");
}
} catch(Exception ex)
{
ex.printStackTrace();
}
/**
* Test method "testcountUsers()"
*/
public void testcountUsers()
{
try
{
System.out.println("----------- testcountUsers() -----------");
TLGen
184
StarData Gmb
V 2.8
String strContent = "?name=xxx-01";
// REST call
String strResponse = this.getHttpClient("GET","http://localhost:8080/rest/restApp/restSession/countUsers" +
strContent,"application/json",null);
// print return data
if(strResponse != null)
{
System.out.println("strResponse :" + strResponse);
}
else
{
System.out.println("ReturnObject is null !!!");
}
} catch(Exception ex)
{
ex.printStackTrace();
}
}
/**
* Test method "testdeleteUser()"
*/
public void testdeleteUser()
{
try
{
System.out.println("----------- testdeleteUser() -----------");
// REST call
String strContent = "/4";
String strResponse = this.getHttpClient("DELETE","http://localhost:8080/rest/restApp/restSession/deleteUser" +
strContent,"application/x-www-form-urlencoded",null);
}
// print return data
if(strResponse != null)
{
System.out.println("strResponse :" + strResponse);
}
else
{
System.out.println("ReturnObject is null !!!");
}
} catch(Exception ex)
{
ex.printStackTrace();
}
/**
* Test method "testupdateUser()"
*/
public void testupdateUser()
{
try
{
System.out.println("----------- testupdateUser() -----------");
Gson gson0 = new GsonBuilder().setDateFormat(DATE_FORMAT).create();
UserJSon json0 = new UserJSon();
json0.setUserID(3L);
json0.setEmail("[email protected]");
json0.setPassWord("xyz-abc");
json0.setFirstName("John");
json0.setUserName("user-update");
json0.setLastName("Johnson");
json0.setModifyDate(new Date(System.currentTimeMillis()));
UserRoleJSon role = new UserRoleJSon();
role.setUserRoleID(2L);
List<UserRoleJSon> list = new ArrayList<UserRoleJSon>();
list.add(role);
json0.setUserRole(list);
String strJSon = gson0.toJson(json0);
// REST call
TLGen
185
StarData Gmb
V 2.8
String strResponse =
this.getHttpClient("PUT","http://localhost:8080/rest/restApp/restSession/updateUser","application/json",strJSon);
// print return data
if(strResponse != null)
{
System.out.println("strResponse :" + strResponse);
}
else
{
System.out.println("ReturnObject is null !!!");
}
} catch(Exception ex)
{
ex.printStackTrace();
}
}
}
7.11.2 Server Seite
Für Interface siehe 7.5.4
/**
* **** do not change with a file editor *****
*/
package eu.stardata.demo.server.persistence.rest;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import org.jboss.resteasy.annotations.cache.NoCache;
import com.tlgen.common.ejb.session.BaseSessionBean;
import com.tlgen.common.rest.TlgListResponse;
import eu.stardata.demo.business.user.UserJSon;
import eu.stardata.demo.server.rest.CallBackRest;
/**
* This is a transient file
* Session bean is a web service session bean for REST
*
* A session bean encapsulates business logic that can be invoked programmatically
* by a client over local, remote, or web service client views.
*/
@Stateless(name = RestSession.JNDI_NAME)
@LocalBean
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@NoCache
public class RestSessionBean extends BaseSessionBean implements RestSession {
// Session annotations and fields for local manager
@EJB
private CallBackRest m_callBack;
/**
* Default Constructor
*/
public RestSessionBean() {
super();
}
// Session class methods
/**
* Session method "fetchUser()"
TLGen
186
StarData Gmb
V 2.8
* @param name
* @return
* @throws Exception
*/
public TlgListResponse<UserJSon> fetchUser(String name) throws Exception {
try {
return m_callBack.fetchUser(name);
} catch(Exception ex) {
throw new Exception(ex.getMessage(),ex);
}
}
/**
* Session method "createUser()"
* @param user
* @return
* @throws Exception
*/
public UserJSon createUser(UserJSon user) throws Exception {
try {
return m_callBack.createUser(user);
} catch(Exception ex) {
throw new Exception(ex.getMessage(),ex);
}
}
/**
* Session method "countUsers()"
* @param name
* @return
* @throws Exception
*/
public long countUsers(String name) throws Exception {
try {
return m_callBack.countUsers(name);
} catch(Exception ex) {
throw new Exception(ex.getMessage(),ex);
}
}
/**
* Session method "deleteUser()"
* @param userId
* @return
* @throws Exception
*/
public String deleteUser(long userId) throws Exception {
try {
return m_callBack.deleteUser(userId);
} catch(Exception ex) {
throw new Exception(ex.getMessage(),ex);
}
}
/**
* Session method "updateUser()"
* @param user
* @return
* @throws Exception
*/
public UserJSon updateUser(UserJSon user) throws Exception {
try {
return m_callBack.updateUser(user);
} catch(Exception ex) {
throw new Exception(ex.getMessage(),ex);
}
}
}
7.12 Message Driven Bean
package eu.stardata.server.message.chat;
TLGen
187
StarData Gmb
V 2.8
import javax.annotation.Resource;
import javax.jms.Message;
import javax.jms.JMSException;
import javax.jms.ConnectionFactory;
import javax.jms.ObjectMessage;
import javax.ejb.ActivationConfigProperty;
import javax.jms.BytesMessage;
import javax.jms.Connection;
import com.tlgen.common.ejb.message.BaseMessageBean;
import eu.stardata.client.test.CallBackServerMessage;
import javax.jms.MessageProducer;
import javax.jms.TextMessage;
import javax.jms.Session;
import javax.jms.Topic;
import java.io.Serializable;
import javax.jms.MessageListener;
import javax.ejb.MessageDriven;
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType",
propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination",
propertyValue = "queue/queueA"),
@ActivationConfigProperty(propertyName = "messageSelector",
propertyValue = "MessageFormat = 'TestMessage'"),
@ActivationConfigProperty(propertyName = "acknowledgeMode",
propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "subscriptionDurability",
propertyValue = "NonDurable")})
public class TestMessageBean extends BaseMessageBean
implements MessageListener {
private static final long serialVersionUID = 73342617;
// Manager class data fields
@Resource(mappedName = "ConnectionFactory")
public ConnectionFactory m_factory = null;
@Resource(mappedName = "topic/topicA")
public Topic m_connect = null;
// Message class methods
/**
* Message method "onMessage()"
* @param message
* @return
*/
public void onMessage(Message message) {
try {
CallBackServerMessage callBack =
new CallBackServerMessage();
Object backObject = callBack.callBackChat(message);
// send back to the client the result from the call back class
if(m_factory != null && m_connect != null) {
Connection connect = m_factory.createConnection();
Session session = connect.createSession(false,
Session.AUTO_ACKNOWLEDGE);
MessageProducer sender = session.
createProducer(m_connect);
// make message receive object
if(backObject instanceof String) {
TextMessage textMessage = session.
createTextMessage();
textMessage.setText((String)backObject);
sender.send(textMessage);
}
else if(backObject instanceof byte[]) {
BytesMessage bytesMessage = session.
createBytesMessage();
bytesMessage.writeBytes((byte[])backObject);
sender.send(bytesMessage);
}
else {
ObjectMessage objMessage = session.
createObjectMessage();
objMessage.setObject((Serializable)backObject);
TLGen
188
StarData Gmb
V 2.8
sender.send(objMessage);
}
connect.close();
}
}
} catch(JMSException ex) {
ex.printStackTrace();
}
}
TLGen
189
StarData Gmb
V 2.8
8 Vergleich zwischen TLGen und andere Code-Generatoren
EJB (Enterprise Java Beans) sind standardisierte Komponente innerhalb eines Applikation
Servers, mit dem Ziel, komplexe, mehrschichtige sowie verteilte Software Systeme mit der
Programmiersprache Java zu vereinfachen.
Die erste Spezifikation von EJB wurde von IBM im Jahr 1997 durchgeführt und von Sun Microsystems mit der Bezeichnung EJV 1.0 und 1.1 angenommen. Kurz danach erschienen die
ersten Applikation Server „WebSphere“ von IBM und „WebLogic“ von BEA auf dem Markt.
Das EJB-Konzept sollte die Softwareentwicklung von komplexen verteilten Applikationen stark
vereinfachen. Das ist aber nur teilweise gelungen, da der persistente Teil (auf Basis von Entity
Beans) erhebliche Performance-Verluste verbuchte. Aus diesem Grund sind eine Reihe von
Applikationen als „Verbesserungs-Tools“ entwickelt worden, hauptsächlich um diesen Zustand,
zu korrigieren.
Version 2 von EJB verbessert diesen Zustand wesentlich, eine bessere Performance ist vorhanden. Aber geblieben ist eine gewisse Schwierigkeit durch sehr komplexe und aufwendig zu
entwickelnde XML Dateien, notwendig für das Deployment von Applikation. Als Hilfe dafür ist
das Tool „XDoclet“ gedacht, welches mit Hilfe von eigenen Tags relativ einfach diese komplexe
XML Dateien generiert.
Ab Version 3.0 und 3.1 von EJB sind alle Probleme von EJB sehr gut gelöst worden. Eine vernünftige Verwendung der Annotationen (neue Features von Java) lässt die komplette
Generierung des notwendigen Java Codes, nur auf Basis von Domainmodell oder Datenmodell,
zu. Die Generierungssteuerung (die nicht sehr umfangreich ist) übernimmt eine Konfigurationsdatei.
Tools wie Hibernate sind für EJB 3 eigentlich nicht mehr notwendig, sie verkomplizieren sogar
die gesamte Applikation. Diese Applikationen bergen folgende Nachteile:

Die Applikation muss in der Running Zeit diese Tools in der Applikation einbeziehen:
o
das verkompliziert die Applikation
o
veranlasst eine Tool-Versions-Abhängigkeit sowie
o
Miteinbeziehung der Tool-Fehler

Verwendet eine extra Code-Schicht als von EJB3 vorgesehen ist

All diese Tools bringen nicht eine komplette neue Lösung in der Verwendung von
Datenbanken mit sich, sondern sind nur eine Extraschicht für einen Applikation Server,
um die Entwicklung mit allen diesen Nachteilen zu erleichtern. Eine reine Nutzung von
EJB3 ohne zusätzliche Tools (wie z.B. Hibernate, Toplink, etc.) ist im direkten Vergleich
zur Tool-Nutzung immer im Vorteil (siehe auch Anhang 1 - folgt in Kürze).
Die Verwendung der Tools (wie z.B. Hibernate, TopLink, iBatis, etc.) mit einem EJB3 Applikation Server ist weder erforderlich noch empfehlenswert, es verkompliziert nur das IT-Programm ohne dabei Vorteile zu erbringen. So ein Tool ist nur für kleine Applikationen, die keinen
Applikation Server benötigt, zu gebrauchen.
TLGen
190
StarData Gmb
V 2.8
In Gegensatz zu diesen Tools bringt TLGen durch eine komplette Generierung des notwendigen Java Codes eine wesentliche Vereinfachung in der Verwendung von EJB3, so dass sich
die Entwicklung nur auf die Fachlogik einer Applikation konzentrieren kann. Die Verwendung
von TLGen bringt folgende Vorteile:

Komplette Code-Generierung: Test-Klassen, Client Technische-Klassen, Session
Beans, Entity Manager, Entity Beans, „persistence.xml“ Dateien, DatenKlassen/Interfaces und Interceptor-Klassen.

TLGen beteiligt sich nicht bei der Applikation in Running Zeit, d. h. keine Abhängigkeit
von der TLGen Version.

Der von TLGen generierte Code hat das gleiche Layout wie der Code, welcher ein
Programmierer selber schreiben könnte.

Durch die sofortige Code-Generierung mit Test-Klassen, können die Designer und
Architekten die Ergebnisse von Konzepten sofort ersehen und eventuell optimieren
(siehe Kap. 2).
TLGen
191
StarData Gmb
V 2.8
9 Literaturhinweis
1. “JSR 317: JavaTM Persistence API, Version 2.0”, EJB3 Persistence Specification
2. “JSR 318: Enterprise JavaBeansTM,Version 3.1” EJB3 Specification
3. “Enterprise JavaBeans 3.1 Eistig, Umstig, Paxis und Referenz” von Uwe Rozanski
4. „Java Web Services“ von Friedrich Kiltz
5. „Maven 3 Konfigurationsmanagement mit Java“ von Martin Spiller
TLGen
192
StarData Gmb
V 2.8
10 Glossar




TLGen
EJB
REST
SOAP
Web Service
Enterprise Java Beans
Representational state transfer
Simple Object Access Protocol
Ist eine Methode zu Kommunizieren in „World Wide Web“
193
StarData Gmb
Herunterladen