konzeption und implementierung des sicherheitskonzepts in ... · interaktion zwischen jsp und...
TRANSCRIPT
Technische Universitat BerlinFakultat IV: Elektrotechnik und InformatikINSTITUT FUR WIRTSCHAFTSINFORMATIK
FACHGEBIET SYSTEMANALYSE UND EDV
Diplomarbeit
Wintersemester 2004/2005
Konzeption und Implementierung
des Sicherheitskonzepts in einem
Net Business Tool
Verfasser: Bassem El-AhmadMatrikelNr: 181794Studiengang: Technische Informatikemail: [email protected]
letzte Anderung: 3. Januar 2005
Gutachter: Prof. Dr. KrallmanBetreuer: Dipl.-Kfm. Marian Scherz
Die selbstandige und eigenhandige Anfertigung versichere ich an Eides statt.
Berlin,den 3. Januar 2005
Unterschrift
Danksagung
Ich mochte mich bei allen bedanken, die mich wahrend meines Studiums unterstutzt
haben, besonders bei meinem Diplomarbeitsbetreuer Dipl.-Kfm. Marian Scherz, der
viel Geduld aufbringen mußte.
Mein großter Dank gilt meiner Mutter, die mir das Studium ermoglicht und mich
auch zu jeder Zeit unterstutzt hat.
3
Inhalt
1. Einleitung 10
1.1. Gliederung der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2. Einleitung zum Net Business Tool 12
2.1. Hintergrund zum Sicherheitskonzept . . . . . . . . . . . . . . . . . . 13
2.2. Zweck des Sicherheitskonzepts . . . . . . . . . . . . . . . . . . . . . . 13
2.3. Anforderungen an Benutzer des Admin Tools . . . . . . . . . . . . . . 13
3. Modellierung und Entwurf 15
3.1. Einfuhrung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2. UML Modellierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2.1. Anwendungsfalldiagramm . . . . . . . . . . . . . . . . . . . . 17
3.2.2. Klassendiagramm . . . . . . . . . . . . . . . . . . . . . . . . 18
3.2.3. Sequenzdiagramm . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2.4. Aktivitatsdiagramm . . . . . . . . . . . . . . . . . . . . . . . 21
3.3. Datenbank Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4. Angewandte Technologien 23
4.1. Enterprise JavaBeans . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.1.1. Der EJB-Server . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.1.2. Der EJB-Container . . . . . . . . . . . . . . . . . . . . . . . . 25
4.1.3. Das EJBHome-Interface . . . . . . . . . . . . . . . . . . . . . 26
4.1.4. Das EJBObjekt-Interface . . . . . . . . . . . . . . . . . . . . . 28
4.1.5. Enterprise JavaBeans Typen . . . . . . . . . . . . . . . . . . . 29
4.1.6. Session Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.1.7. Der Zugriff auf eine Session-Bean . . . . . . . . . . . . . . . . 32
4
4.1.8. Entity Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.2. Java Servlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.3. Java Server Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.3.1. Elemente einer JSP-Seite . . . . . . . . . . . . . . . . . . . . . 39
4.3.2. Direktiven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.3.3. Aktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.3.4. Scripting Elemente . . . . . . . . . . . . . . . . . . . . . . . . 41
4.3.5. Implizite Objekte einer JSP Seite . . . . . . . . . . . . . . . . 42
4.3.6. Gultigkeitsbereiche von Objekten . . . . . . . . . . . . . . . . 42
4.3.7. Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.3.8. Tag-Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.3.9. Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.4. Code Generation mit XDoclet . . . . . . . . . . . . . . . . . . . . . . 48
4.4.1. Was ist XDoclet? . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.4.2. XDoclet und J2EE . . . . . . . . . . . . . . . . . . . . . . . . 51
4.4.3. Beispiel EJB mit XDoclet . . . . . . . . . . . . . . . . . . . . 52
4.4.4. Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.5. JBoss Application Server . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.5.1. Deployment unter JBoss . . . . . . . . . . . . . . . . . . . . . 54
5. Implementierung 55
5.1. UsersBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.2. GroupsBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.3. PagesBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.4. Anbindung an die Datenbank . . . . . . . . . . . . . . . . . . . . . . 62
5.5. Admin Tool Web-Interface . . . . . . . . . . . . . . . . . . . . . . . . 62
6. Admin Tool Benutzerhandbuch 65
6.1. Authentifizierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
6.2. User Verwaltung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
6.2.1. List all user . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
6.2.2. Create user . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
6.2.3. Reset password . . . . . . . . . . . . . . . . . . . . . . . . . . 68
6.2.4. Update User . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
6.2.5. Delete user . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.2.6. Show user groups . . . . . . . . . . . . . . . . . . . . . . . . . 70
5
6.3. Groups verwalten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
6.3.1. List all groups . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
6.3.2. Create group . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
6.3.3. Add user to group . . . . . . . . . . . . . . . . . . . . . . . . 71
6.3.4. Delete group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
6.3.5. Delete user from group . . . . . . . . . . . . . . . . . . . . . . 72
6.3.6. Add sub-group . . . . . . . . . . . . . . . . . . . . . . . . . . 72
6.3.7. Delete sub-group . . . . . . . . . . . . . . . . . . . . . . . . . 72
6.4. PLP Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
A. Anhang 75
A.1. GroupsBean.Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
A.2. UsersBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
A.3. PagesBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Literaturverzeichnis 125
6
Abbildungsverzeichnis
3.1. Admin Tool UML Anwendungsfalldiagramm . . . . . . . . . . . . . . 18
3.2. Admin Tool Klassendiagramm . . . . . . . . . . . . . . . . . . . . . . 19
3.3. Die unterschiedlichen Datenbank Tabellen . . . . . . . . . . . . . . . 22
4.1. Die EJB-Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.2. Die Beziehung Zwischen EJB-Server und EJB-Container . . . . . . . 25
4.3. Client-Schnittstelle einer EJB . . . . . . . . . . . . . . . . . . . . . . 26
4.4. EJB-Typen in EJB-Version 2.0 . . . . . . . . . . . . . . . . . . . . . 30
4.5. Zugriff auf eine Session-Bean . . . . . . . . . . . . . . . . . . . . . . . 33
4.6. Die verschiedenen Stufen bei der Ausfuhrung eines Servlets . . . . . . 36
4.7. Die verschiedenen Stufen bei der Ausfuhrung eines Servlets . . . . . . 39
4.8. XDoclet Ablauf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.1. Die Hauptpackages . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.2. UsersBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.3. GroupsBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
5.4. PagesBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.5. Web infterface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
6.1. Authentifizierung Prozess . . . . . . . . . . . . . . . . . . . . . . . . 65
6.2. Login Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
6.3. Hauptansicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
6.4. Liste aller verfuegbaren User . . . . . . . . . . . . . . . . . . . . . . . 67
6.5. Create new user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
6.6. Update user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.7. Delete user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.8. List All Gropus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
7
6.9. Add new group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
6.10. Delete group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
6.11. PLP Security Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
6.12. PLP Managegroups . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
8
Tabellenverzeichnis
4.1. Implizite Objekte einer JSP-Seite . . . . . . . . . . . . . . . . . . . . 41
4.2. Gultigkeitsbereiche von Objekten einer JSP-Seite . . . . . . . . . . . 43
9
1. Einleitung
Diese Arbeit handelt von einem Admin Tool fur die Realisierung eines Sicherheits-
konzeptes fur das NBT 1. Zur Realisierung gehort unter anderem die Integration in
das vorhandene PLP2 Tool. Weiterhin wird eine Webanwendung mit JSP’s und EJB
ermoglicht. Mit Hilfe vom NBT Tool werden die Benutzer in Gruppen verwaltet und
ihnen bestimmte Rechte zugewiesen.
Es gibt drei Arten von Benutzern (Admin User, Group User und Guest User). Der Ad-
min User verfugt uber alle moglichen Rechte, wie z.B. anlegen, loschen und verandern
von Usern und Gruppen. Dagegen hat der Super User weniger Rechte als der Admin
User, er darf Veranderungen an den einzelnen Usern vornehmen, sie jedoch nicht
loschen. Zuletzt hat der Guest User nur eingeschrankte Moglichkeiten und darf nur
seine eigenen Informationen verandern.
Das Sicherheitstool stellt bestimmten Usern HTML Elemente im LRP Tool zur
Verfugung, dabei ist die Anzeige abhangig vom eingeloggten User in der zugehorigen
Gruppe. Demnach werden Elemente angezeigt bzw. versteckt.
Das Tool gliedert sich in die drei Hauptbereiche Usermanager, Groupmanager und
Pagemanager. Im Usermanager werden alle Funktionalitaten fur die Verwaltung der
Benutzer implementiert. Der Gruppenmanager untergliedert sich in Groups und Sub-
groups, dabei werden im Bereich Groups die zugehorigen Rechte der Gruppe auf den
User ubertragen bzw. ihm entzogen, wenn der User aus der Gruppe ausscheidet, da-
gegen ist die Subgroup eine Untergruppe von Groups, d.h. sie erbt alle Rechte der
Oberklasse Groups. Der Pagemanager wird fur die Verwaltung der einzelnen Projekte
und HTML Elemente benotigt.
Zusatzlich wird eine PostgreSQL-Datenbank zur Verwaltung der Daten aufgebaut.
Dafur werden Tabellen fur die Bereiche Gruppen, Users und Elemente angelegt.
1Net Business Tool:http://venus.cs.tu-berlin.de/2PRESENTATION LAYER PRODUCER:http://venus.cs.tu-berlin.de/
10
1.1. Gliederung der Arbeit 11
1.1. Gliederung der Arbeit
Als erstes werden die Sicherheitsanforderungen and das NBT Admin Tool im Kapi-
tel 2 vorgestellt. Dabei werden die Sicherheitsaspekte fur Webapplikationen in den
Vordergrund gestellt, diskutiert und analysiert. Dazu werden Anforderungen und
Strategien sowie der Ablauf dargestellt.
In Kapitel 3 erfolgt eine Kurzbeschreibung der Modellierungssprache UML. Es wer-
den bestimmte Modellierungsmethoden zur Konzeptbeschreibung verwendet. Die ver-
schiedenen Usecases, Klassendiagramme sowie das Datenbankschema kommen durch
spezifische Beschreibung zur Geltung. Die einzelnen Diagramme dienen als Bausteine
zur Realisierung der Implementierungen.
Die angewandten Technologien (EJB, Servlets, JSP, JBOSS und XDoclet) werden in
Kapitel 4 beschrieben. Dazu gehort ein kleiner Exkurs in die Technologien, die wie-
derum auf die Problematik der Diplomarbeit abgestimmt werden. Zusatzlich werden
Definitionen und Grundkenntnisse in den einzelnen Technologien erlautert. Weiterhin
werden die Moglichkeiten und deren Anwendungsmoglichkeiten untereinander darge-
stellt und angewendet.
Kapitel 5 beshreibt die vollstandige Implemtentierung der einzelnen Funktionalitaten,
wie z.B. UserBean, GroupBean und PagerBean. In UserBean werden Funktiona-
litaten zur Verwaltung und Erzeugung von Usern implementiert. Die GroupBean
Klasse ermoglicht das Einbinden erzeugter User durch UserBean in verschiedene
Gruppen zuzuordnen. Hingegen der Benutzerverwaltungen und Gruppenrechtzuwei-
sungen beschreibt PagerBean die Verwaltung der einzelnen Projekte und HTML Ele-
mente. Die Datenbankkonfiguration, die Interaktion zwischen Servlets und EJB’s, die
Interaktion zwischen JSP und Servlets und die Realisierung des Web-Interfaces zum
Admin Tool werden implementiert.
Ein Benutzerhandbuch in Kapitel 6 dient fur die Schritt fur Schritt Benutzung des
Admin Tools, das durch Grafikelemente die Navigation auf der Applikation erleich-
tert. Auszuge aus der User- und Gruppenverwaltung dienen als Demo.
2. Einleitung zum Net Business Tool
Das Net Business Tool (NBT) ist ein generisches, komponentenbasiertes, plattform-
und gerateunabhangiges Framework auf Basis offener Quelltexte (Open Source). Die-
ses Framework ubernimmt die Aufgaben der Komponentenverwaltung und -verteilung.
Mit wenigen Operationen konnen mit dem NBT innerhalb weniger Minuten Websei-
ten erstellt werden. Der Webgenerator kann dabei an individuelle Anforderungen
angepasst werden (Customizing).
Ziel des NBT ist die Verschmelzung von Struktur- und Layout innerhalb des HTML-
Codes so zu separieren, dass hierarchische Strukturen und logische Abhangigkeiten
zwischen den verschiedenen HTML-Objekten definiert werden konnen. Das NBT
verwaltet ein Projekt mit samtlichen Bestandteilen einer zu erstellenden Website in
einer Datenbank.
Die Inhalte dieser Tabellen werden beim abschließenden Generierungslauf in XML
Befehle ubersetzt. Grundgedanke der Software ist die Trennung von Layout und
eigentlichem Inhalt (Texte, Bilder, Multimedia, etc.). Das Erstellen von Stylesheets,
die im NBT uber Bausteine direkt oder als Datei eingebunden werden, gibt eine
zusatzliche Moglichkeit, das Webdesign professionell zu gestalten1.
Das NBT soll in Anwendungsbereichen wie Internet- und Intranet-Applikationen,
eBusiness sowie Geschaftsautomatisierung als plattformunabhangiges Werkzeug sei-
ne Funktionalitat zur Verfugung stellen. Zur Umsetzung der Plattformunabhangigkeit
ist das NBT in Java geschrieben und benotigt zur Ausfuhrung lediglich eine instal-
lierte Java VM und einen Browser, der Java uneingeschrankt unterstutzt.
1Net Business Tool:http://venus.cs.tu-berlin.de/
12
2.1. Hintergrund zum Sicherheitskonzept 13
2.1. Hintergrund zum Sicherheitskonzept
Immer mehr Anwendungen laufen auf einer Internet basierenden Technik, so auch
geschaftskritische Anwendungen. Das Internet stellt jedoch eine offene Plattform dar,
so dass der Sicherheitsgedanke fest mit der Anwendung verankert werden muss.
Spatestens beim Aufbau Internet basierender Geschaftsmodelle, zum Beispiel (e-
Business) oder beim Thema Fernwartung ist die Etablierung stabiler und verifizier-
barer Sicherheitskonzepte unumganglich. Nicht nur, dass der Gesetzgeber heute ein
Management der Sicherheit (Risikomanagement) fordert, der Fortbestand einer Un-
ternehmung hangt ganz entscheidend von der Wahrung der Unternehmensgeheimnis-
se ab. Dies betrifft sowohl Benutzerdaten mit ihren Rechten als auch den Entwick-
lungsstand von zukunftigen Produkten und Dienstleistungen. Je nach Tatigkeitsfeld
sind verschiedene Informationen von unterschiedlicher Wichtigkeit und Bedeutung.
Grundlage fur eine Webanwendung bzw. Security-Losung ist eine Risikoanalyse, in
der mogliche Schwachstellen und Bedrohungen untersucht werden und wie mogliche
Angriffe darauf gestartet werden konnen. Nach der Bewertung, welchen Schaden diese
Angriffe anrichten konnen, werden geeignete Praventivmaßnahmen untersucht. Aus-
gehend von dieser Risikoanalyse, wird festgestellt, welche Sicherheitsmangel bestehen
und welche Gefahren daraus entstehen konnen.
2.2. Zweck des Sicherheitskonzepts
Sicherheitsaspekte spielen eine zentrale Rolle in Webapplikationen. Als Grundlage
fur eBusiness-Strategien muss sichergestellt werden, dass Informationen nicht jedem
zuganglich sind, d.h. nicht jeder Benutzer ist befugt jede Information zu erhalten.
Daher mussen Einschrankungen vorgenommen werden um die Sicherheit und Pri-
vatsphare jedes einzelnen zu schutzen und zu garantieren.
2.3. Anforderungen an Benutzer des Admin Tools
Das Sicherheitskonzept innerhalb des Admin Tools muss die Verwaltung und Se-
parierung der Informationen gewahrleisten. Dabei werden bestimmte Zugriffsrechte
den Usern durch Gliederung in bestimmten Gruppen auferlegt. Nicht jeder User hat
2.3. Anforderungen an Benutzer des Admin Tools 14
damit die Moglichkeiten bestimmte Elemente sowie Projekte zusehen, d.h. der be-
stimmte User sieht nur fur ihn zugelassene Elemente. Die einzelnen User konnen ihre
eigenen Daten andern, aber sich nicht aus der Datenbank loschen. Hingegen diesen
Bestimmungen darf der Admin alle Operationen fur einen User vornehmen und den
Benutzer somit aus der Datenbank loschen, verandern oder neu anlegen.
Die Gliederung der User in einzelne Gruppen ermoglicht ihnen bestimmte Funktiona-
litaten auszufuhren. Es gibt drei Arten von Usergruppen (Admingroup, Supergroup,
Anonymousgroup). Die Admingruppe verfugt uber alle Rechte im Tool. Dagegen
verfugt ein Supergroup User uber mehr Rechte als ein Guest bzw. Anonymous User.
Jedoch konnen die User nur bestimmte Elemente bzw. Projekte sehen, die im Ver-
bund mit ihnen stehen.
3. Modellierung und Entwurf
3.1. Einfuhrung
Die Unified Modelling Language (UML) hat sich in den letzten Jahren als stan-
dardisierte Modellierungssprache fuer Softwareprodukte durchgesetzt. Die Darstel-
lung und Modellierung erfolgt mit verschiedenen Diagrammen, die unterschiedliche
Aspekte des Systems beleuchten.1 Diese sind beispielsweise die gewuenschten An-
wendungsfaelle (sogenannte use cases), Klassendiagramme (classdiagrams) oder Se-
quenzdiagramme (sequence diagrams). Letztere beschreiben die Kommunikation ver-
schiedenener Klassen untereinander. Ein UML-Modell besteht aus mehreren dieser
Diagramme, die in ihrer Gesamtheit ein Softwareprodukt moglichst vollstandig mo-
dellieren sollen.2
Die Erstellung solcher Dokumente geschieht meist mit Softwareentwicklungswerkzeu-
gen (engl. CASE-Tools). Bekannte Vertreter sind hier Rational Rose3 und Together
ControlCenter4. Diese Werkzeuge dienen meist nicht nur zur Erstellung der Diagram-
me, sondern helfen dem Softwareentwickler auch bei der Erstellung des Sourcecodes
und der Dokumentation.
Viele CASE-Tools bieten inzwischen das sogenannte Roundtrip-Engineering. Darun-
ter versteht man die Moglichkeit, sowohl mit Diagrammen als auch mit dem eigent-
lichen Sourcecode zu arbeiten.5Anderungen in einem der beiden Teile werden auto-
matisch im anderen Teil nachgefuhrt. Dabei ist die Generierung von Diagrammen
aus bereits bestehendem Sourcecode ebenfalls moglich. Diese Werkzeuge entwickeln
sich zunehmend zu Werkzeugen fur den gesamten Softwareentwicklungszyklus. So
1Alhir (2003)2Eine recht umfangreiche Ubersicht findet sich unter http://www.jeckle.de/unified.htm3http://www.rational.com4http://www.togethersoft.com5Balzert (2001)
15
3.2. UML Modellierung 16
gibt es Programme, die automatisch Tests durchfuhren konnen und aus Testlaeufen
Sequenzdiagramme erzeugen.
Selten wird ein Softwareprodukt nur von einer Person entworfen und programmiert.
Die Arbeit in Entwicklungsteams stellt somit den Regelfall dar. Softwareentwick-
lungswerkzeuge bieten auch hier einige Hilfswerkzeuge zur Teamarbeit an, die das
gemeinsame Arbeiten an Dokumenten ermoglichen. Dazu gehort neben der Verwal-
tung von Revisionen und Varianten auch das Softwarekonfigurationsmanagement.
Eine Vielzahl der Softwareentwicklungsprozesse arbeiten iterativ. Diese Iterationen
konnen dabei verschiedene Formen annehmen, auch eine Ueberlappung ist moeg-
lich. Es lasst sich jedoch allgemein feststellen, dass die standige Uberarbeitung und
Korrektur der Entwurfsdokumente und Sourcecodes eine Vielzahl von verschiedenen
Versionen produziert. Betrachtet man zusatzlich die Moglichkeit aus vorhandenen
Programmen Diagramme generieren zu konnen (durch Reverse- Engineering oder
Testlaufe), so nimmt die Anzahl der Diagramme weiter zu. Diese Diagramme bein-
halten viele wertvolle Informationen uber den Entwicklungsprozess.
3.2. UML Modellierung
1. Was ist die UML?
Unified Modelling Language ist eine Sprache zur Spezifikation, Visualisierung,
Konstruktion und Dokumentation von Modellen fur Softwaresysteme, Geschafts-
modelle und andere Nicht-Softwaresysteme. Sie bietet den Entwicklern die
Moglichkeit, den Entwurf und die Entwicklung von Softwaremodellen auf ein-
heitlicher Basis zu diskutieren. Die UML wird seit 1998 als Standard angese-
hen.6 Sie lag und liegt weiterhin bei der Object Management Group (OMG)
zur Standardisierung vor.
2. Wer steht hinter der UML?
Entwickelt wurde die UML von Grady Boch, Ivar Jacobsen und Jim Rum-
baugh von RATIONAL ROSE SOFTWARE . Sie kombinierten die besten Ide-
en objektorientierter Entwicklungsmethoden und schufen daraus”UML“. Vie-
le fuhrende Unternehmen der Computerbranche (Microsoft, Oracle, Hewlett-
6Objektorientierter Softwareentwurf mit UML Bannert:1999
3.2. UML Modellierung 17
Packard,...) wirkten aktiv an der Entwicklung mit und unterstutzen die UML.
3. Warum ist die UML keine Methode?
Die UML ist keine Methode. Sie ist lediglich ein Satz von Notationen zur For-
mung einer allgemeinen Sprache zur Softwareentwicklung. Eine Methode bein-
haltet Empfehlungen zur Vorgehensweise bei Entwicklungsprozessen. Um UML
erfolgreich zu nutzen, ist es notwendig eine passende Methode zu entwickeln,
die die UML unterstutzt.7
Die Modellelemente der UML werden nach Diagrammtypen gegliedert:
• Anwendungsfalldiagramm
• Klassendiagramm
• Aktivitatsdiagramm
• Kollaborationsdiagramm
• Sequenzdiagramm
• Zustandsdiagramm
• Komponentendiagramm
• Einsatzdiagramm
3.2.1. Anwendungsfalldiagramm
• Definition:
Ein Anwendungsfalldiagramm besteht aus einer Menge von Anwendungsfallen und
stellt die Beziehungen zwischen Akteuren und Anwendungsfallen dar. Es zeigt das
außerlich erkennbare Systemverhalten aus der Sicht eines Anwenders.
7Alhir (2003)
3.2. UML Modellierung 18
Abbildung 3.1.: Admin Tool UML Anwendungsfalldiagramm
• Beschreibung:
Ein Anwendungsfalldiagramm beschreibt die Zusammenhange zwischen verschiede-
nen Anwendungsfallen untereinander und zwischen Anwendungsfallen und den be-
teiligten Akteuren. Es zeigt die Struktur und Zusammenhange von verschiedenen
Geschaftsvorfallen und wie mit ihnen verfahren wird. Die drei wichtigsten Akteure
im Admin Tool sind Guest, Super und Admin User. Abbildung 3.1 beschreibt die
Interaktionen zwischen den verschiedenen Anwendungsfallen.
3.2.2. Klassendiagramm
• Definition:
Eine Klasse ist eine Menge von Objekten, in der die Eigenschaften (Attribute), Ope-
rationen und die Semantik der Objekte definiert werden. Alle Objekte einer Klasse
entsprechen dieser Festlegung.
3.2. UML Modellierung 19
Abbildung 3.2.: Admin Tool Klassendiagramm
3.2. UML Modellierung 20
• Beschreibung:
Eine Klasse ist eine Zusammenfassung gleichartiger Objekte. Objekte sind die agie-
renden Grundelemente einer Anwendung. Die Gleichartigkeit bezieht sich auf Eigen-
schaften (Attribute) und/oder auf Fahigkeiten (Operationen/Methoden) der Objek-
te einer Klasse. Eine Klasse enthalt gewissermaßen die Konstruktionsbeschreibung
fur Objekte die mit ihr erzeugt werden. Das Verhalten der Objekte wird durch die
Moglichkeit eines Objektes Nachrichten zu empfangen und zu verstehen beschrie-
ben. Dazu benotigt das Objekt bestimmte Operationen. Die Begriffe Operation und
Nachricht sollten nicht synonym verwendet werden. Zusatzlich zu Eigenschaften und
Fahigkeiten kann eine Klasse auch Definitionen von Zusicherungen, Merkmalen und
Stereotypen enthalten. Das NBT Admin Tool besteht aus verschiedenen Klassen, die
drei wichtigsten Klassen sind: UsersBean, GroupsBean und PagesBean. Abbilldung
3.2 beschreibt die Relatation zwischen den verschiedenen Klassen.
3.2.3. Sequenzdiagramm
• Definition:
Das Sequenzdiagramm beschreibt die zeitliche Abfolge von Interaktionen zwischen
einer Menge von Objekten innerhalb eines zeitlich begrenzten Kontextes.
• Beschreibung
Mittels des Sequenzdiagrammes beschreibt man die Interaktionen zwischen den Mo-
dellelementen ahnlich wie bei einem Kollaborationsdiagramm, jedoch steht beim Se-
quenzdiagramm der zeitliche Verlauf des Nachrichtenaustausches im Vordergrund.
Die Zeitlinie verlauft senkrecht von oben nach unten, die Objekte werden durch
senkrechte Lebenslinien beschrieben und die gesendeten Nachrichten waagerecht ent-
sprechend ihres zeitlichen Auftretens eingetragen.
3.3. Datenbank Schema 21
3.2.4. Aktivitatsdiagramm
• Definition:
In einem Aktivitatsdiagramm werden die Objekte eines Programmes mittels der Ak-
tivitaten, die sie wahrend des Programmablaufes vollfuhren, beschrieben. Eine Ak-
tivitat ist ein einzelner Schritt innerhalb eines Programmablaufes, d.h. ein spezieller
Zustand eines Modellelementes, eine interne Aktion sowie eine oder mehrere von ihm
ausgehende Transitionen enthalt. Gehen mehrere Transitionen von der Aktivitat aus,
so mussen diese mittels Bedingungen voneinander zu entscheiden sein. Somit gilt ein
Aktivitatsdiagramm als Sonderform eines Zustandsdiagrammes, dessen Zustande der
Modellelemente in der Mehrzahl als Aktivitaten definiert sind.8
• Beschreibung:
In einem Programmablauf durchlauft ein Modellelement eine Vielzahl von Akti-
vitaten, d.h. Zustanden, die eine interne Aktion und mindestens eine daraus resul-
tierende Transition enthalt. Die ausgehende Transition impliziert den Abschluss der
Aktion und den Ubergang des Modellelementes in einen neuen Zustand bzw. eine
neue Aktivitat. Diese Aktivitaten konnen in ein Zustandsdiagramm integriert wer-
den oder besser aber in einem eigenen Aktivitatsdiagramm visualisiert werden. Ein
Aktivitatsdiagramm ahnelt in gewisser Weise einem prozeduralem Flußdiagramm,
jedoch sind alle Aktivitaten eindeutig Objekten zugeordnet, d.h. sie sind entweder
einer Klasse, einer Operation oder einem Anwendungsfall eindeutig untergeordnet.
3.3. Datenbank Schema
Eine logische Beschreibung von Daten, die in einer Datenbank gespeichert sind. Das
Schema definiert nicht nur die Namen der einzelnen Daten, ihre Große und andere
Charakteristiken, sondern identifiziert auch die Beziehung zwischen den Daten.9
Das DB-Schema wurde so geplant, daß man neue Users, Groups, HTML Elemente
und Pages hinzufugen kann, ohne daß man etwas am Quellcode der Komponenten
8Sams (1999)9Turner (March 27, 2002)
3.3. Datenbank Schema 22
Abbildung 3.3.: Die unterschiedlichen Datenbank Tabellen
andern muß. Die Datenbank wurde in einer Postgre-Datenbank10 realisiert.
Dazu gibt es eine Tabelle Users mit den Attributen (Uid, Username, Realname,
Email, Password), eine Tabelle Groups und deren Attributen (Gid, Groupname,
Groupdescription, Groupowner), eine Tabelle sub-groups mit den Attributen (Users,
Groups), eine Tabelle groups-user mit den Attributen (Gid, Uid), eine Tabelle element-
groups mit den Attributen (Gid, Pid, Eid). eine Tabelle projects-users mit den At-
tributen (Users, Projects). Fur jeden Typ existiert dann eine eigene Tabelle mit den
angegebenen Attributen, in der die eigentlichen Daten gespeichert werden. Abbildung
3.3 stellt Alle NBT Admin Tool benotigen Tabellen dar.
10http://www.postgresql.org/
4. Angewandte Technologien
4.1. Enterprise JavaBeans
Um Enterprise JavaBeans (EJB) effektiv verwenden zu konnen, muss man die EJB-
Architektur verstehen (siehe Abbildung 4.1). Die Enterprise JavaBeans sind Haupt-
bestandteil der Java2 Enterprise Edition (J2EE). Sie stellen die Komponententech-
nologie fur Applikationsserver mit J2EE dar. Im 1997 wurde die Technologie EJB
angekundigt. Im August 2001 wurde die Public Final-Version EJB 2.0 verfugbar, der
viele signifikante Erweiterungen und Verbessrungen gegenuber den Vorgangerversionen
enthalt.
Sun Microsystems definiert EJB wie folgt:
Die Enterprise JavaBeans Architektur ist eine Komponenten-Architektur fur die Ent-
wicklung und Inbetriebnahme Komponenten-basierte Geschaftsanwendung. Applika-
tionen, die unter Verwendung der EJB-Architektur geschrieben werden, sind skalier-
bar, transaktionsorientiert, und Mehr-benutzer-geeignet. Diese Applikation konnen
einmal geschrieben und dann auf jeder Serverplattform in Betrieb genommen werden,
die die EJB-Spezifikation unterstutzen.
4.1.1. Der EJB-Server
Eigentlich musste man von einem J2EE-Server sprechen. Die Strategie von Sun aber
bezieht EJB wesentlich starker in das gesamte Portofolio von Java-basierten Program-
mierschnittstellen und Produkten ein, als es bislang der Fall war 1.Der EJB-Server
stellt Systemdienste fur Enterprise-Beans zur Verfugung und verwaltet die Container,
in denen die Beans ausgefuhrt werden. Also der EJB-Server ist eine Laufzeitumge-
bung fur verschiedene Container.
1(Denninger, 2000)
23
4.1. Enterprise JavaBeans 24
Abbildung 4.1.: Die EJB-Architektur
Vom EJB-Server wird die Basisfunktionalitat bereitgestellt.
Dazu gehort:
• das Thread- und Prozessmanagement, damit mehrere Container parallel auf
dem Server ihre Dienste anbieten konnen
• die Unterstutzung von Clustering und Lastverteilung
• die Ausfallsicherheit
• ein Namens- und Verzeichnisdienst, um Komponenten auffinden zu konnen
• eine Zugriffsmoglichkeit auf und das Pooling von Betriebssystemressourcen
Die Schnittstelle zwischen dem Server und den Containern ist dabei vom Hersteller
abhangig. Da ein Standard fur dieses Protokoll fehlt, ist nicht sichergestellt, dass
der EJB-Container des Herstellers A im Server des Herstellers B betrieben werden
kann 2. Der JBOSS- und der WebLogic Application Server sind ein Beispiel fur einen
solchen Server.
2(Denninger, 2000)
4.1. Enterprise JavaBeans 25
Abbildung 4.2.: Die Beziehung Zwischen EJB-Server und EJB-Container
4.1.2. Der EJB-Container
Der EJB-Container ist eine Laufzeitumgebung fur Enterprise-Beans-Komponenten.
Enterprise- Beans wird als Oberbegriff fur Session-Beans, Entity-Beans und Message-
driven-Beans (EJB 2.0) verwendet. Eine Enterprise-Bean ist von ihrem EJB-Container
abhangig. Genauso ist der EJB-Container auf den Server als Laufzeitumgebung und
Dienstanbieter angewiesen. Ein EJB-Server kann viele Container haben, die alle eine
oder mehrere Arten von Enterprise-Beans enthalten (siehe Abbildung 4.2).
Ein EJB-Container kummert sich um den gesamten Lebenszyklus der Enterprise-
Beans. Dazu gehort das Erzeugen, Lesen, Andern und Loschen von Enterprise-Beans.
Das schließt nicht aus, Die Architektur von Enterprise JavaBeans dass moglichst oft
ein Pooling verwendet wird, um die Operationen fur Erzeugen und Loschen einzuspa-
ren 3. Obwohl Container einen wesentlichen Bestandteil der Enterprise-JavaBeans-
Architektur ausmachen, mussen sich Enterprise-Bean-Entwickler und Anwendungs-
3(Zimmermann, 2000)
4.1. Enterprise JavaBeans 26
Abbildung 4.3.: Client-Schnittstelle einer EJB
integratoren nicht mit den Containern befassen. In einem verteilten EJB-System
sind sie im Hintergrund tatig. Die Spezifikation (EJB 2.0) verpflichtet den EJB-
Container dazu, einer Bean zur Laufzeit mindestens folgende Programmierschnitt-
stellen zuganglich zu machen: Java 2 APIs, EJB 2.0, JNDI 1.2, JTA 1.0.1, JMS 1.0.2,
JDBC 2.0 und JavaMail 1.1. Dem Anbieter eines Java-Applikationsserver steht es frei
zusatzliche Dienste uber Standard- Schnittstellen anzubieten.
4.1.3. Das EJBHome-Interface
Es steuert den Lebenszyklus der Bean. Im (EJB)Home-Interface sind die Methoden
definiert, die ein Client zum Erstellen, Suchen und Loschen von Instanzen einer Bean
verwendet (siehe Abbildung 4.3).
Als Bean-Provider muss man das Home-Interface definieren, aber jedoch nicht imple-
mentieren. Dies ubernimmt der EJB-Container, indem er ein Home-Objekt erstellt,
das eine Referenz auf die Bean zuruck gibt. Es ist ublich, dem Home-Interface den-
selben Namen zuzuweisen wie der Bean-Klasse und das Suffix Home anzuhangen.
Hat die Bean beispielsweise den Namen Users, sollte der Name des Home-Interfaces
4.1. Enterprise JavaBeans 27
fur Users UsersHome lauten.
Alle Home-Interfaces erweitern das Interface javax.ejb.EJBHome, das wiederum das
java.rmi.Remote erweitert. Deshalb konnen alle Methoden des Home-Interfaces die
Ausnahme RemoteException auslosen 4. Nachfolgend ist die vollstandige Definition
vom EJBHome-Interface dargestellt:
package login.interfaces;
/**
* Home interface for Users.
* @xdoclet-generated at ${TODAY}
* @copyright The XDoclet Team
* @author XDoclet
* @version ${version}
*/
public interface UsersHome
extends javax.ejb.EJBHome
{
public static final String COMP_NAME="java:comp/env/ejb/Users";
public static final String JNDI_NAME="ejbs/Users";
public login.interfaces.Users create()
throws javax.ejb.CreateException,java.rmi.RemoteException;
}
EJBHome verfugt uber zwei remove()-Methoden zum Entfernen von Enterprise-
Bean-Instanzen. Die erste remove()-Methode identifiziert die Instanz anhand eines
Handles und die zweite anhand eines Primarschlussels getEJBMetaData( ) gibt
eine javax.ejb.EJBMetaData-Instanz zuruck, die das Home-, das Remote- In-
terface, die Primarschlusselklasse sowie die Information zuruckgibt, ob es sich bei
der Bean um eine Session- oder Entity-Bean handelt 5. Mit getHomeHandle()
kann ein Client sich einen so genannten HomeHandle zum Home-Interface geben
4(Zimmermann, 2000)5(Monson-Haefel, 2000)
4.1. Enterprise JavaBeans 28
lassen und diesen auf nicht fluchtigem Speicher ablegen, da HomeHandle von ja-
va.io.Serializable abgeleitet ist. Der Handle einer Enterprise-Bean kann zum einem
ubergeben werden, oder bei Entity-Beans auch deren Primarschlussel, der in einem
regularen Java-Objekt reprasentiert sein muss 6.
4.1.4. Das EJBObjekt-Interface
Der eigentliche Anwendungsdienst oder Persistenzdienst wird von den Methoden ge-
bildet, die es außer Erstellen, Loschen und Auffinden noch gibt. Solche Methoden sind
im Remote-Interface zusammengefasst. Wenn der Client sich eine Referenz auf das
Remote-Interface holt, dann bekommt er in der Wirklichkeit eine Remote-Referenz
auf ein EJB-Objekt. Das EJB-Objekt implementiert das Remote-Interface, in dem es
Geschaftsmethoden an die Bean-Klasse weiter delegiert, es stellt seine eigenen Imple-
mentationen der in EJBObject definierten Methoden zur Verfugung 7. Nachfolgend
ist der Quelltext fur EJBObject-Interface dargestellt:
package login.interfaces;
public interface Users
extends javax.ejb.EJBObject
{
public boolean addUser( String username,String realname,
String email,String password )
throws java.lang.Exception, java.rmi.RemoteException;
.......
}
Die Methode getEJBHome() gibt eine Remote-Referenz auf das Home-Objekt der Be-
an zuruck. Die Remote-Referenz wird als javax.ejb.EJBHome-Objekt zuruckgegeben,
das dann auf das Home- Interface der jeweiligen Bean eingeengt werden kann. Die-
se Methode ist nutzlich, wenn ein EJBObjekt den Sichtbarkeitsbereich des Home-
Objekts, von dem es erzeugt wurde, verlassen hat. Wenn es sich bei der Bean um
6(Zimmermann, 2000)7(Monson-Haefel, 2000)
4.1. Enterprise JavaBeans 29
eine Entity-Bean handelt, gibt die getPrimaryKey()-Methode den Primarschlussel
fur die Bean zuruck. Die remove()-Methode loscht die Enterprise-Bean. Die Wir-
kung dieser Methode ist gleich wie bei der bereits besprochene Methode EJBHo-
me.remove(). Die getHandle() Methode gibt einen bestandigen Handle auf die
Bean-Instanz zuruck. Weiterhin gibt es die Methode isIdentical() zum Vergleichen
von Enterprise-Beans 8. Alle Methoden deklarieren das auslosen einer Ausnahme
(Exception) von Typ java.rmi.RemoteException , was erforderlich ist, wenn eine
Methode uber RMI aufgerufen werden kann. Wie genau die oben genannten Metho-
den in der Realitat verwendet werden, wird in den nachsten Kapiteln verdeutlicht.
4.1.5. Enterprise JavaBeans Typen
Abbildung 3.3 veranschaulicht die drei EJB-Arten aus Version 2.0. In der ersten
Version der EJBSpezifikation (1.0) war nur die Unterstutzung von Session-Beans
vorgeschrieben. Session-Beans sind EJBs, die genau einem Client zugeordnet sind.
Diese Beans konnen einen internen Zustand haben, der uber mehrere Aufrufe in
der selben Bean hinweg existiert. Dieser Zustand wird allerdings in der Regel nur im
Hauptspeicher gehalten oder temporar auf die Platte ausgelagert, uberlebt einen Ab-
sturz oder Neustart des Servers nicht. Hingegen sind Entity-Beans, die erst seit der
Version 1.1 verpflichtend sind, persistent in einem Backend-System gespeichert, das
Methoden zum Erzeugen, Lesen, Schreiben und Loschen der Objekte bereitstellt. In
der Regel ubernehmen diese Aufgabe Relationale Datenbanken. Bei Beanmanaged-
Persistence (BMP) muss der Entwickler selbst die Zugriffmethoden implementieren.
Der Entwickler kann bei der Container-managed-Persistence (CMP) aber abstrakt
vorgeben, welche Felder persistent sein sollen und die Mapping-Tools der EJB-Server
generieren die tatsachlichen Zugriffcode. Bislang wurden alle Methodenaufrufe von
EJBs synchron durchgefuhrt, das heißt der Client wartet bis ein Ruckgabewert vom
Server geliefert wurde. Bei Message-driven-Beans (EJB 2.0) ist dies anders. Nun ist
auch das asynchrone auslosen von Aktionen durch den Java-Messaging Service JMS9
moglich. Das bedeutet, die Clients stellen eine Nachricht in eine Warteschlange, fur
die der EJB-Server als Subscriber registriert ist. Jede EJB arbeitet nun anstehen-
de Requests ab und ruft fur jede Nachricht die onMessage()-Methode auf. Clients
warten nicht auf das Ende des Methodenaufrufs, konnen jedoch eine Ruckmeldung
8http://info.borland.com/devsupport/appserver/faq/ejbcpp/ejb_cpp.html9http://java.sun.com/products/jms/
4.1. Enterprise JavaBeans 30
Abbildung 4.4.: EJB-Typen in EJB-Version 2.0
erhalten, wenn eine Message-driven-Bean den Auftragbearbeitet hat. Die Message-
driven-Beans ahneln vom Verhalten her zustandslosen (stateless) Session-Beans. Sie
mussen allerdings nicht explizit mit create()-Methoden erzeugt werden und besitzen
weder ein Home- noch ein Komponenten-Interface. Im Gegensatz zu bisherigen JMS-
Servern konnen auch mehrere EJBs gleichzeitig aktiv sein und eine große Anzahl
Requests parallel bearbeiten.
4.1.6. Session Beans
Session Beans werden dazu verwendet Anwendungslogik auf dem Server auszufuhren.
Sie sind dafur geeignet, da fur jeden Client durch den EJB- Server und den Container
ein eigenes Bean konstruiert wird und auch nur dieser eine Client Zugriff darauf hat.
Eine Session-Bean ist ein Geschaftsobjekt, weil sie die Logik eines Geschaftsprozesses
realisiert. Der Geschaftsprozess beschreibt alle Schritte, die notwendig sind, um eine
bestimmte Aufgabe zu erfullen. Logisch wird eine Session-Bean als serverseitige Er-
weiterung des Clientprogramms betrachtet 10. Sie kann Informationen fur den Client
behalten.
Normalerweise wird die Bean entfernt, wenn der Client die Sitzung beendet. Im Ge-
gensatz zu Entity-Beans reprasentieren Session-Beans keine gemeinsamen genutzten
Daten in der Datenbank 11 und somit sind sie nicht persistent. Session-Beans konnen
die Interaktionen zwischen Entity-Beans verwalten und beschreiben, wie diese zu-
10Denninger (2000)11(Monson-Haefel, 2000)
4.1. Enterprise JavaBeans 31
sammenarbeiten, um eine bestimmte Aufgabe zu erfullen.
Das Bean ist nicht persistent, d.h. sobald die Kommunikation zwischen Client und
Server beendet ist wird auch die Instanz durch den Container zerstort. Dies hat den
Nachteil, daß bei einer eventuellen Verbindungsunterbrechung, wie z.B. durch einen
Server- oder Client- Absturz samtliche Informationen verloren gehen. Daten, wie
z.B. eine Transaktion die von dem Session Bean an eine Datenbank oder an ein En-
tity Bean delegiert werden, bleiben naturlich bestehen (es wird aber keine Rollback
Funktionalitat angeboten), es geht lediglich die Instanz des Session Beans verloren.
Man kann die Session Beans weiter in statefull (zustandsbehaftete) und state-
less (zustandslose) Beans unterteilen. Zustandslose Beans bekommen eine Anfrage
und geben eine Antwort, d.h. sie konnen sich nicht den Status einer vorausgegange-
nen Anfrage merken und dementsprechend reagieren. Sie werden also bei einfachen
Methodenaufrufen verwendet, wie z.B. bei Zahlungsvorgangen, bei denen eine Kre-
ditkartennummer und der Betrag ubermittelt wird, das Bean die Zahlungsfahigkeit
uberpruft und dann eine positive oder negative Bestatigung zuruckschickt.
Ein weiterer Anwendungsfall ware eine komplexere Berechnung. Dem Bean wer-
den mehrere Eingangsdaten ubergeben, die sie dann auswertet und ein Ergebnis
zuruckschickt. Bei zustandbehafteten Session Beans handelt es sich um komplizierte-
re Konstrukte, bei denen der Zustand der Konversation mit den Clients gespeichert
wird. Session Beans haben zusammenfassend folgende Eigenschaften:
• Reprasentiert nicht Daten in einer Datenbank.
• Kann gemeinsamgenutzte Daten in einer Datenbank verandern.
• Ein SessionBean ist immer nur einem Client zugeordnet (d.h. ein gleichzeitiger
Zugriff von mehreren Clients ist nicht moglich)
• Ist relativ kurzlebig.
• Unterstutzt Transaktionen, ist jedoch kein Erfordernis.
• Verschwindet falls der EJB Server absturzt (d.h. die Session Bean kann nicht
wiederhergestellt werden).
4.1. Enterprise JavaBeans 32
4.1.7. Der Zugriff auf eine Session-Bean
Der Client bekommt mit Hilfe des JNDI eine Referenz auf das Home-Interface. Beim
Aufruf der Methode lookup von Context wird ein Objekt vom Typ java.lang.Object
zuruckgegeben. Ihr Code muss das zuruckgegebene Objekt in den erwarteten Typ
umwandeln (siehe Abbildung 4.5). Fur die richtige Konvertierung der Datentyp gibt
es die Methode narrow() von der Klasse javax.rmi.PortableRemoteObject. Nachdem
das Home-Interface bekannt ist, kann der Client eine neue Bean erzeugen (create)
und bekommt als Ruckgabewert das Remote-Interface der Bean. Wenn es sich um
zustandslose Session-Bean handelt, verfugt das Home-Interface nur uber eine crea-
te()-Methode, so dass diese vom Client aufgerufen werden muss, um die Remote-
Schnittstelle zu beziehen.
Die vorgegebene create()-Methode einer zustandslosen Sesssion-Bean hat keine Pa-
rameter 12. Mit dem Remote-Interface kann der Client mit der Bean fast so arbeiten,
als ware sie ein lokales Objekt. Eine Java-Client-Applikation verwendet JNDI, um
eine Verbindung zu einem EJB-Server aufzubauen und ein bestimmtes Home-Objekt
zu finden. Nach dem Gebrauch der Bean muss der Client die Bean wieder loschen.
Der folgende Codefragment zeigt, wie das JNDI-API verwendet werden konnte, um
eine Referenz auf das Home-Objekt zu finden und zu bekommen:
//mit dem Naming-Service einen JNDI-Kontext abrufen
public void init() throws ServletException {
try {
Context context = new InitialContext();
value = (String) context.lookup("java:/comp/env/Title");
Object ref = context.lookup("java:/comp/env/ejbs/Users");
usershome =
(UsersHome) PortableRemoteObject.narrow(ref, UsersHome.class);
} catch (Exception e) {
throw new ServletException("Lookup of java:/comp/env/ failed");
}
}
12http://info.borland.com/devsupport/appserver/faq/ejbcpp/ejb_cpp.html
4.1. Enterprise JavaBeans 33
Abbildung 4.5.: Zugriff auf eine Session-Bean
4.1.8. Entity Beans
Die Unterstutzung von Entity-Beans wurde erst in EJB-1.1 als obligatorisch fur
Server- und Container-Provider definiert. Im Gegensatz zu Session-Beans waren die
Entity-Beans in der EJB.1.0-Spezifikation noch optional 13. Entity-Beans modellieren
Geschaftskonzepte, die als Substantive ausgedruckt werden konnen. Geschaftskonzepte
reprasentieren Daten, die kontrolliert und moglicherweise auch manipuliert werden
mussen. Entity-Beans reprasentieren also Objekte der realen Welt. Sie beschreiben
sowohl den Zustand als auch das Verhalten von diesen Objekten und ermoglichen
es Entwicklern, die Daten und die Geschaftsregeln, die zu bestimmten Konzepten
gehoren, einzukapseln.
Entity-Beans reprasentieren Daten in der Datenbank. Es hat viele Vorteile, Entity-
Beans zu verwenden, anstatt direkt auf die Datenbank zuzugreifen. Die Verwendung
von Entity-Beans, um Daten in Objekt-Form zu bringen, stellt den Entwicklern einen
einfachen Mechanismus fur den Zugriff auf die Daten und die Veranderung derselben
zu Verfugung. Es ist beispielsweise viel einfacher, den Titel eines Buch durch Aufruf
von buch.setTitel() zu andern, als einen SQL-Befehl an die Datenbank zu schicken.
13(Denninger, 2000)
4.2. Java Servlets 34
Außerdem erhoht man so die Chancen 14, wiederverwendbare Software zu schreiben.
Eine einmal definierte Buch-Entity-Bean kann in vielen Bibliotheken auf konsistente
Weise wiederverwendet werden. Weil Entity-Beans es mehreren Clients ermoglichen,
parallel auf die gleichen Daten zuzugreifen, werden sie als zentrale Ressource be-
trachtet. jeder Client einer Entity-Bean arbeitet fast so, als wurde er exklusiv auf sie
zugreifen. Die Datenbankprobleme, die durch den parallelen Zugriff entstehen, ver-
meidet der EJB-Container durch die teilweise Serialisierung der Zugriffe und durch
den Einsatz von Transaktionen (siehe Kapitel Transaktionen) 15. Der paralleler Zu-
griff mehrere Clients auf eine Entity-Bean ist ein wesentlicher Unterschied zu Session-
Beans, die jeweils fur genau einen Client existieren.
Folgende Eigenschaften kennzeichnen Entity Beans:
• Reprasentiert Daten in einer Datenbank.
• Erlaubt gleichzeitigen (shared) Datenzugriff von mehreren Clients auf ein En-
tity Bean
• Unterliegt immer der Transaktionsverwaltung.
• Kann langlebig sein (d. h. lebt solange die Daten in der Datenbank bleiben)
• Uberlebt EJB Serverabsturze (d. h. das Entity Bean kann nach einem Absturz
wiederhergestellt werden)
4.2. Java Servlets
Java Servlets bieten eine sehr machtige Moglichkeit, Web-Applikationen zu bauen,
die leicht auf bereits vorhandene Systeme (z.B.: Datenbanken) zugreifen konnen. Was
ist nun ein Servlet? Die Java Servlet Specication Version 2.416
definiert Servlets wie folgt:
14(Monson-Haefel, 2000)15(Denninger, 2000)16Java Servlet Specification Version 2.4: http://java.sun.com/products/servlet/
4.2. Java Servlets 35
”Ein Servlet ist eine Web-Komponente (im Engl.: web component), die uber einen
Kontainer (Servlet Engine17) gemanagt, dynamische Inhalte generiert. Servlets sind
”kleine“ plattform-unabhangige Java Klassen, die nachdem sie in neutralen Byteco-
de kompiliert wurden, von einem Web-Server dynamisch geladen und zum Laufen
gebracht werden konnen. Servlets interagieren mit Web-Clients uber ein Request-
Response-Schema (basierend auf das Hypertext Transfer Protocol), das vom Servlet
Kontainer implementiert wird“
Vereinfachend kann ein Servlet auch mit einem Applet 18 verglichen werden, das auf
der Server-Seite lauft und daher keine grafische Oberflache besitzt. Folgende Vorteile
bietet der Einsatz von Java Servlets:
1. Plattform-Unabhangigkeit
2. Zugang zu allen Java API’s
3. Schneller als CGI Scripts19
4. Session-Management
Zur Ausfuhrung des Servlets ist eine sogenannte Servlet Engine notwendig, die An-
fragen an bestimmte Servlets weiterleitet. Die Servlet Engine ist entweder direkt im
Web-Server integriert (JavaSoft Java Web Server) oder eine eigene Server-Applikation
wie JBOSS20 oder Tomact Abbildung 2.8 zeigt, welche Methoden von der Servlet En-
gine wahrend des Servlet’s Life Cycle aufgerufen werden.
Die init() Methode dient zur Initialisierung des Servlets, das geschieht entweder bei
der ersten Verwendung des Servlets oder schon vorher. Die service() Methode kann
mit der main() Methode einer Java Applikation verglichen werden. Fur das abschlie-
ßende Aufraumen der besetzten Resourcen wird die destroy() Methode verwendet.
Bei der Programmierung eines Servlets mussen diese Methoden entsprechend ange-
paßt werden, weiters muss das Servlet direkt oder indirekt das javax.servlet.Servlet
Interface implementieren. Der einfachere Weg ist das uberschreiben von Methoden ei-
ner vorhandenen Servlet-Klasse, wie zum Beispiel der javax.servlet.http.HttpServlet
17Eine Servlet Engine ist eine Server-Applikation, die Servlets ausfuhrt.18Java Servlet Programming19Gewohnliche CGI’s spalten beim Request jeweils einen neuen Prozess ab, Servlets hingegen sind
nur einfache Threads.20http://www.jboss.org
4.2. Java Servlets 36
Abbildung 4.6.: Die verschiedenen Stufen bei der Ausfuhrung eines Servlets
Klasse. Listing 3.1 zeigt ein vom HttpServlet abgeleites Servlet, das nur die doGet()
Methode uberschreibt, die dem HTTP Get entspricht.
Listing 3.1 Hello, ein vom HttpServlet abgeleitetes Java Servlet:
1 import javax.servlet.http.*;
2 import javax.servlet.*;
3 import java.io.*;
4 public class Hello extends HttpServlet {
5 public void doGet (HttpServletRequest request,
6 HttpServletResponse response)
7 throws ServletException, IOException {
8 // get an PrintWriter from the response object
9 PrintWriter out = response.getWriter();
10 // prepare the response’s content type
11 response.setContentType("text/html");
12 // get the IP address of the client
4.2. Java Servlets 37
13 String remoteAddress = request.getRemoteAddr();
14 // print to the output stream!
15 out.println("Hi Man from <b>" + remoteAddress + "</b>");
16 }
17 }
Vorausgesetzt der Server unterstutzt Java Servlets, kann nun das Servlet via Web-
Browser21 aufgerufen werden, dass im Gegenzug ein simples in unserem Fall so-
gar unvollstandiges HTML-Dokument an den Client sendet. Akzeptiert das Servlet
den Aufruf, werden der doGet Methode zwei Objekte ubergeben, eines der Klas-
se HttpServletRequest und eines der Klasse HttpServletResponse. Das erste Objekt
(request) kapselt die ,eingehende‘ , das andere Objekt (response) die ,ausgehende‘
Kommunikation und vereinfacht das Handling mit dem Hypertext Transfer Proto-
koll. Zum Beispiel wird in Listing 2.7, Zeile 11 der MIME22-Type der HTTP-Antwort
festgelegt. Ein etwas sinnvollerer Anwendungsbereich von Servlets ist deren Einsatz
zur Kommunikation mit Datenbanken. Die benotigte Schnittstelle zu Datenbanken
wird durch das JDBC23 API realisiert, dass fur alle bekannten Datenbanken Treiber
zur Verfugung stellt. Ein Verbindungsaufbau mit einer Postgresql Datenbank zeigt
das folgende Java Code-Stuck aus der init() Methode eines Datenbank Servlets:
"");
Class.forName("org.postgresql.Driver").newInstance();
dbc = DriverManager.getConnection("jdbc:postgresql://localhost:5432/myDB?"
+"user=name&password=paswd");
Das erste Statement erzeugt ein Connection-Objekt, das die Verbindung zur Daten-
bank kapselt. Dazu wird ein passender JDBC-Driver fur die Datenbank benotigt, in
unserem Fall heißt dieser org.gjt.mm.mysql.DriverDas zweite Statement stellt nun
eine konkrete Verbindung zur Datenbank her und diese bleibt wahrend der Lebens-
zeit des Servlets aufrecht. Das Auslesen aller Datensatze einer Tabelle Produkte kann
zum Beispiel so geschehen:
21Aufruf uber URL, zum Beispiel http://localhost/servlets/Hello.22Multipurpose Internet Mail Extensions, siehe [Freed Borenstein, 1996].23Java DataBase Connectivity. Ein Java API zum Ausfuhren von SQL-Statements, stellt eine Reihe
von Klassen und Interfaces zur Manipulation von Datenbanken zur Verfugung.
4.3. Java Server Pages 38
1 Statement stmt = dbc.createStatement();
2 stmt.execute("select * from Produkte");
3 ResultSet rs = stmt.getResultSet();
Mit der Moglichkeit, SQL-Statements zu exekutieren (siehe Zeile 2), steht nun die
gesamte Funktionalitat der Datenbank zur Verfugung. Der Einsatz von RMI24wurde
den Code des Servlets noch zusatzlich vereinfachen und die Komplexitat des Datenbank-
Handlings auf eine zusatzliche Schicht verlagern.
Die Servlets-Technologie wird von einer immer großer werdenden Anzahl von Ser-
vern unterstutzt und bietet eine gute Alternative zu CGI basierenden zeitkritischen
Applikationen.25 Zusatzliches Session-Management erlaubt nun endgultig die Inter-
aktivitat zu erhohen. Mit Java hat man zudem den Vorteil, auf einer großen Menge
von Plattformen ohne Probleme lauffahige Applikationen erzeugen zu konnen und
von der Machtigkeit der vorhandenen APIs zu profitieren. Zur Zeit ist die Java Serv-
let API Specification Version 2.4 unter http://java.sun.com/products/servlet
verfugbar.
4.3. Java Server Pages
JSP ist eine Technologie, die von der Firma SUN entwickelt wurde und die auf der
Java- Servlet-API basiert.Java Server Pages sind den Active Server Pages (ASP) von
Microsoft sehr ahnlich. Mit beiden Techniken kann man in eine normale HTML-
Seite spezielle Kommandos integrieren, und damit zum Beispiel dynamische Inhalte
in die Seite integrieren26. Ziel von Java Server Pages ist es, eine Trennung von De-
sign und Applikationslogik zu erreichen. Da JSP auf Java basiert, ist außerdem eine
hohe Portabilitat gewahrleistet. Ein großer Vorteil von JSP ist, daß man innerhalb
einer JSP-Seite auf beliebige Java APIs zugreifen kann.Wahrend Active Server Pages
nur mir den Microsoft Webservern verfugbar sind, kann man die Java Server Pages
mittlerweile mit allen gangigen Webservern benutzen27.
Ein Webserver kann aber normalerweise nicht selbst die JSP-Seiten korrekt be-
handeln. Dazu benotigt man eine JSP-Engine. Diese wird dann gewohnlich uber
24Remote Method Invocation, siehe http://java.sun.com/docs/books/tutorial/rmi25Kurniawann (2002)26Pure JSP – Java Server Pages: A Code-Intensive Premium Reference27Perry (2004)
4.3. Java Server Pages 39
Abbildung 4.7.: Die verschiedenen Stufen bei der Ausfuhrung eines Servlets
ein zusatzliches Modul mit dem Webserver verbunden. Spezielle Anfragen an den
Webserver (meist alle Anfragen auf Dateien mit der Endung .JSP) werden dann an
die JSP-Engine weitergegeben. Die JSPEngine ist normalerweise als Servlet imple-
mentiert, welches in einer Servlet-Engine lauft.
Die JSP-Engine sorgt dafur, daß aus einer JSP-Seite ein Servlet generiert und dann
kompiliert wird. Ist dann eine aktuelle Klasse vorhanden, so wird die Anfrage an das
entsprechende Servlet weitergegeben. Treten beim generieren oder kompilieren des
Servlets Fehler auf, so werden diese als HTML-Seite zuruckgegeben.
4.3.1. Elemente einer JSP-Seite
Die Basis einer JSP-Seite ist normalerweise eine beliebige HTML-Seite. In diese Tem-
platedaten werden JSP-spezifische Elemente eingefugt.Es gibt drei unterschiedliche
Typen von Elementen:28 Direktiven , Aktionen und Scripting Elemente. Ein
zusatzliches Element ist der ’versteckte’ Kommentar. Da es eigentlich keine Funk-
tion fur die Seite hat, fallt dieses Element allerdings etwas aus der Reihe. Es wird
dazu benutzt um Kommentar in einer JSP-Seite einzufugen, der nicht in die Ausga-
be geschrieben wird. Der gleiche Effekt ist allerdings auch mit Scripting Elementen
28KOLB (2000)
4.3. Java Server Pages 40
moglich.
Dieser Text wird in den Ausgabestrom geschrieben.
<!-- Auch dieser HTML-Kommentar wird ausgegeben ! -->
<%-- Dieser Kommentar wird nicht ausgegeben ! --%>
<% /* Dieser Kommentar ist in der Programmiersprache der Seite und
wird auch nicht ausgegeben ! */ %>
Grundsatzlich konnen alle speziellen Elemente einer JSP-Seite auch XML-konform
geschrieben werden. Aktionen werden sowieso schon in einer an XML angelehnten
Form geschrieben. Fur Direktiven und Scripting Elemente gibt es entsprechende Al-
ternativen. Im folgenden wird noch einmal auf die Funktionen und Schreibweise der
drei Hauptelemente eingegangen.29
4.3.2. Direktiven
Mit einer Direktiven lassen sich bestimmte Informationen an die JSP-Engine ubergeben.
Es gibt die drei Direktiven include, taglib und page. Mit der include-Direktiven las-
sen sich statische Seiten einbinden. Die taglib-Direktive definiert die Zuordnung von
Prafixen zu Benutzertags. Auf diese Direktive und die Benutzertags wird spater noch
genauer eingegangen. Die page-Direktive wird benutzt, um Eigenschaften der gesam-
ten JSP-Seite zu setzten. So kann man zum Beispiel den Typ des Inhaltes definieren
oder die Puffergroße setzten. Theoretisch kann man damit auch die Programmier-
sprache der Seite bestimmen. Diese muß dann naturlich auch von der JSP-Engine
unterstutzt werden.
<%@ page language="java" import="package.*" buffer="none" %>
<%@ taglib uri="tagLibURI" prefix="myTagLib" %>
<%@ include file="header.html" %>
4.3.3. Aktionen
Aktionen dienen zur Beeinflussung des Ausgabestromes. Es gibt eine Reihe von Stan-
dardaktionen, die in einer JSP Seite benutzt werden konnen. Dazu zahlen zum Bei-
29Goodwill (2000)
4.3. Java Server Pages 41
Name Klasse Zweckrequest javax.servlet.ServletRequest Reprasentation der Anfrageresponse javax.servlet.ServletResponse der Antwort auf die AnfragepageContext javax.servlet.jsp.PageContext Der Kontext der Seitesession javax.servlet.http.HttpSession Das Session Objektapplication javax.servlet.ServletContext Der Kontext der Anwendungout javax.servlet.jsp.JspWriter Ausgabestrom fur die Antwortconfig javax.servlet.ServletConfig Enthalt Einstellungen der Seitepage java.lang.Object Instanz der Seitenimplementierungexception java.lang.Throwable Die aufgetretene Ausnahme,
Tabelle 4.1.: Implizite Objekte einer JSP-Seite
spiel das Einbinden von dynamischen Seiten oder der Zugriff auf Beans30. Auch be-
nutzerdefinierte Tags zahlen zu den Aktionen.
Einbinden eines Beans und setzen von Eigenschaften.
<jsp:useBean id="myBean" class="package.class"/>
<jsp:setProperty name="myBean" property="property1"
value="propertyValue"/>
Ausgabe einer Eigenschaft...
<jsp:getProperty name="myBean" property="property2">
4.3.4. Scripting Elemente
Scripting Elemente sind Codefragmente, die direkt in die JSP-Seite geschrieben wer-
den. Es gibt drei verschiedene Typen von Scripting Elementen: Deklarationen ,
Scriptlets und Ausdrucke . Alle mussen in speziellen Zeichen verschachtelt sein.
<%! Deklaration %>
<% Scriptlet %>
<%= Ausdruck %>
Mit Deklarationen kann man fur eine Seite Variablen und Methoden definieren. Diese
konnen dann spater in Scriptlets oder Ausdrucken verwendet werden. Ein Scriptlet
30Beans sind wiederverwertbare Java-Komponenten. Sie bestehen aus einer Java-Klasse, die einen pa-rameterlosen Konstruktor enthalt und meist Daten durch get- und set-Methoden zuganglich macht.
4.3. Java Server Pages 42
besteht aus beliebigem Code. Dieser wird ausgefuhrt, sobald die Ausgabe der Seite
die Position des Tags erreicht hat. Ausdrucke werden zur Laufzeit ausgewertet und
das Ergebnis wird direkt in den Ausgabestrom geschrieben. Sie konnen auch als dy-
namische Parameter fur Attribute von Aktionen benutzt werden, sofern dies fur das
Attribut erlaubt ist. Beispiel:
<html>
<body>
<%! String color="black"; %>
Wir produzieren eine Zufallsfarbe !<br>
<% color="#";
while (color.length() < 7) {
int i = (int) (Math.random() * 15);
if (i > 9) color += (char) (i + 87);
else color += (char) (i + 48);
%>
<font color="<%= color %>">Der Text ist farbig !</font><br>
</body>
</html>
4.3.5. Implizite Objekte einer JSP Seite
Es gibt eine Reihe von Objektinstanzen, die innerhalb einer JSP-Seite verfugbar
sind. Man kann direkt auf sie zugreifen, da sie von der JSP-Engine erzeugt werden.
In Tabelle 4.1 sind alle Impliziten Objekte einer JSP-Seite aufgelistet. Einige dieser
Objekte, wie zum Beispiel exception sind allerdings nur in speziellen Fallen verfugbar.
4.3.6. Gultigkeitsbereiche von Objekten
Alle impliziten Objekte einer JSP-Seite sind Gultigkeitsbereichen zugeordnet. Das
bedeutet eine Instanz ist nur in einem bestimmten Bereich verfugbar. Auch eigene
Objekte konnen solchen Bereichen zugeordnet, und so zum Beispiel auf mehreren
Seiten genutzt werden. Eine Ubersicht aller Gultigkeitsbereiche ist in Tabelle 4.2
verfugbar.
4.3. Java Server Pages 43
page Objekte die dieses Gultigkeitsbereiches sind nur von der Seite auserreichbar, auf der sie erzeugt wurden. Sie sind im pageContextObjekt abgelegt. (Implizite Objekte: page, response, pageContext,out, config)
request Objekte die dieses Gultigkeitsbereiches sind im request Objekt ab-gelegt. Sie sind auf allen Seiten verfugbar, die bei der Bearbeitungder selben Anfrage beteiligt sind. Das kann zum Beispiel bei einemforward der Fall sein. (Implizite Objekte: request)
session Objekte, dieses Gultigkeitsbereiches sind nur verfugbar, wenn dieSeite eine Session benotigt. Nur in diesem Fall ist das session Objektvorhanden, in dem die Objekte abgelegt werden. (Implizite Objekte:session)
application Alle Objekte, die im ServletContext (application Objekt) verfugbarsind, besitzen diesen Gultigkeitsbereich. Sie sind von allen Seitenaus erreichbar.(Implizite Objekte: application)
Tabelle 4.2.: Gultigkeitsbereiche von Objekten einer JSP-Seite
4.3.7. Beans
Man kann in einer JSP-Seite auch Java-Beans einbinden. Dies geschieht uber eine
spezielle Aktion: jsp:useBean
<jsp:useBean id="instanceName" class="package.class" scope="scope"/>
Mit anderen Aktionen kann man nun entweder Eigenschaften des Beans setzten oder
auslesen.
Setzten eines konstanten Wertes, oder eines Ausdrucks:
<jsp:setProperty name="instanceName" property="property" value="value"/>
Setzen von Werten aus den Request-Parametern:
<jsp:setProperty name="instanceName" property="property" param="param"/>
Ausgabe einer Eigenschaft:
<jsp:getProperty name="instanceName" property="property" />
Beans sind eine gute Moglichkeit, um dynamische Inhalte in eine JSP-Seite einzubin-
den. Dabei bleibt der Code vollstandig getrennt vom Layout. In vielen Fallen konnen
Beans deshalb auch komplett wiederverwertet werden. Beans sind meist recht einfach
zu erstellen, da keine großen Anforderungen an sie gestellt werden. Der Nachteil von
4.3. Java Server Pages 44
Beans ist, daß man nicht ohne weiteres Zugriff auf die impliziten Objekte der JSP-
Seite hat. Alle Einstellungen und Objekte, die dem Bean verfugbar gemacht werden
sollen, mussen uber die Aktion setProperty ubergeben werden.
4.3.8. Tag-Extensions
Da die Bibliothek, die wahrend der Diplomarbeit entwickelt wurde, auf Tag-Extensions
basiert, wird hier etwas ausfuhrlicher darauf eingegangen. Mit JSP-Tag-Extensions
ist es moglich eigene Tags zu definieren. Diese konnen dann mit spezieller Logik ver-
sehen werden. Es besteht aber auch die Moglichkeit, Tags aus fertigen Bibliotheken
zu benutzen. Zu jeder Bibliothek gehort eine Beschreibungsdatei, der Tag-Library-
Descriptor (TLD). Dort stehen Informationen zur Bibliothek und deren Tags. Unter
anderem geschieht dort auch die Zuordnung von Tagname zu Tagklasse. Aber nicht
nur ein Tag einer Bibliothek, sondern auch jedes andere, eigene Tag muß in einem
TLD deklariert werden, um es in einer JSP-Seite nutzen zu konnen. Zusatzlich muß
man noch mit einer Direktive den entsprechenden Tag-Library-Descriptor bekannt
machen:Einbinden einer Tag-Library
<%@ taglib uri="tagLibURI" prefix="myTagLib" %>
In einer JSP-Seite kann man dann auf alle Tags in einer solchen Bibliothek mit dem
gleichen, in der Direktive angegebenen Prafix zugreifen. Die Tags konnen theoretisch
beliebig verschachtelt werden. Auch ist es moglich innerhalb der Tags beliebigen
HTML-Code, Scripting-Elemente oder Aktionen zu verwenden:
<myTagLib:myTag1 attribute1="value">
Hallo Welt !<br><jsp:
<myTagLib:myTag2 attribute1="value1"/>
</myTagLib:myTag1>
Tags in einer JSP-Seite
Ob solche Verschachtelungen allerdings sinnvoll, bzw. uberhaupt moglich sind, hangt
von der Logik der Tags ab. Es kann zum Beispiel sein, daß ein bestimmtes Tag immer
im Body31 eines anderen Tags stehen muß. Genauso kann es aber auch sein, daß ein
31Der Body eines Tags ist das, was zwischen Start-Tag und End-Tag steht.
4.3. Java Server Pages 45
Tag den Inhalt des Bodys stets ignoriert. Wenn eine JSP-Seite von der JSP-Engine
kompiliert wird, dann pruft diese, ob die Tags syntaktisch korrekt verwendet wurden.
Die Informationen, die dazu notig sind, bekommt sie aus dem Tag-Library-Descriptor.
Dieser ist in einem XML-Dialekt geschrieben. Die Datei endet ublicherweise mit ’.tld’.
Die Struktur ist wie folgt:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>aShortName</shortname>
<uri>theTaglibURI</uri>
<info>Infos zu der Bibliothek</info>
<tag>
<name>myTag</name>
<tagclass>package.class</tagclass>
<info>Infos zu dem Tag</info>
<attribute>
<name>attribute1</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>attribute2</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
4.3. Java Server Pages 46
Die Klasse, die zu einem Tag gehort ist der sogenannte Tag-Handler. Jeder Tag-
Handler muß das Interface Tag32 implementieren. Tags die Attribute definieren,
mussen zusatzlich fur jedes Attribut eine get- und eine set- Methode implemen-
tieren. Es gibt zwei Verschiedene Arten von Tag-Handlern. Einmal Tag-Handler, die
auf den Inhalt des Bodys zugreifen mussen, und dann solche, die es nicht mussen.
Das Interface BodyTag erweitert das Tag Interface, um den Zugriff auf den Body
zu ermoglichen. Mit den Tag-Extensions hat man gegenuber Beans ein paar Vor-
teile. Diverse Methoden der Tag-Handler Interfaces bieten die Moglichkeit, durch
Ruckgabewerte die Ausgabe zu beeinflussen. Dadurch kann man zum Beispiel den
Body des Tags mehrfach, oder auch gar nicht ausgeben. Auch ist es moglich, den ge-
samten Inhalt zu bearbeiten, bevor er in den Ausgabestrom geschrieben wird. Damit
lassen sich mit Tags Schleifenkonstrukte (for, while,...) oder bedingte Ausgaben (if,
switch,...) erzeugen.
Die Tag-Handler werden von der JSP-Engine erzeugt. Diese ruft dann die Methoden
des Tag- Handler Interfaces und die set-Methoden der belegten Attribute nach einem
bestimmten Schema auf.
Der Ablauf bei einem normalen Tag ist wie folgt:
ATag t = new ATag();
t.setPageContext(...);
t.setParent(...);
t.setAttribute1(value1);
t.setAttribute2(value2);
t.doStartTag();
t.doEndTag();
t.release();
Fur Tags, die BodyTag implementieren ist der Ablauf folgendermaßen:
// bis hier wie bei einem normalen Tag
t.doStartTag();
32Die Klassen, auf die sich im folgenden bezogen wird gehoren zum Package javax.servlet.jsp.tagextder Servlet API. http://java.sun.com/products/servlet/2.2/javadoc/index.html
4.3. Java Server Pages 47
out = pageContext.pushBody();
t.setBodyContent(out);
t.doInitBody();
t.doAfterBody();
// solange wie doAfterBody den Status EVAL_BODY_TAG zuruckgibt
// wird die Body Auswertung erneut ausgefuhrt.
...
t.doAfterBody();
t.doEndTag();
t.pageContext.popBody();
t.release();
Die Klassen TagSupport und BodyTagSupport sind zwei Basisimplementierungen fur
Tag-Handler. Diese erleichtern die Programmierung, da man nur noch die Methoden
implementieren muß, in denen spezielle Logik notig ist. In allen Tags sind auch die im-
pliziten Objekte der JSP-Seite zuganglich. Allerdings ist nur das pageContext Objekt
direkt verfugbar. Alle anderen lassen sich uber Methoden dieses Objekts erreichen.
Tags, die in einem anderen verschachtelt sind, haben Zugriff auf die entsprechende
Tag- Handler-Instanz des ubergeordneten Tags - dem Parent.
4.3.9. Zusammenfassung
Da als Basis fur JSP die Programmiersprache Java verwendet wird, ist eine hohe
Portabilitat gewahrleistet. Fur die gangigsten Betriebssysteme bekommt man schon
eine Java Runtime Engine (JRE). Da es auch verschiedene JSP-Engines gibt, die
komplett unter Java geschrieben sind kann somit auch JSP mit diesen Systemen ver-
wendet werden.Java ist außerdem einfach zu erlernen und bietet eine umfangreiche
Klassenbibliothek, auf die uneingeschrankt zugegriffen werden kann.
Java Anwendungen mit grafischer Oberflache sind oft recht langsam. Dies liegt haufig
an den AWT33 Klassen. Da die JSP-Engine komplett serverseitig lauft, benotigt man
diese Klassen im Normalfall nicht. Somit sind JSP-Seiten meist auch ausreichend
schnell.Nutzt man Beans und Taglibraries, so bekommt man eine Trennung von De-
sign und Logik.
33Abstract Window Toolkit. Eine API, die fur das erstellen von Oberflachen gedacht ist. In den JavaVersion bis 1.2 recht langsam.
4.4. Code Generation mit XDoclet 48
So kann man gut anderbare und skalierbare Webanwendungen erstellen. Außerdem
wird der Code besser wiederverwendbar. Ein Nachteil von JSP ist allerdings, daß man
viele Daten in der Session ablegen muß und die Logik stellenweise ungunstig verteilt
ist. Als Beispiel konnte man eine JSP-Seite nehmen, die Daten ladt und in einem
Formular bereitstellt. Nach dem Abschicken der Formulardaten mussen diese auf der
Folgeseite ausgewertet werden. Jegliche Zustande mussen dabei in der Session abge-
legt werden, damit sie auf beiden Seiten verfugbar sind. Die Logik ist auf mindestens
Zwei Seiten verteilt. Sinnvoller ware, daß standardmaßig die Logikkomponente der
ersten Seite auch die Formulardaten auswertet. Die Komponente hatte alle Zustande
zur Verfugung und konnte dann, je nach Daten entscheiden, welche Seite dem Be-
nutzer angezeigt wird. Alles in allem ist JSP aber eine gute Moglichkeit dynamische
Webseiten zu erzeugen. Das zeigt sich auch daran, daß diverse Application-Server
und auch Content-Management- Systeme auf JSP aufsetzten, oder es zumindest un-
terstutzen.
4.4. Code Generation mit XDoclet
Wenn man einmal die ganzen Klassen und Deployment Descriptoren fur eine EJB
von Hand geschrieben hat, wird man ermudet feststellen, dass es hier eigentlich un-
heimlich viele redundante Vorgange gibt. Da ware doch ein Tool nutzlich, das diesen
Code nach den gewunschten Vorgaben generiert. Solche Tools gibt es naturlich: Viele
kosten Geld und sind Bestandteil von Entwicklungsumgebungen basieren auf Eigen-
entwicklungen und Datenbanken. Es gibt aber auch ein kostenloses XML-basierendes
Tool: XDoclet .
XDoclet braucht normalerweise nur eine Datei, namlich die EJB Implementation,
und generiert daraus alle weiteren notewendigen Dateien, um eine EJB zu deployen,
also:
1. EJB und produktspezifische (JBoss, WebLogic, WebSphere, Orion) deployment
descriptoren
2. Home und Remote Interfaces
3. Primary Key Class fur die Entity Bean
4. Bulk Data Object (Value Object)
4.4. Code Generation mit XDoclet 49
5. EJB Wrapper Klassen
Wo notig, kann man auch die Erstellung einiger dieser Datein unterbinden, man
kann den generierten Code verandern lassen und zusatzlichen Code/Descriptions als
vordefinierte ’Merge Points’ hinzufugen.
XDoclet ist eine Weiterentwicklung des Original-EJBDoclet-Tools von Rickard Oberg.
Die Idee dahinter ist simpel: Statt mit allen EJB-Dateien zu jonglieren, wird die gan-
ze Komponente aus der Bean-Klasse erzeugt. Wie das geht? In Java gibt es doch die
Javadoc-Tags. Wir setzten nun einfach spezielle @ -Tags in die normalem Javadoc-
Kommentare hinein, und lassen das Doclet-Tool diese Tags auslesen. Das Tool gene-
riert die entsprechenden XML-Descriptoren und Interfaces fur diese EJB. XDoclet
fuhrt die Idee von EJBDoclet noch weiter, indem das Framework noch viel mehr als
nur EJB unterstutzt: Man kann auch Web Services, Web Application Descriptoren
und sogar Eigenentwicklungen damit schreiben lassen.
4.4.1. Was ist XDoclet?
XDoclet ist eine OpenSource Engine fur die Generierung von Code. Sie liest Ja-
va Quelldateien ein und wertet die darin enthaltenen Metainformationen aus. Die
XDoclet Informationen werden in Form von JavaDoc Tags direkt im Quellcode an-
gegeben. Mit Hilfe von Code-Schablonen und den ermittelten Metainformationen er-
zeugt die Engine die gewunschten Ausgabedateien. Mogliche Zielformate sind unter
anderem XML (z. B. Deployment Deskriptoren), Java Quelldateien oder Implemen-
tierungen der J2EE Patterns.34
Der Funktionsumfang von XDoclet kann uber Module erweitert werden. Module ent-
halten die entsprechenden Generierungs-Schablonen fur eine bestimmte Technologie.
Folgende Module sind bereits in XDoclet integriert:
• EJB
• Web
34Sullins und Whipple (May 2003)
4.4. Code Generation mit XDoclet 50
Abbildung 4.8.: XDoclet Ablauf
4.4. Code Generation mit XDoclet 51
• Hibernate
• Mockobjects
• JDO
• JMX
Die Anpassung bzw. die Erstellung eigener Module ist m?glich.
Fur die Ausfuhrung der Engine wird in der aktuellen Version das ebenfalls als Open-
Source verfugbare Buildwerkzeug Apache Ant benotigt. Die einzelnen Module stellen
Ant Tasks zur Verfugung, mit deren Hilfe der eigentliche Generierungslauf ausgefuhrt
wird.
4.4.2. XDoclet und J2EE
XDoclet bietet eine gute Unterstutzung der J2EE Technologien. Neben der manuel-
len Erstellung bzw. Erweiterung der Deployment Deskriptoren entfallen z. B. auch
zeitaufwendige T?tigkeiten wie die Erstellung von Home- und Remoteinterfaces bei
der EJB Entwicklung. Es genugt, die Bean Klasse um Metainformationen in Form
von Tags zu erweitern.35
Dies hat zum einen zur Folge, daß innerhalb des Projektes keine veralteten Deploy-
ment Deskriptoren mehr enthalten sind, zum anderen erhalt der Entwickler eine bes-
sere Ubersicht uber das Projekt, da die Informationen nicht mehr auf mehrere Dateien
verteilt, sondern zentral in einer Datei gepflegt werden. Mit Hilfe von XDoclet lassen
sich neben Standard Deployment Deskriptoren auch containerabhangige Deskripto-
ren erzeugen. Unterstutzt werden zur Zeit unter anderem:
• JBoss
• Tomcat
• Bea Weblogic
• IBM Websphere
35Sullins und Whipple (May 2003)
4.4. Code Generation mit XDoclet 52
Zusatzlich wird die Implementierung einiger J2EE Patterns erleichtert. Durch Dekla-
ration in der Java Datei sowie in der Build Datei lassen sich so z. B. ValueObjects,
Struts Formulare oder Schlusselgenerierungs Session Beans erzeugen.
4.4.3. Beispiel EJB mit XDoclet
Abschließend wird anhand eines Beispiels der Einsatz von XDoclet wahrend der EJB
Entwicklung gezeigt.
Ausgangspunkt der Entwicklung ist die Bean Klasse, die wir, entgegen der eigentli-
chen Vorgehensweise bei Session Beans, als abstrakte Klasse implementieren. XDoclet
erstellt bei der Generierung eine abgeleitete Klasse, die die fehlenden Callback Metho-
den (setSessionContext, etc.) implentiert. Diese Klasse wird dann auch automatisch
in den Deployment Deskriptor eingetragen.
In die Dokumentation der Klassen werden allgemeine Metainformationen wie Bean-
Name und Typ des Beans aufgenommen. In der Dokumentation der Business-Methode
wird definiert, daß die Methode auch im Interface aufgefuhrt sein soll. Damit ist die
Bean Implementierung abgeschlossen.
Zur Generierung wird das XDoclet Modul ejbdoclet benutzt. Dieses muß hierzu in
der Build Datei angegeben und aufgerufen werden. Im Beispiel enthalt der Auf-
ruf von ejbdoclet die Anweisung, daß samtliche auf Bean.java endende Dateien im
Source Verzeichnis in die Verarbeitung eingeschlossen werden sollen. Durch das ses-
sion Element wird ejbdoclet angewiesen, Session Beans zu berucksichtigen und die
entsprechenden Tags auszuwerten. Das Attribut acceptAbstractClasses erlaubt den
oben bereits erwahnten Einsatz von abstrakten Klassen bei Session Beans. Im weite-
ren wird definiert, daß Remote- und Homeinterfaces erstellt werden sollen. Zusatzlich
wird ein Standard Deployment Deskriptor sowie ein JBoss Deployment Deskriptor
erzeugt.
Die so erstellten Java Klassen konnen nun compiliert und in ein JAR Archiv gepackt
werden. Dieses kann anschlieaend in den Server deployed werden.
<target name="xdoclet-generate" depends="init">
<taskdef name="ejbdoclet"
4.4. Code Generation mit XDoclet 53
classname="xdoclet.modules.ejb.EjbDocletTask">
<classpath refid="compile.classpath"/>
</taskdef>
<ejbdoclet destdir="${build.src.dir}"
excludedtags="@version,@author"
mergedir="${meta.dir}/ejb-jar/META-INF/">
<fileset dir="${src.dir}">
<include name="**/*Bean.java"/>
</fileset>
<session acceptAbstractClasses="true"/>
<remoteinterface/>
<homeinterface/>
<deploymentdescriptor destdir="${build.dir}/META-INF"/>
<jboss version="3.0" xmlencoding="UTF-8"
destdir="${build.dir}/META-INF"
validateXml="false"/>
</ejbdoclet>
</target>
4.4.4. Fazit
XDoclet ist sicher kein Model Driven Architecure (MDA) Tool im eigentlichen Sinne,
es handelt sich vielmehr um ein hilfreiches Werkzeug, mit dessen Hilfe die Entwick-
lung besonders von J2EE Anwendungen vereinfacht wird. Der Entwickler kann sich
wieder auf die eigentlichen Aufgaben konzentrieren und muß sich nicht mehr mit
aufwendiger, fehleranfalliger Cut- and Paste Arbeit aufhalten.36
36http://www.xdoclet.org
4.5. JBoss Application Server 54
4.5. JBoss Application Server
JBoss ist ein vollstandig in Java implementierter Open-Source Application Server.
Er unterstutzt Enterprise JavaBeans 2.0 und arbeitet sowohl mit Jetty als auch mit
Tomcat als Web Engine zusammen.37
4.5.1. Deployment unter JBoss
JBoss unterstutzt das sogenannte Hot Deployment . Um eine EJB einzusetzen,genugt
es, die dazugehorige Jar-Datei in das Deploy-Verzeichnis des Application Servers zu
kopieren (JBOSS/server/default/deploy). JBoss erkennt, dass die Datei verandert
wurde und ladt die enthaltenen EJBs. Im Verzeichnis JBOSS/server befnden
sich mehrere Profile des Application Servers. Beim Start wird durch den Parame-
ter -configure=X das zu ladende Profile X festgelegt. Das Standardprofile ist
JBOSS/server/default . Ein neues Profile lasst sich einfach durch das Kopieren
eines bestehenden erstellen. Jedes Profile besitzt ein eigenes Deploy-Verzeichnis. Be-
vor die Komponente Usermanagement eingesetzt werden kann, muss sie zunachst
kompiliert, zusammen mit den Deployment-Deskriptoren in ein Jar-Archiv gepackt
und in das Deployment-Verzeichnis des JBoss kopiert werden
Neben deploy werden die Funktionen compile und clean zur Verfugung gestellt.
Deploy erstellt aus den kompilierten Klassen ein Jar-Archiv und kopiert es in das
standard Deploy-Verzeichnis des Application Servers. Der Pfad zu einer Installa-
tion von JBoss wird dem Skript mit der Variablen jboss.path ubergeben. Falls es
notwendig ist, wird von deploy die Funktion compile aufgerufen, wodurch zunachst
samtliche Klassen kompiliert werden. Mit clean konnen alle erzeugten Klassen und
Archive wieder geloscht werden.
37http://www.jboss.org
5. Implementierung
In diesem Kapital werden die Hauptpackages dargestellt. Weiter wird die JSP Web-
inferface erklart. Die Implementierung der Hauptpackages untergliedert sich in drei
Unterpackages (package login.ejb, package login.interfaces, package login.web), die
im Zusammenhang miteinander stehen. Im Package login.ejb befinden sich alle EJB’s
zur Realisierung der einzelnen Klassen usersBean, pagesBean und groupsBean. Das
Interface wird durch XDoclet automatisch erzeugt. Das Interface beinhaltet somit
das remote- und home-interface. Hingegen benutzt das login.web package die anderen
beiden Packages (Abbildung 5.1). In diesem Package befinden sich unter anderem die
Servlets und die JSP-Seiten.
Hinweis: Die vollstandige Implementierung der einzelnen Methoden, Klassen und
Packages sind im Anhang zu finden.
Abbildung 5.1.: Die Hauptpackages
55
5.1. UsersBean 56
5.1. UsersBean
Alle notwendigen Funktionalitaten uber den User werden in der Klasse UsersBe-
an implementiert. Darin befinden sich die Methoden wie die Auflistung aller User,
Loschen einzelner User, Hinzufugen einzelner User in eine bestehende Gruppe und
Verandern der Daten eines Users.
Abbildung 5.2.: UsersBean
Login: Die folgende Methode login erhalt den Namen und das Passwort des Users.
Ist der User vorhanden und tippt der User sein Passwort korrekt ein, so wird er durch
diese Methode erkannt und die Zulassung zum System erfolgt. Sollte der User falsche
Eingaben vornehmen, wird eine Exception ausgelost.
public Integer login(String userName, String password) {
...
}
5.1. UsersBean 57
Add User: Durch die addUser Methode wird der User in die Datenbank hinzugefugt.
Existiert der User bereits, wird eine Exception ausgelost und die Daten des Users
werden verworfen. Diese Aktion wird durch eine Hilfsmethode isUserFree durch-
gefuhrt. Der User erfahrt somit, dass jemand mit dem von ihm gewahlten Usernamen
schon existiert. Existieren jedoch die Daten nicht, so wird der User in die Datenbank
aufgenommen.
public boolean addUser(String username,
String realname, String email, String password)
throws Exception {
....
}
Delete User: In der folgenden Methode wird ein User aus der vorhandenen Liste
der User geloscht. Dafur wird die ID des Users benotigt. Ist der User zum Loschen
markiert, wird er nach Ausfuhren aus der Datenbank sowie aus den Gruppen, in
denen er sich befindet, geloscht. Als Ausgabe erhalt man, dass der User erfolgreich
vom System entfernt wurde.
public String deleteUser(Integer uid) throws Exception {
...
}
Update User: Mit Hilfe dieser Methode updateUser konnen die Daten der jeweiligen
User aktualisiert werden. Die Methode braucht zur Aktualisierung der Daten das
Usernamen, Realnamen, Emailadresse und den Passwort des Users.
public void updateUser(String username,
String realname, String email,
String password)
throws Exception, RemoteException {
...
}
5.2. GroupsBean 58
Get Users: Durch die Implementierung der Methode getUser wird das Auslesen
eines bzw. mehrerer User ermoglicht. Die Ausgabe erfolgt durch ein String Array
pro User. Dieses Array liefert als Ausgabe den UserId, Usernamen, Realnamen und
Emailadresse.
public String[] getUser(String username)
throws Exception, RemoteException {
...
}
Reset Password: Durch diese Option hat der User die Moglichkeit, eine Anfrage
beim Admin fur die Zurucksetzung seines Passwortes zu machen. Dafur benotigt der
Admin lediglich den Usernamen des Users, um das Passwort auf einen Defaultwert
zuruckzusetzen.
public void setpassword(String username,
String admin, String password)
throws Exception, RemoteException {
...
}
5.2. GroupsBean
In der Klasse GroupsBean befinden sich alle Methoden fur die Verwaltung von
Gruppen. Darunter befinden sich Methoden, wie z.B. Erstellen einer neuen Grup-
pe, Loschen einer vorhanden Gruppe sowie das Hinzufugen bzw. Loschen eines User
in bzw. aus eine(r) vorhandene(n) Gruppe. Zusatzlich werden in dieser Klasse den
Gruppen auch Elemente und Projekte zu geordnet.
Add Group: Durch diese Methode wird eine neue Gruppe im System erstellt. Als
Pflichteingabefelder sind Gruppenname und Gruppenbeschreibung einzugeben. Falls
die Gruppe vorhanden ist, wird eine Exception ausgelost und die eingegebenen Daten
werden verworfen.
5.2. GroupsBean 59
Abbildung 5.3.: GroupsBean
public boolean addGroup(String groupname,
String gdescription)
throws Exception {
...
}
Delete Group: Die Methode deleteGroup loscht eine vorhandene Gruppe aus dem
System. Durch das Entfernen der Gruppe verliert die Gruppe ihre Gultigkeit, jedoch
existieren die User weiterhin im System. Zum Loschen der Gruppe benotigt man
lediglich die ID der Gruppe. Als Ruckgabewert wird ein String ausgegeben.
public String deleteGroup(Integer gid)
throws Exception {
...
}
Add user to group: Es besteht die Moglichkeit einer vorhandenen Gruppe einen
bzw. mehrere User hinzuzufugen. Dies wird durch die Methode addUserToGroup
5.2. GroupsBean 60
ermoglicht. Als Eingabewerte fur die Methode sind Gruppenname und Username
erforderlich.
public boolean addUserToGroup(String gname,
String uname) throws Exception {
...
}
Deletes a user from a group: Das Loschen eines Users aus einer vorhandenen
Gruppe bedeutet nicht das Loschen des Users aus dem System. In der Methode
removeUserFromGroup wird der User aus der Gruppe entfernt, somit verliert der
User seine Gruppenangehorigkeit. Die Gruppe und der User existieren weiterhin.
public void removeUserFromGroup(String gname,
String uname) throws Exception{
...
}
Add element to group: Die Methode addElementToGroup weist einer vorhan-
denen Gruppe ein neues HTML-Element bzw. ein neue Page zu. Dazu benotigt die
Methode die Page ID bzw. Element ID und den Gruppennamen. Ist ein neues Element
bzw. Page einer Gruppe hinzugefugt worden, so erhalten alle User die Berechtigungen
zu den Elementen.
public void addElementToGroup(Integer eid,
Integer pid,String gname) throws Exception{
...
}
Delete element from group: Im Gegensatz zu addElementToGroup besteht auch
eine Methode removeElementFromGroup, um Elemente und Pages aus einer Gruppe
wieder zu Entfernen. Nach dem entfernen der Elemente verlieren die Gruppenmit-
glieder die Berechtigung gegenuber den Elementen.
public void removeElementFromGroup(Integer eid,
5.3. PagesBean 61
Integer pid, String gname) throws Exception {
...
}
Get Group: Die Darstellung und Anzeige aller vorhandenen Gruppen wird durch
eine Vektormethode getAllGroups realisiert. Diese Methode ist eine einfache Imple-
mentierung zur Darstellung der Gruppen mit Ihren ID’s, Gruppenname sowie der
Gruppenbeschreibung.
public Vector getAllGroups()
throws Exception ,RemoteException {
...
}
5.3. PagesBean
Die Klasse PagesBean besteht aus einigen private-Methoden und der isVisible-Methode.
Dabei wird in den private-Methoden, die nach aussen nicht sichtbar sind, ein Ver-
gleich zwischen den Gruppen und den Usern durchgefuhrt, ob sie im Zusammenhang
miteinander stehen. Ist dies der Fall, so hat die Gruppe, und somit auch der User,
die Berechtigung dieses HTML-Element zu sehen.
Abbildung 5.4.: PagesBean
isVisible: Die großte Bedeutung kommt der isVisible Methode in der Klasse Pa-
gerBean zu. Diese Methode , gibt die Berechtigung bzw. Zusammengehorigkeit der
Gruppen und User frei, und ermoglicht somit Elemente oder Pages zusehen.
5.4. Anbindung an die Datenbank 62
public Boolean isVisible(Integer userID,
Integer projectID,Integer pageID,
Integer elementID,Vector pageHierarchy) {
...
}
5.4. Anbindung an die Datenbank
Die Anbindung der PostgreSQL-Datenbank wird durch ein EJB”configBean“ rea-
lisiert. Dabei wird eine Verbindung durch die Methode getDBConnectionData auf-
gebaut. Diese Methode braucht zusatzlich den Treiber fur die Datenbank. Als Para-
meter benotigt die Methode noch zusatzliche Angaben wie den Usernamen fur die
Datenbank, Passwort, Port und den Datenbanknamen.
public Map getDBConnectionData (){
Map map = new HashMap();
map.put("driver", "org.postgresql.Driver");
map.put("url", "jdbc:postgresql://localhost:5432/admin");
map.put("username", "test");
map.put("password", "test");
return map;
}
5.5. Admin Tool Web-Interface
Das Web-Interface dient zur Realisierung der Funktionalitaten und ist eine JSP-
Seite, die eine Verbindung zwischen dem Benutzer und dem System darstellt. Im
Package web.root werden die einzelnen Servlets und JSP-Seiten abgelegt. Weitere
Klassen innerhalb des Web-Interfaces sind validateUser, validateGroup und treeTag.
Um auf die EJB’s zugreifen zu konnen, benotigen wir die Klasse validateUser, um eine
5.5. Admin Tool Web-Interface 63
Verbindung zwischen den EJB’s und den JSP-Seiten zu ermoglichen. Aquivalent gilt
diese Implementierung fur den validateGroup, der dann die Verbindung zwischen den
EJB’s und den JSP-Seiten gruppenseitig herstellt. Ein Auszug aus dem validateUsers
sieht wie folgt aus:
public boolean addUser(String username, String realname, String email,
String password) {
try {
Context context = new InitialContext();
String value = (String) context.lookup("java:/comp/env/Title");
Object ref = context.lookup("java:/comp/env/ejbs/Users");
UsersHome usershome = (UsersHome) PortableRemoteObject.narrow(ref,
UsersHome.class);
Users bean = usershome.create();
bean.addUser(username, realname, email, password);
return true;
} catch (Exception exp) {
return false;
}
}
Die Klasse treeTag dient zur dynamischen Darstellung der einzelnen Links. Durch
Ausfuhren dieser Klasse wird die Navigation der einzelnen Funktionalitaten sicher-
gestellt. Diese Klasse ermoglicht weiterhin das Expandieren bzw. den Kollaps der
Baumstruktur.
5.5. Admin Tool Web-Interface 64
Abbildung 5.5.: Web infterface
6. Admin Tool Benutzerhandbuch
Das folgende Kapitel beschreibt eine Schritt fur Schritt Einfuhrung in das Admin
Tool. In diesem Abschnitt werden die einzelnen Schritte uber das Einloggen bis hin
zum Benutzen des Admin Tools im Detail beschrieben.1
6.1. Authentifizierung
Abbildung 6.1.: Authentifizierung Prozess
Der Zugang zum Admin Tool erfolgt uber eine Authentifizierungsseite. Nur authen-
tifizierten Usern ist der Zugang in das Admin Tool gestattet. Jeder User muss sich
mit seinem gultigen Usernamen und Passwort auf der Authentifizieungsseite anmel-
den (siehe Abbildung 6.2). Versucht ein nichtauthentifizierter User den Zugang zu
erzwingen, wird er vom Admin Tool abgewiesen und erhalt eine Fehlermeldung an-
hand einer HTML Error Page (siehe Abbildung 6.1).
Nach dem Einloggen gliedert sich die Webapplikation in drei Bereiche. Im linken
Bereich der Applikation sieht man die User und Gruppen Verwaltung. Im rechten
1NBT Admin Tool: http://www.venus.cs.tu-berlin.de/adminproject/login.jsp
65
6.2. User Verwaltung 66
Abbildung 6.2.: Login Page
Frame, dem so genannten Hauptframe, sieht man die Ubersicht der einzelnen Funk-
tionen bzw. Darstellung der einzelnen Links (Abbildung 6.3).
6.2. User Verwaltung
Im Untermenu User Verwaltung befinden sich weitere Untermenus, die alle Benutzer
anzeigen, neue User anlegen, Passworter zurucksetzen bzw. Anzeigen von vorhande-
nen Gruppen.
6.2.1. List all user
In der User List erhalt man alle im System vorhandenen User mit ihren Usernamen,
Realnamen und Emailadressen sowie eine Checkbox, um bestimmte Operationen auf
den User auszufuhren, wie z.B. Einfugen eines ausgewahlten Users in eine Gruppe.
6.2. User Verwaltung 67
Abbildung 6.3.: Hauptansicht
Abbildung 6.4.: Liste aller verfuegbaren User
6.2. User Verwaltung 68
6.2.2. Create user
Unter diesem Link besteht die Moglichkeit einen neuen User anzulegen. Dafur werden
Informationen uber den Usernamen, Realnamen und die Emailadresse benotigt. Falls
der User sich in der Datenbank befindet bzw. sein Username schon existiert, wird der
User vom System abgewiesen und die eingegebenen Daten werden verworfen.
Abbildung 6.5.: Create new user
6.2.3. Reset password
Falls der User sein Passwort vergisst, kann der Admin dessen Passwort auf Wunsch
wieder zurucksetzen. Dieses Feature wird in Zukunft dann uber eine Email abge-
wickelt und der User erhalt sein zuruckgesetztes Passwort per Mail.
6.2.4. Update User
Diese Funktionalitat ist fur den Admin sowie fur den Anonymous User verfugbar,
d.h. sogar der Anonymous User hat das Recht, Veranderungen an seinen eigenen
Daten vorzunehmen.
6.2. User Verwaltung 69
Abbildung 6.6.: Update user
6.2.5. Delete user
Delete user dient zum Loschen eines Users aus der Datenbank. Ist der User aus
der Datenbank verworfen, gehen alle Daten uber den User verloren sowie dessen
Zugehorigkeiten in den einzelnen Gruppen.
Abbildung 6.7.: Delete user
6.3. Groups verwalten 70
6.2.6. Show user groups
Mit dieser Funktion wird eine detaillierte Ausgabe uber einen ausgewahlten User in
den eingetragenen Gruppen dargestellt. Es werden nur die Gruppen dargestellt, in
denen sich der User auch tatsachlich befindet.
6.3. Groups verwalten
Unter dem Hauptmenupunkt Gruppenverwaltungen verbergen sich Funktionalitaten
wie Anzeigen aller Gruppen, Erzeugen von neuen Gruppen sowie das Hinzufugen,Loschen
und die Verwaltung der Subgruppen, die eine Teilmenge der Hauptgruppen sind.
6.3.1. List all groups
Im ersten Untermenu von der Gruppenverwaltung befindet sich list all groups. Hierbei
werden alle Gruppen aufgelistet, die im System vorhanden sind. Diese Gruppen sind
eindeutig uber ID’s gekennzeichnet. Weiterhin erhalt man eine Kurzbeschreibung zu
den einzelnen Gruppen.
Abbildung 6.8.: List All Gropus
6.3. Groups verwalten 71
6.3.2. Create group
Create Group dient zur Erzeugung einer neuen Gruppe. Dabei wird ein eindeuti-
ger ID der Gruppe durch das System zugeordnet. Weiterhin hat der Eintragende
die Moglichkeit den Gruppennamen sowie eine Kurzbeschreibung uber den erfolgten
Eintrag einzugeben.
Abbildung 6.9.: Add new group
6.3.3. Add user to group
Ein neuer bzw. bestehender User wird zu einer vorhandenen Gruppe hinzugefugt,
somit erhalt der User bestimmte Rechte, die der Gruppe auferlegt sind, und erhalt
dadurch die Verknupfung zu den Projekten und den HTML Elementen.
6.3.4. Delete group
Mit ein paar klick’s loscht man eine vorhandene Gruppe aus der Liste. Dafur wahlt
man die Checkbox und geht dann auf Delete. Hierbei wird die Gruppe geloscht,
jedoch nicht die einzelnen User, d.h. die User verlieren nur die Zugehorigkeiten zur
geloschten Gruppe und nicht mehr.
6.3. Groups verwalten 72
Abbildung 6.10.: Delete group
6.3.5. Delete user from group
Loscht man einen User aus der Gruppe, so verliert der User die Verknupfung zu den
einzelnen Projekten sowie zu den HTML Elementen, da der User nicht mehr in der
Gruppe existiert. Dies bedeutet jedoch nicht, dass der User komplett vom System
geloscht wurde, sondern nur den Verlost der Berechtigung fur die jeweilige Gruppe.
6.3.6. Add sub-group
In dem Untermenu add sub-group wird eine neue Gruppe einer bestehenden Main-
gruppe erzeugt. In diesem Falle erbt die Untergruppe alle Berechtigungen und Funk-
tionalitaten der Maingruppe. Zu dem werden auch alle User aus der Maingruppe ein
Teil der neuen Subgruppe.
6.3.7. Delete sub-group
Mit dem Entfernen einer Subgruppe werden alle Funktionalitaten und Berechtigun-
gen sowie die eingetragenen User geloscht. Durch diesen Loschvorgang wird die Main-
gruppe, aus der die Subgruppe einmal erzeugt wurde, nicht angetastet, d.h. die Main-
gruppe verliert weder ihre Berechtigungen, Funktionalitaten noch die eingetragenen
6.4. PLP Security 73
User.
6.4. PLP Security
Abbildung 6.11.: PLP Security Panel
Das Admin Tool wird durch ein Gui-Interface in PLP erganzt. Damit man die Secu-
rity (Abbildung 6.11) Funktionalitaten ausnutzen kann muss, man sich auf dem PLP
als Administrator einloggen. Daher ist ein zusatzliches Login Fenster fur das PLP
vorhanden, um bestimmte Elemente den verschiedenen Usern, die in unterschiedli-
chen Gruppen zugeordnet sind, anzuzeigen.
6.4. PLP Security 74
Die einzelnen Elemente und Pages werden durch den Menupunt Managegroups (Ab-
bildung 6.12) behandelt. Dabei werden bestimmte Projekte und HTML Elemente zu
bestimmten Gruppen hinzugefugt. Jede Gruppe erhalt somit eine bestimmte Aus-
wahl an HTML Elementen und Projekten, die ihr zugewiesen werden.
Abbildung 6.12.: PLP Managegroups
A. Anhang
A.1. GroupsBean.Java
/* $Id: GroupsBean.java,v 1.10 2004/12/13 06:42:15 bassem Exp $ */
package login.ejb;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import java.util.Vector;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.EJBHome;
import javax.ejb.EJBObject;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
75
A.1. GroupsBean.Java 76
import javax.rmi.PortableRemoteObject;
/**
* @author <a href="mailto:[email protected]">Bassem El-Ahmad</a>
*
* @ejb.bean name = "Groups"
* display-name = "GroupsBean EJB"
* description = "EJB inorder to manged the Groups"
* view-type = "remote"
* jndi-name = "ejbs/Groups"
*/
public class GroupsBean implements SessionBean {
/**
* The Java-Mysql Connection
*
* @uml.property name="stmt"
* @uml.associationEnd multiplicity="(0 -1)" elementType="java.lang.String"
*/
private Statement stmt = null;
/**
* database connection result
*
* @uml.property name="rs"
* @uml.associationEnd multiplicity="(0 -1)" elementType="java.lang.String"
*/
private ResultSet rs = null;
private String admin;
private String all;
private String page;
A.1. GroupsBean.Java 77
private boolean loggedIn;
public GroupsBean() {
super();
}
public Connection getConnection() {
Map map = null;
try {
Context context = new InitialContext();
Object ref = context.lookup("funcEJBS/Config");
EJBHome homeObject = (EJBHome) PortableRemoteObject.narrow(ref,
EJBHome.class);
Method createMethod = homeObject.getEJBMetaData()
.getHomeInterfaceClass()
.getMethod("create", new Class[] {});
EJBObject ejbObject = (EJBObject) createMethod.invoke(homeObject,
new Object[] {});
Method method = homeObject.getEJBMetaData()
.getRemoteInterfaceClass().getMethod("getDBConnectionData",
new Class[] {});
map = (Map) method.invoke(ejbObject, new Object[] {});
Class.forName((String) map.get("driver")).newInstance();
Connection conn = DriverManager.getConnection((String) map
.get("url"), (String) map.get("username"), (String) map
.get("password"));
return conn;
} catch (NamingException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
A.1. GroupsBean.Java 78
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* Adds a group
*
* @param group The Group
* @param user The user who wants to add the Group
* @throws Exception if group allready exists
* @ejb.interface-method view-type = "remote"
*/
public boolean addGroup(String groupname,String gdescription) throws Exception {
String insert;
try {
Connection conn = getConnection();
if (this.groupFree(groupname)) {
stmt = conn.createStatement();
A.1. GroupsBean.Java 79
insert = ("insert into groups(gname,gdescription) values(’"
+ groupname.trim()
+ "’,’"
+ gdescription.trim() + "’)");
stmt.execute(insert);
return true;
} else{
throw new Exception(groupname + " is allready in Database!");
}
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
A.1. GroupsBean.Java 80
return false;
}
/**
* Deletes a group
* @param gid The Group ID
* @ejb.interface-method view-type = "remote"
*/
public String deleteGroup(Integer gid)throws Exception {
String result = "Group Deleted";
Connection conn = null;
try
{
conn = getConnection();
stmt = conn.createStatement();
stmt.executeUpdate("DELETE FROM groups_users WHERE gid = "+gid.intValue());
stmt = conn.createStatement();
stmt.executeUpdate("delete from groups where gid ="+gid.intValue());
}catch(Exception e){
e.printStackTrace();
result = e.getMessage();
}
finally{
try{
conn.close();
A.1. GroupsBean.Java 81
}catch(SQLException ex){
}
}
return result;
}
/**
* Adds a user to a group
*
* @param group The name of the Group
* @param user The user who is to be added to the group
* @param admin The admin who wants to add to the group
* @throws Exception If user is not allowed to add users to the group
* @ejb.interface-method view-type = "remote"
*/
public boolean addUserToGroup(String gname, String uname) throws Exception {
String insert = null;
try {
Connection conn = getConnection();
if (!(groupFree(gname))) {
if (this.getUid(uname) == 0)
throw new Exception("Failed to add " + uname
+ " to group " + gname + "!");
stmt = conn.createStatement();
insert = ("insert into groups_users values (’"
+ this.getGid(gname) + "’,’"
+ this.getUid(uname) + "’)");
stmt.executeUpdate(insert);
return true;
A.1. GroupsBean.Java 82
} else
throw new Exception("Group " + gname + " does not exist");
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* Deletes a user from a group
*
* @param group The name of the Group
* @param user The user who is to be deleted from the group
* @param admin The admin who wants to delete the user
* @throws Exception If user is not allowed to delete users from group
* @ejb.interface-method view-type = "remote"
*/
public void removeUserFromGroup(String gname, String uname) throws Exception{
try {
Connection conn = getConnection();
String delete = null;
stmt = conn.createStatement();
delete = ("DELETE FROM groups_users WHERE uid = ’"
+ this.getUid(uname) + " and gid = ’"
+ this.getGid(gname) + "’)");
A.1. GroupsBean.Java 83
stmt.executeUpdate(delete);
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* Adds a element to a group
*
* @param gname The name of the Group
* @param eid Element ID
* @param pid The Project ID
* @throws Exception If user is not allowed to add users to the group
* @ejb.interface-method view-type = "remote"
*/
public void addElementToGroup(Integer eid,Integer pid, String gname) throws Exception{
String insert;
try {
Connection conn = getConnection();
stmt = conn.createStatement();
insert = ("insert into element_groups values("
+ this.getGid(gname) + ","
+ eid.intValue()+"," +
pid.intValue()+ ")");
stmt.executeUpdate(insert);
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
A.1. GroupsBean.Java 84
/**
* Delete element from group
*
* @param gname The name of the Group
* @param eid Element ID
* @param pid The Project ID
* @throws Exception If user is not allowed to add users to the group
* @ejb.interface-method view-type = "remote"
*/
public void removeElementFromGroup(Integer eid,Integer pid, String gname) throws Exception{
String insert;
try {
Connection conn = getConnection();
stmt = conn.createStatement();
insert = ("delete from element_groups where eid="+eid.intValue()+" AND pid="+
pid.intValue()+" AND gid="+getGid(gname));
stmt.executeUpdate(insert);
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* Returns a Vector of all groups
*
* @return A vector of groups (only with Groupnames)
A.1. GroupsBean.Java 85
* @throws Exception If user is not allowed to
* @ejb.interface-method view-type = "remote"
*/
public Vector getAllGroups() throws Exception ,RemoteException {
String select = null;
Vector allgroups = new Vector();
Connection conn = getConnection();
if (conn != null) {
try {
stmt = conn.createStatement();
select = "select gid,gname,gdescription,gowner from groups";
rs = stmt.executeQuery(select);
while (rs.next()) {
String[] row = new String[4];
row[0] = rs.getString("gid");
row[1] = rs.getString("gname");
row[2] = rs.getString("gdescription");
row[3] = rs.getString("gowner");
allgroups.add(row);
}
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
A.1. GroupsBean.Java 86
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
}
return allgroups;
}
/**
* Returns a Vector of all group names
*
* @return A vector of groups (only with Groupnames)
* @throws Exception If user is not allowed to
* @ejb.interface-method view-type = "remote"
*/
public Vector getGroupName() {
Vector groups = new Vector();
Connection conn = getConnection();
if (conn != null) {
try {
A.1. GroupsBean.Java 87
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT gname FROM groups");
while (rs.next()){
String group = new String(rs.getString("gname"));
groups.add(group);
}
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
}
return groups;
}
/**
A.1. GroupsBean.Java 88
* Returns a Vector of all group names
*
* @return A vector of groups (only with Groupnames)
* @throws Exception If user is not allowed to
* @ejb.interface-method view-type = "remote"
*/
public Vector getGroupNamesOfElement(Integer eid, Integer pid) {
Vector groups = new Vector();
Vector gids = new Vector();
Connection conn = getConnection();
if (conn != null) {
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT gid FROM element_groups where eid="+
eid.intValue()+" AND pid="+pid.intValue());
while (rs.next()){
gids.add(new Integer(rs.getInt("gid")));
}
rs = stmt.executeQuery("SELECT gid, gname FROM groups");
while(rs.next()){
Integer i = new Integer(rs.getInt("gid"));
if(gids.contains(i)) groups.add(rs.getString("gname"));
}
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
A.1. GroupsBean.Java 89
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
}
return groups;
}
/**
*
* @param gid
* @param uid
* @return
* @ejb.interface-method view-type = "remote"
*/
public Vector getGroupNamesOfUser(Integer gid, Integer uid) {
Vector usergroups = new Vector();
Vector gids = new Vector();
Connection conn = getConnection();
if (conn != null) {
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT gid FROM groups_users where uid="+
uid.intValue()+" AND gid="+gid.intValue());
A.1. GroupsBean.Java 90
while (rs.next()){
gids.add(new Integer(rs.getInt("gid")));
}
rs = stmt.executeQuery("SELECT gid, gname FROM groups");
while(rs.next()){
Integer i = new Integer(rs.getInt("gid"));
if(gids.contains(i)) usergroups.add(rs.getString("gname"));
}
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
}
A.1. GroupsBean.Java 91
return usergroups;
}
/**
* Returns the Id of a given group
*
* @param user
* The groups name
* @return The Group id
*/
private int getGid(String group) throws Exception, RemoteException {
String select;
try {
Connection conn = getConnection();
stmt = conn.createStatement();
select = ("select gid from groups where gname =’" + group.trim() + "’");
rs = stmt.executeQuery(select);
if (rs.next()) {
return rs.getInt("gid");
} else
return 0;
} catch (Exception e) {
System.out.println(e.getMessage());
return 0;
}
}
/**
* Returns the Id of a given User
A.1. GroupsBean.Java 92
* @param user The user
* @return The Uid
*/
public int getUid(String uname) throws Exception, RemoteException {
String select;
try {
Connection conn = getConnection();
stmt = conn.createStatement();
select = ("select uid from users where username = ’" + uname + "’");
rs = stmt.executeQuery(select);
if (rs.next()) {
return rs.getInt("uid");
} else
return 0;
} catch (Exception e) {
System.out.println(e.getMessage());
return 0;
}
}
/**
* Checks if the Groupname is already used
* @param gName The name of the Group)
* @return true, if Groupname is unused, false else
*
*/
private boolean groupFree(String gname) throws Exception, RemoteException {
String select;
try {
Connection conn = getConnection();
A.1. GroupsBean.Java 93
stmt = conn.createStatement();
select = ("select * from groups where gname = ’" + gname.trim() + "’");
rs = stmt.executeQuery(select);
if (rs.next())
return false;
else
return true;
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}
}
/**
* Default create method
*
* @throws CreateException
* @ejb.create-method
*/
public void ejbCreate() throws CreateException {
}
/* (non-Javadoc)
* @see javax.ejb.SessionBean#ejbActivate()
*/
public void ejbActivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see javax.ejb.SessionBean#ejbPassivate()
*/
A.2. UsersBean 94
public void ejbPassivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see javax.ejb.SessionBean#ejbRemove()
*/
public void ejbRemove() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
*/
public void setSessionContext(SessionContext arg0) throws EJBException,
RemoteException {
// TODO Auto-generated method stub
}
}
A.2. UsersBean
/* $Id: UsersBean.java,v 1.10 2004/12/05 18:41:19 bassem Exp $ */
package login.ejb;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.sql.Connection;
A.2. UsersBean 95
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import java.util.Vector;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.EJBHome;
import javax.ejb.EJBObject;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
/**
* @author <a href="mailto:[email protected]">Bassem El-Ahmad </a>
*
* @ejb.bean name = "Users"
* display-name = "UsersBean EJB"
* description = "EJB inorder to manged the Users"
* view-type = "remote"
* jndi-name = "ejbs/Users"
*/
public class UsersBean implements SessionBean {
/** A commando for the database */
private Statement stmt = null;
A.2. UsersBean 96
/** database connection result */
private ResultSet rs = null;
/**
* Is the user logged in
*
* @uml.property name="loggedIn"
*/
private boolean loggedIn;
/**
*
* @uml.property name="pass"
*/
private String pass;
public UsersBean() {
super();
}
public Connection getConnection() {
Map map = null;
try {
Context context = new InitialContext();
Object ref = context.lookup("funcEJBS/Config");
EJBHome homeObject = (EJBHome) PortableRemoteObject.narrow(ref,
EJBHome.class);
Method createMethod = homeObject.getEJBMetaData()
.getHomeInterfaceClass()
.getMethod("create", new Class[] {});
EJBObject ejbObject = (EJBObject) createMethod.invoke(homeObject,
A.2. UsersBean 97
new Object[] {});
Method method = homeObject.getEJBMetaData()
.getRemoteInterfaceClass().getMethod("getDBConnectionData",
new Class[] {});
map = (Map) method.invoke(ejbObject, new Object[] {});
Class.forName((String) map.get("driver")).newInstance();
Connection conn = DriverManager.getConnection((String) map
.get("url"), (String) map.get("username"), (String) map
.get("password"));
return conn;
} catch (NamingException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
A.2. UsersBean 98
/**
* Adds a user
*
* @param user The username
* @param admin The admin who adds the user
* @throws Exception If user is not allowed to add an user or if user allready exists
*
* @ejb.interface-method view-type = "remote"
*/
public boolean addUser(String username, String realname, String email, String password) throws Exception {
String insert;
try {
Connection conn = getConnection();
if (this.userFree(username)) {
stmt = conn.createStatement();
insert = ("insert into users(username, realname, email, password) values(’"
+ username.trim()
+ "’,’"
+ realname.trim()
+ "’,’"
+ email.trim()
+ "’,’"
+ password.trim() + "’)");
stmt.execute(insert);
return true;
} else{
throw new Exception(username + " is allready in Database!");
}
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
A.2. UsersBean 99
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
return false;
}
/**
* Deletes a User
* @param user the user who is going to be deleted
* @param admin the admin who wants to delete the user (can be the user)
* @throws Exception If user is not allowed to delete user
*
* @ejb.interface-method view-type = "remote"
*/
public String deleteUser(Integer uid) throws Exception {
String result = "User Deleted";
A.2. UsersBean 100
String delete = null;
String select = null;
String toDelete = null;
try {
Connection conn = getConnection();
//User is deleted from the groups_users table
stmt = conn.createStatement();
stmt.executeUpdate("delete from groups_users where uid ="+uid.intValue());
//User is deleted from the user table
stmt = conn.createStatement();
stmt.executeUpdate("delete from users where uid ="+uid.intValue());
//All groups owned by user are deleted
stmt = conn.createStatement();
stmt.executeUpdate("select * from groups where gowner ="+uid.intValue());
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
A.2. UsersBean 101
stmt = null;
}
}
}
return result;
}
/**
* Updates data of a specific user
*
* @param username The (old) name of the user who is going to be updated
* @param user The new user data
* @param admin The admin who wants to change the Data
* @throws Exception If user is not allowed to update user or if new username allready exists
*
* @ejb.interface-method view-type = "remote"
*/
public void updateUser(String username, String realname, String email,
String password) throws Exception, RemoteException {
String update = null;
try {
Connection conn = getConnection();
if ((!(username.equals(username))) && this.userFree(username)) {
stmt = conn.createStatement();
update = "update users set username = ’" + username
+ "’, realname = ’" + realname + "’, email = ’" + email
+ "’ where uid = " + this.getUid(username) + ";";
stmt.executeUpdate(update);
} else
throw new Exception("Username " + username
+ " is allready in use");
}
catch (SQLException ex) {
A.2. UsersBean 102
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
}
/**
* Returns a User
* @param user The user
* @param admin The admin who wants the userdata (can be the user)
* @return A User
* @throws Exception If user is not allowed to get the user
*
* @ejb.interface-method view-type = "remote"
*/
public String[] getUser(String username) throws Exception, RemoteException {
String select = null;
A.2. UsersBean 103
String[] returnUser = null;
String str = null;
Statement stmt = null;
ResultSet rs = null;
String iproj = null;
try {
Connection conn = getConnection();
stmt = conn.createStatement();
select = "select username,realname,email from users where username = ’"+username+"’";
rs = stmt.executeQuery(select);
if (rs.next()) {
returnUser = new String[3];
returnUser[0] = rs.getString("username");
returnUser[1] = rs.getString("realname");
returnUser[2] = rs.getString("email");
} else
throw new Exception("User " + username + "does not exist");
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
A.2. UsersBean 104
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
return returnUser;
}
/**
* Returns a Vector of Users
*
* @return A vector of User objects (but only with the Usernames)
* @throws Exception If user is not allowed to
*
* @ejb.interface-method view-type = "remote"
*/
public Vector getAllUser() throws Exception, RemoteException {
String select = null;
Vector allUser = new Vector();
Connection conn = getConnection();
if (conn != null) {
try {
Statement stmt = conn.createStatement();
select = "select uid,username,realname,email from users";
A.2. UsersBean 105
rs = stmt.executeQuery(select);
while (rs.next()) {
String[] row = new String[4];
row[0] = rs.getString("uid");
row[1] = rs.getString("username");
row[2] = rs.getString("realname");
row[3] = rs.getString("email");
allUser.add(row);
}
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
}
return allUser;
A.2. UsersBean 106
}
/**
* Checks if a user exists and uses the correct password
* @param User The user
* @param password The password
* @return The user who is logged in
* @throws Exception If user is unable to login
*
* @ejb.interface-method view-type = "remote"
*/
public Integer login(String userName, String password) {
Integer result = new Integer(-1);
try {
Connection conn = getConnection();
stmt = conn.createStatement();
String sql = "SELECT uid FROM users" + " WHERE username=’"
+ userName + "’" + " AND password=’" + password + "’";
ResultSet rs = stmt.executeQuery(sql);
if (rs.next()) {
result = new Integer(rs.getInt("uid"));
rs.close();
stmt.close();
conn.close();
}
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
A.2. UsersBean 107
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
return result;
}
/**
* Checks if a user exists in group
* @param Username The user
* @param Groupname The groupname
* @return True if the user part the group else return false
* @throws Exception If user is unable to login
*
* @ejb.interface-method view-type = "remote"
*/
public boolean isUserinGroup(String username, String groupname) throws Exception,
A.2. UsersBean 108
RemoteException {
String sql = "select * from gruops, users where gruops.gname = \’"
+ groupname + "\’ ";
sql += " and group.gid = users.gid ";
sql += ("and user.username = \’" + username + "\’ ");
System.out.println(sql);
boolean ret = false;
ResultSet r = null;
try {
Connection conn = getConnection();
Statement select = conn.createStatement();
sql = new String(sql.getBytes("SJIS"), "8859_1");
r = select.executeQuery(sql);
ret = r.first();
select.close();
conn.close();
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
A.2. UsersBean 109
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
return ret;
}
/**
* Allows the admin to change an Users password
* @param user The user whos password is going to be change
* @param admin the admin
* @param password The new password
* @throws Exception If user is not allowed to set password
*
* @ejb.interface-method view-type = "remote"
*/
public void setpassword(String username, String admin, String password)
throws Exception, RemoteException {
String update = null;
try {
Connection conn = getConnection();
if (this.checkAdmin(admin)) {
stmt = conn.createStatement();
update = "update users set password = sha1(\"" + password
+ "\") where uid = " + this.getUid(username) + ";";
stmt.executeUpdate(update);
} else
throw new Exception(
"You are not allowed to change the password of user "
+ username);
}
catch (SQLException ex) {
A.2. UsersBean 110
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
}
/**
* Allows an user to change his password
* @param user The user who wants to change his passwod
* @param password The new password
* @throws Exception If user is not allowed to set password
*
* * @ejb.interface-method view-type = "remote"
*/
public void userSetpassword(String username, String password) throws Exception,
RemoteException {
String update = null;
try {
Connection conn = getConnection();
A.2. UsersBean 111
stmt = conn.createStatement();
update = "update users set password = sha1(\"" + password
+ "\") where uid = " + this.getUid(username) + ";";
stmt.executeUpdate(update);
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) {
rs = null;
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) {
stmt = null;
}
}
}
}
/**
* Returns the Id of a given User
* @param user The user
* @return The Uid
*
A.2. UsersBean 112
* @ejb.interface-method view-type = "remote"
*/
public int getUid(String username) {
int re_uid = -1;
try {
Connection conn = getConnection();
Statement select = conn.createStatement();
String sql = "select * from users where " + "users.username = \""
+ username + "\"";
sql = new String(sql.getBytes("SJIS"), "8859_1");
ResultSet res = select.executeQuery(sql);
if (res.first()) {
re_uid = res.getInt("uid");
}
select.close();
conn.close();
} catch (Exception err) {
System.out.println("Error in SQL query: " + err);
}
return re_uid;
}
/**
* Checks if the username is already used
* @param username The name of the User
* @return true, if username is unused, false else
*/
private boolean userFree(String username) throws Exception, RemoteException {
A.2. UsersBean 113
String select;
try {
Connection conn = getConnection();
stmt = conn.createStatement();
select = ("select * from users where username = ’" + username.trim() + "’");
rs = stmt.executeQuery(select);
if (rs.next())
return false;
else
return true;
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}
}
/**
*
* @uml.property name="loggedIn"
*/
public void setLoggedIn(boolean status) {
this.loggedIn = status;
}
/**
*
* @uml.property name="pass"
*/
public void setPassword(String pass) {
final String password = null;
this.pass = password;
A.2. UsersBean 114
}
/**
* Allows an Admin to set a new admin
*
* @param newAdmin The new admin
* @param admin The admin who wants to set the new Admin
* @throws Exception If user is not allowed to set a new admin
*/
public void setAdmin(String newAdmin, String admin) throws Exception,
RemoteException {
String update = null;
try {
Connection conn = getConnection();
if ( checkAdmin(admin)) {
if (!(this.userFree(newAdmin))) {
stmt = conn.createStatement();
update = "update users set adminflag = \"" + ’a’
+ "\" where uid = " + this.getUid(newAdmin) + ";";
stmt.executeUpdate(update);
} else
throw new Exception(newAdmin + " does not exist!");
} else
throw new Exception("You are not allowed to set new Admins");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
/**
* Checks if a user is a global admin
* @param admin The (potential) admin
A.2. UsersBean 115
* @return true if user is admin, false else
*/
private boolean checkAdmin(String admin) throws Exception, RemoteException {
String select = null;
try {
Connection conn = getConnection();
stmt = conn.createStatement();
select =
("SELECT * FROM users WHERE username = ’" + admin + "’ AND adminflag = a");
rs = stmt.executeQuery(select);
if (rs.next())
return true;
else
return false;
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}
}
/**
* Default create method
*
* @throws CreateException
* @ejb.create-method
*
*/
public void ejbCreate() throws CreateException {
A.2. UsersBean 116
}
/**
* (non-Javadoc)
*
* @see javax.ejb.SessionBean.ejbActivate()
*/
public void ejbActivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
/**
* (non-Javadoc)
*
* @see javax.ejb.SessionBean.ejbPassivate()
*/
public void ejbPassivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
/**
* (non-Javadoc)
*
* @see javax.ejb.SessionBean.ejbRemove()
*/
public void ejbRemove() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
A.3. PagesBean 117
/**
* (non-Javadoc)
*
* @see javax.ejb.SessionBean.setSessionContext(javax.ejb.SessionContext)
*/
public void setSessionContext(SessionContext arg0) throws EJBException,
RemoteException {
// TODO Auto-generated method stub
}
}
A.3. PagesBean
/* $Id: PagesBean.java,v 1.10 2004/12/10 20:02:35 bassem Exp $ */
package login.ejb;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import javax.ejb.CreateException;
A.3. PagesBean 118
import javax.ejb.EJBException;
import javax.ejb.EJBHome;
import javax.ejb.EJBObject;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
/**
* @author <a href="mailto:[email protected]">Bassem El-Ahmad</a>
*
* @ejb.bean name = "Pages"
* display-name = "PagesBean EJB"
* description = "EJB in order to managed the Page"
* view-type = "remote"
* jndi-name = "ejbs/Pages"
*/
public class PagesBean implements SessionBean {
private Connection conn;
public PagesBean() {
super();
// TODO Auto-generated constructor stub
}
public Connection getConnection() {
Map map = null;
try {
Context context = new InitialContext();
Object ref = context.lookup("funcEJBS/Config");
A.3. PagesBean 119
EJBHome homeObject = (EJBHome) PortableRemoteObject.narrow(ref,
EJBHome.class);
Method createMethod = homeObject.getEJBMetaData()
.getHomeInterfaceClass()
.getMethod("create", new Class[] {});
EJBObject ejbObject = (EJBObject) createMethod.invoke(homeObject,
new Object[] {});
Method method = homeObject.getEJBMetaData()
.getRemoteInterfaceClass().getMethod("getDBConnectionData",
new Class[] {});
map = (Map) method.invoke(ejbObject, new Object[] {});
Class.forName((String) map.get("driver")).newInstance();
Connection conn = DriverManager.getConnection((String) map
.get("url"), (String) map.get("username"), (String) map
.get("password"));
return conn;
} catch (NamingException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
A.3. PagesBean 120
e.printStackTrace();
}
return null;
}
/**
* detects whether a HTML element is visible or not
* @throws Exception if group allready exists
* @ejb.interface-method view-type = "remote"
*/
public Boolean isVisible(Integer userID,Integer projectID,Integer pageID,
Integer elementID,Vector pageHierarchy){
Vector userGroups = getGroupsForUser(userID.intValue());
Vector elementGroups = getGroupNamesOfElement(elementID,projectID);
if(elementGroups.size() == 0){
elementGroups = getGroupNamesOfElement(pageID,projectID);
}
if(elementGroups.size() == 0){
for(int i = 0; i < pageHierarchy.size() && elementGroups.size() == 0 ; i++){
Integer tmp = (Integer)pageHierarchy.elementAt(i);
elementGroups = getGroupNamesOfElement(tmp,projectID);
}
}
return new Boolean(compareGroups(userGroups,elementGroups));
}
private boolean compareGroups(Vector userGroups ,Vector elementGroups){
A.3. PagesBean 121
boolean result = false;
for (int i = 0; i < userGroups.size(); i++) {
if(elementGroups.contains(userGroups.get(i))){
result = true;
break;
}
}
return result;
}
private Vector getGroupsForUser(int uid){
Vector result = new Vector();
String sql = "select gid from groups_users where uid="+uid;
boolean ret = false;
ResultSet rs = null;
//Connection conn = null;
try {
//conn = getConnection();
Statement select = conn.createStatement();
rs = select.executeQuery(sql);
while(rs.next()){
result.add(new Integer(rs.getInt("gid")));
}
//iyad:temp loesung jeder User ist auch in der Gruppe
//anonymous mitglied, bessere Loesung mit SubGruppen
rs = select.executeQuery("select gid from groups where gname=’anonymous’");
if(rs.next()){
result.add(new Integer(rs.getInt("gid")));
}
} catch (Exception err) {
System.out.println(err.getMessage());
}
finally{
//try{
// conn.close();
A.3. PagesBean 122
//}catch(SQLException ex){
//}
}
return result;
}
private Vector getGroupNamesOfElement(Integer eid, Integer pid) {
Vector groups = new Vector();
Vector gids = new Vector();
ResultSet rs = null;
//Connection conn = getConnection();
if (conn != null) {
try {
Statement stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT gid FROM element_groups where eid="+
eid.intValue()+" AND pid="+pid.intValue());
while (rs.next()){
gids.add(new Integer(rs.getInt("gid")));
}
rs = stmt.executeQuery("SELECT gid, gname FROM groups");
while(rs.next()){
Integer i = new Integer(rs.getInt("gid"));
if(gids.contains(i)) groups.add(i);
}
}
catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
A.3. PagesBean 123
finally {
//try {
//conn.close();
//} catch (SQLException sqlEx) {
//}
}
}
return groups;
}
/**
* Default create method
*
* @throws CreateException
* @ejb.create-method
*/
public void ejbCreate() throws CreateException {
conn = getConnection();
System.out.println("dbConection created for PagesBean");
}
/* (non-Javadoc)
* @see javax.ejb.SessionBean.ejbActivate()
*/
public void ejbActivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see javax.ejb.SessionBean.ejbPassivate()
*/
A.3. PagesBean 124
public void ejbPassivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see javax.ejb.SessionBean.ejbRemove()
*/
public void ejbRemove() throws EJBException, RemoteException {
if(conn != null){
try{
conn.close();
}catch(Exception ex){
System.out.println("Exception while closing the database connection in "
+"PagesBean");
System.out.println(ex.getMessage());
}
}
System.out.println("PagesBean removed");
}
/* (non-Javadoc)
* @see javax.ejb.SessionBean.setSessionContext(javax.ejb.SessionContext)
*/
public void setSessionContext(SessionContext arg0) throws EJBException,
RemoteException {
// TODO Auto-generated method stub
}
}
Literaturverzeichnis
[JMS ] :
Java Message Service.
http://java.sun.com/products/jms/
[RMI ] :
The Java Remote Method Invocation.
http://java.sun.com/docs/books/tutorial/rmi
[JBoss ] :
JBoss Developer Zone.
http://www.jboss.org
[NBT ] :
Net Business Tool.
http://venus.cs.tu-berlin.de/
[PostgreSQL ] :
PostgreSQL.
http://www.postgresql.org/
[Rational ] :
Rational.
http://www.rational.com
[UML-Uebersicht ] :
Eine recht umfangreiche UML Uebersicht.
http://www.jeckle.de/unified.htm
[Servlet-Specification ] :
125
Literaturverzeichnis 126
Servlet Specification Version 2.4.
http://java.sun.com/products/servlet/
[Together-Technologies ] :
Together technologies.
http://www.togethersoft.com
[XDoclet ] :
What is XDoclet.
http://xdoclet.sourceforge.net/xdoclet/index.html
[Alhir 2003] Alhir, Sinan S. (Hrsg.):
Learning UML.
O’Reilly, 2003
[Balzert 2001] Balzert, Heide (Hrsg.):
UML kompakt.
Spektrum, 2001
[Bannert 1999] Bannert, Weitzel M. (Hrsg.):
Objektorientierter Softwareentwurf mit UML.
Addison-Wesley, 1999
[Denninger 2000] Denninger, S. (Hrsg.):
Enterprise JavaBeans.
Addison-Wesley, 2000
[Goodwill 2000] Goodwill, James (Hrsg.):
Pure JSP – Java Server Pages: A Code-Intensive Premium Reference.
Sams, 2000
[Jason Hunter 1998] Jason Hunter, William C. (Hrsg.):
Java Servlet Programming.
OReilly, 1998
[KOLB 2000] KOLB, DUANE K. FIELDS MARK A. (Hrsg.):
Web Development with JavaServer Pages.
Manning Publications Co, 2000
Literaturverzeichnis 127
[Kurniawann 2002] Kurniawann, Budi (Hrsg.):
Java for the Web with Servlets, JSP, and EJB: A Developer’s Guide to J2EE
Solutions.
New Riders Publishing, 2002
[Monson-Haefel 2000] Monson-Haefel, R. (Hrsg.):
2. Auflage Enterprise JavaBeans.
OReilly, 2000
[Perry 2004] Perry, Bruce W. (Hrsg.):
Java Servlet and JSP Cookbook.
O’Reilly, 2004
[Sams 1999] Sams (Hrsg.):
Sams Teach Yourself UML in 24 Hours.
Macmillan Computer Publishing, 1999
[Sullins und Whipple May 2003] Sullins, Benjamin G. (Hrsg.) ; Whipple,
Mark B. (Hrsg.):
EJB Cookbook.
Manning Publications Co, May 2003
[Turner March 27, 2002] Turner, James (Hrsg.):
MySQL and JSP Web Applications:ata-Driven Programming Using Tomcat and
MySQL.
Sams Publishing, March 27, 2002
[Zimmermann 2000] Zimmermann, J. (Hrsg.):
Verteilte Komponenten und Datenbankanbindung.
Addison-Wesley, 2000