Stage Eindwerk - Howest DSpace

advertisement
Stage
Eindwerk
Studiegebied
Bachelor
Afstudeerrichting
Academiejaar
Student
Handelswetenschappen en Bedrijfskunde
Toegepaste Informatica
2007-2008
Bram Gadeyne
Thema
Seam’s Like Future
Een onderzoek naar de toepasbaarheid van een framework in Java
Stageplaats
Dolmen
Huizingen & De Pinte
Stage
Eindwerk
Studiegebied
Bachelor
Afstudeerrichting
Academiejaar
Student
Handelswetenschappen en Bedrijfskunde
Toegepaste Informatica
2007-2008
Bram Gadeyne
Thema
Seam’s Like Future
Een onderzoek naar de toepasbaarheid van een framework in Java
Stageplaats
Dolmen
Huizingen & De Pinte
Woord Vooraf
Toegepaste Informatica aan de Hogeschool West-Vlaanderen… de richting waar ik mijn
kennis over informatica de laatste 3 jaar heb kunnen bijschaven. Aan het einde van de
boeiende weg kwam de mogelijkheid om alle vergaarde kennis om te zetten in de praktijk.
Ik ging hiervoor op zoek naar een informaticabedrijf die naast een grote omvang en een
goede naam ook al een langere tijd actief is op de markt. Ook wou ik dat mijn stage me kijk
gaf op nieuwe technologieën en technieken in de programmeertaal Java.
Ik wil allereerst Bart Van Loocke bedanken die me het bedrijf Dolmen aanraadde. Zij
voldeden perfect aan mijn vereisten. Ze waren ook zeer enthousiast om mij een stage aan te
bieden.
Bij Dolmen liep ik een boeiende en leerrijke stage. Hiervoor wil ik dan ook mijn mentors
Hans De Neve en Frederik Dierickx bedanken voor de hulp die ze me boden gedurende mijn
stage. Ook mijn stagegever Silvia Di Bono wil ik bedanken voor de eerste ervaring met een
sollicitatiegesprek en de mogelijkheid die ze me bood om stage te lopen bij Dolmen.
Daarnaast wil ik ook mijn stagebegeleider Corneel Theben Tervile bedanken voor de
begeleiding vanuit de hogeschool.
Ook wil ik mijn medestagiaire Lisa Van Daele en alle medewerkers van Dolmen van harte
bedanken voor de toffe werksfeer die de stage aangenamer maakte. Voornamelijk Tim
Vandeplas die me technisch bijstond als ik een probleem had. Ook Pascal Vandaele waarmee
ik het grootste deel van de tijd in De Pinte het bureau deelde en waarmee ik vele
aangename gesprekken heb gehad.
De grootste groep mensen die mij geholpen hebben, zijn mensen die ik nog nooit heb gezien
en enkel ken via hun fictieve naam op het internet. Ik heb het hier over alle mensen die
topics hebben behandeld op het JBoss forum en de ontwikkelaars van JBoss Seam of andere
JBoss frameworks die via de JIRA sites oplossingen zochten en gaven voor problemen.
Ook al was mijn stage geen groepsopdracht, de uitwerking zou zonder alle hier boven
vernoemde mensen niet realiseerbaar geweest zijn.
Eindwerk Bram Gadeyne
Samenvatting
Programmatie van grote enterprise webapplicaties is de dag van vandaag een hot topic in de
programmeerwereld. Iedereen heeft er in de Java-wereld zo zijn eigen visie over. Men maakt
gebruik van verschillende frameworks die bepaalde functies voor de gewenste applicaties
aanbieden of voorzien in een volledige basisarchitectuur voor de applicatie. Door het gebruik
van verschillende frameworks door elkaar verliest de applicatie op zich soms wat aan
structuur. Sommige frameworks leggen zelfs bewust de Java-standaarden naast zich neer.
Maar net naar die standaarden en compatibiliteit tussen verschillende frameworks is er een
grote vraag.
Het Seam project van “JBoss, a devision of red hat” is een veelbelovend framework die een
uitstekende oplossing kan bieden voor dit probleem. Eigenlijk is het doel van Seam om vaak
gebruikte onderdelen zoals authenticatie, webpagina’s (view), business logica (EJB 3.0),
testing, logging, mail afhandeling, creatie van PDF’s, databankondersteuning (met
persistence), enz … te bundelen en direct, gemakkelijk en zonder al te veel configuratie
beschikbaar te maken voor de programmeur. Web 2.0 compatibiliteit wordt voorzien door
het gebruik van Richfaces die een uitstekende ondersteuning biedt voor AJAX.
De integratie van deze frameworks en de webapplicatie architectuur werden uitgetest aan
de hand van een competentie management systeem. Via verworven competenties kunnen
werknemers bepaalde functies of opdrachten toegewezen krijgen waarvoor ze de benodigde
competenties bezitten. Competenties kunnen verworven worden na het volgen van
opleidingen van Dolmen of zelfstudie.
“Seam’s like Future” is zeker geen misplaatste uitspraak bij dit framework. Seam maakt veel
kans om in de toekomst heel vaak te worden gebruikt door de eenvoud en de grote
productiviteit die het met zich meebrengt. Het succes van Seam kun je terugvinden bij de
WebBeans. Dit is eigenlijk de standaard die uit Seam is voortgevloeid.
Eindwerk Bram Gadeyne
Abstract
Programming giant enterprise wide web applications is nowadays a hot topic in the world of
programming. Everyone in the Java-world has his own view on creating them. They use
different frameworks which provide some functions for the desired web application. Or they
provide a full basic architecture for it. Due to the use of different frameworks together, the
application loses some of its structure. Some frameworks even consciously ignore the Javastandards. Nowadays there is a great demand for these standards and compatibility
between different frameworks.
The Seam project of “JBoss, a devision of red hat” is a promising framework which can
provide a very good solution for these problems. In fact the goal of Seam is to bundle and
provide rapid and easy access without to many configurations to the frameworks for the
programmers. Examples of these frameworks are authentication, WebPages (view), business
logic (EJB 3.0), testing, logging, mail handling, creating PDF files, database access (with
persistence), … Web 2.0 compatibility is added by the use of Richfaces which provides a very
good support for AJAX.
The integration of these frameworks and the web application architecture were tested by a
competence management program. By means of the gained competences employees can
be assigned to some functions or tasks for which they have the competences needed. These
competences can be gained by Dolmen trainings or by self-study.
“Seam’s like Future” is not a wrongly placed expression for this framework. Seam has many
opportunities to be used in the future by its simplicity and the great productivity it provides.
The success of Seam can be found with the WebBeans. This is actually the standardisation of
Seam.
Eindwerk Bram Gadeyne
Verklarende Woordenlijst
Term
AJAX
Uitleg
Is een afkorting voor assynchronious javascript and xml. De bedoeling van
Ajax is om vragen en antwoorden asynchroon te kunnen verzenden en
ontvangen van client naar server. Asynchroon wil zeggen dat de client niet
zal wachten op het antwoord van de server maar dat hij de verwerking van
het antwoord zal doen wanneer het antwoord terug bij de client toekomt.
De gebruiker kan dus ondertussen verderwerken met de applicatie.
Door het gebruik van XML, waarop HTML ook is gebaseerd, en javascript
kunnen stukken HTML vervangen worden door andere zonder dat de
pagina door de webbrowser volledig opnieuw moet worden geladen.
Hierdoor krijg je het effect alsof je op een gewone desktop applicatie aan
het werken bent.
Bindings
In JSF gebruikt men vaak bindings om een bepaalde waarde te koppelen
aan een object. Die koppeling op zich klinkt simpel maar dankzij JSF moet er
geen rekening meer gehouden worden met het gebruik van POST of GET
variabelen of andere manieren om data uit bijvoorbeeld een tekst veld in
een bepaalde value van een object op te slaan.
CORBA
Common Object Request Broker Architecture, is een standaard voor de
communicatie
tussen
objecten,
geschreven
in
verschillende
programmeertalen en draaiend op verschillende machines. ORB's (Object
Request Brokers) worden geleverd door verschillende bedrijven en zijn
gebaseerd op IIOP (Internet Inter Orb Protocol), waardoor in principe
clients en servers, onafhankelijk van de gebruikte ORB, met elkaar kunnen
praten.
EL (Expression Dit is een onderdeel van JSF die het mogelijk maakt om bindings te maken
Language)
tussen een JSF pagina en backing beans. Met EL kun je ook berekeningen
uitvoeren of bepaalde voorwaarden controleren in een JSF pagina.
Framework
Een Framework bestaat meestal uit een aantal objecten of packages die
voorzien in bepaalde functionaliteiten voor een applicatie. Het is eigenlijk
een verzameling van code die ter beschikking wordt gesteld van andere
programmeurs zodat ze voor dezelfde problemen de al gevonden
oplossingen kunnen gebruiken. Sommige frameworks voorzien ook in een
goede integratie van een bepaalde applicatie architectuur.
JIRA-sites
Dit is een groep van Bug Tracking sites. Ze worden gebruikt om van een
bepaald project bugs te kunnen beheren. Je kunt er dan ook zien wie met
welke bugs bezig is en of er eventueel al oplossingen voor gevonden zijn.
Eindwerk Bram Gadeyne
Loosely
Coupled
Objecten zijn lously coupled als ze elkaar via een interface kunnen
benaderen en geen effectieve referentie naar elkaar moeten bijhouden. Op
die manier kunnen gedragingen of implementaties van objecten
gemakkelijk veranderd worden at runtime.
POJO
Is een afkorting voor een Plain Old Java Object. Dit is eigenlijk een andere
naam voor een gewone basis Java klasse.
Proven
Technologie
Technologie waarvan de bedrijfswereld vindt dat ze zichzelf al meerdere
malen heeft bewezen. Meestal gaat dit gepaard met grote projecten die
een bepaald framework of techniek als referentie kan opgeven.
Web 2.0
Web 2.0 is een begrip die binnen de webwereld de laatste tijd veel gebruikt
wordt. Helaas bestaat er geen echte definitie van Web 2.0 omdat Web 1.0
nooit is beschreven en omdat Web 2.0 een toekomstvisie is zoals men
graag de websites naar een nieuw niveau zou willen laten zien veranderen.
Dankzij frameworks als Richfaces die gebruik maken van Ajax om hun
componenten af te laten beelden en laten samenwerken met elkaar krijg je
al een mooi voorbeeld van hoe Web 2.0 eruit zou kunnen zien.
PO
Een persoonlijke overleg tussen een chef en een medewerker.
Eindwerk Bram Gadeyne
Inhoudsopgave
Woord Vooraf .......................................................................................................................... 4
Samenvatting ........................................................................................................................... 5
Abstract .................................................................................................................................... 6
Verklarende Woordenlijst ...................................................................................................... 7
Inhoudsopgave ......................................................................................................................... 9
1
Voorstelling van het bedrijf ........................................................................................... 12
2
Stageopdracht ................................................................................................................. 14
3
Analyse ............................................................................................................................ 15
3.1
Doelstelling .............................................................................................................. 15
3.2
Bestaande situatie ..................................................................................................... 15
3.3
Functionele eisen ...................................................................................................... 16
3.4
Niet-functionele eisen .............................................................................................. 17
3.5
Randvoorwaarden ..................................................................................................... 17
3.6
Use case diagrams .................................................................................................... 17
3.6.1
Beheer Competentiefiche.................................................................................. 18
3.6.2
Beheer Opleiding .............................................................................................. 19
3.6.3
Beheer Actieplan .............................................................................................. 20
3.6.4
Beheer Functiebeschrijving .............................................................................. 21
3.7
Rapporten ................................................................................................................. 22
3.8
Beschrijving gebruikers ............................................................................................ 22
3.8.1
Personeelsverantwoordelijke ............................................................................ 23
3.8.2
Personeelssecretariaat ....................................................................................... 23
3.8.3
Chef................................................................................................................... 23
3.8.4
Medewerker ...................................................................................................... 23
3.9
Rechten gebruikers ................................................................................................... 23
4
Ontwerp........................................................................................................................... 24
4.1
Logisch ..................................................................................................................... 24
4.1.1
Data-analyse / Datamodel ................................................................................. 25
4.1.2
Objectgeoriënteerd model ................................................................................. 26
4.2
Architectuur .............................................................................................................. 30
4.2.1
Application Architecture .................................................................................. 30
4.2.2
Platformonafhankelijkheid ............................................................................... 31
4.3
Technisch ................................................................................................................. 32
4.3.1
Java 5 ................................................................................................................ 33
4.3.2
EJB 3.0 .............................................................................................................. 34
4.3.3
JSF .................................................................................................................... 37
4.3.4
Seam ................................................................................................................. 41
4.3.5
Rich Web Applications (Web 2.0).................................................................... 45
4.3.6
Seam Logging ................................................................................................... 54
Eindwerk Bram Gadeyne
5
Seam Mail ......................................................................................................... 55
4.3.7
4.3.8
Seam Timer ....................................................................................................... 56
4.3.9
Seam Timer met Seam Mail ............................................................................. 57
4.3.10 Seam authenticatie ............................................................................................ 57
4.3.11 Seam Fileupload/filedownload ......................................................................... 58
4.3.12 Seam Taalondersteuning ................................................................................... 61
4.3.13 Persistence – Hibernate..................................................................................... 61
4.3.14 Rapportering ..................................................................................................... 64
4.3.15 Testing .............................................................................................................. 66
4.3.16 Exception handling ........................................................................................... 69
4.3.17 Servers .............................................................................................................. 69
Programmatie ................................................................................................................. 73
5.1
Gebruikte hardware .................................................................................................. 73
5.2
Gebruikte software ................................................................................................... 73
5.2.1
Besturingssystemen .......................................................................................... 73
5.2.2
Servers .............................................................................................................. 73
5.2.3
IDE .................................................................................................................... 74
5.2.4
Programmeertalen ............................................................................................. 75
5.2.5
Tekstverwerkers ................................................................................................ 75
5.2.6
Beeldverwerker ................................................................................................. 76
5.2.7
Varia ................................................................................................................. 76
5.3
Een nieuw project starten ......................................................................................... 77
5.3.1
Installatie van Eclipse ....................................................................................... 78
5.3.2
Installatie van de JBoss Tools........................................................................... 79
5.3.3
Installatie van de Seam Runtime ...................................................................... 82
5.3.4
Creatie van een nieuw Seam project. ................................................................ 83
5.3.5
Het project starten ............................................................................................. 94
5.3.6
Werken met de JBoss Tools ............................................................................. 95
5.3.7
Richfaces drag and drop demo ......................................................................... 95
5.4
Algoritmes ................................................................................................................ 98
6
Bespreking van het programma .................................................................................. 100
6.1
Gebruikershandleiding ........................................................................................... 100
6.1.1
Gebruikerstypes .............................................................................................. 100
6.1.2
Algemeen ........................................................................................................ 100
6.1.3
Het admin paneel ............................................................................................ 106
6.1.4
Het Gebruiker Menu ....................................................................................... 113
6.2
Installatiehandleiding Windows ............................................................................. 120
6.3
Installatiehandleiding Linux ................................................................................... 120
7
Conclusies ...................................................................................................................... 121
8
Kritische Reflectie ........................................................................................................ 123
9
Voor akkoord verklaard .............................................................................................. 124
10
Literatuurlijst ............................................................................................................... 125
10.1
10.2
Boeken .................................................................................................................... 125
Webpagina’s ........................................................................................................... 125
11
Bijlagen .......................................................................................................................... 126
11.1
11.2
11.3
11.4
Installatie onder Windows ...................................................................................... 126
Installatie onder Linux ........................................................................................... 146
Actierapport ............................................................................................................ 162
Functiebeschrijving rapport.................................................................................... 164
1 Voorstelling van het bedrijf
Dolmen is een informaticadienstverlener die inmiddels reeds meer dan 20 jaar actief is op de
Belgische markt. Ongeveer 850 medewerkers realiseren er samen een omzet van 138 miljoen
euro. Als toonaangevend informaticabedrijf is het voor vele organisaties uit diverse sectoren de
vaste hard- en softwarepartner geworden.
Ontsproten in de schoot van Colruyt heeft het bedrijf gedurende heel haar bestaan een maturiteit
en stabiliteit opgebouwd die zich ondermeer vertaalt in een duidelijke missie en een set van
corporate values waar elke werknemer van Dolmen zich naar spiegelt. De missie, waarden en
historiek bepalen Dolmens herkenbare bedrijfscultuur.
Dolmens producten en diensten situeren zich binnen tal van informaticadomeinen. De focus ligt
op het aanbieden van geïntegreerde totaaloplossingen op basis van de noden van de klant. Dit
zowel op infrastructureel als op applicatiegebied.
Dolmen telt 7 vestigingen
Corporate Headquarter
Industriezone Zenneveld
A. Vaucampslaan 42
1654 Huizingen
Dolmen Brussel
Bruidstraat 11
1000 Brussel
Dolmen De Pinte
Grote Steenweg 15
9840 De Pinte
Dolmen Harelbeke
Kortrijksesteenweg 307
8530 Harelbeke
Dolmen Kontich
Veldkant 33B
2550 Kontich
Dolmen Namur
Rue de Gembloux 9A
5080 Rhisnes
Dolmen Turnhout
Steenweg op Mol 148
2360 Oud-Turnhout
Eindwerk Bram Gadeyne
2007-2008
12
In 2 van deze vestigingen, namelijk in De Pinte en in Huizingen (Corporate Headquarters), liep ik
stage.
Dolmen De Pinte
Dolmen Huizingen
Dolmen levert een groot aantal diensten die allen kunnen gevraagd worden door de klant.
Daarnaast levert Dolmen ook totaaloplossingen waarbij ze op allerlei domeinen een zo goed
mogelijke uitwerking van de vraag proberen te verzekeren.
In onderstaande figuur kun je alle services terugvinden. Ze zijn weergegeven op 2 assen die ze in
verschillende domeinen opdeelt.
•
•
de horizontale as:
o Projects zijn eenmalig en bepaald in de tijd, met een vaste begin- en einddatum
o Exploitation, ook de ‘Managed Services’ genoemd, is een continu proces
de verticale as:
o Tactical omvat het sturende
o Operational duidt op het uitvoerende
schema
services
Dolmen biedt 3 grote
groepen services aan.
•
•
•
Eindwerk Bram Gadeyne
2007-2008
Applications
Services
Education
Services
Infrastructure
Services
13
2 Stageopdracht
De stageopdracht waarvoor ik solliciteerde legde sterk de nadruk op het idee van Web 2.0. Dit is
weliswaar geen term die een echte betekenis heeft. Web 2.0 houdt eigenlijk in dat webapplicaties
evolueren naar applicaties die eerder lijken op gewone desktop applicaties waarbij webpagina’s
niet moeten herladen worden om extra onderdelen van de applicatie op te roepen.
De opdracht bestond er in een nieuw framework te onderzoeken genaamd Seam. Dit java
framework is gebaseerd op enkele java standaarden. Het is naast het dichter brengen van het idee
van web 2.0 ook de bedoeling van Seam om meer standaarden opnieuw te gebruiken en een
goede integratie ertussen te voorzien.
De integratie van web 2.0 zal vooral gebeuren door het gebruik van AJAX. Dit is de afkorting van
“Asynchronous JavaScript and XML” en maakt het mogelijk om stukken HTML code te vervangen
zonder daarvoor de pagina opnieuw te moeten laden. Hiervoor maakt Seam ook weer gebruik van
frameworks waaronder het Richfaces framework. Dit maakt het mogelijk om rich internet
applications te maken.
Deze technische analyse zette ik dan om naar de praktijk door een competentie management
system te maken. Momenteel worden competenties van medewerkers en functiebeschrijvingen
bijgehouden bij de chefs op papier. Men wil hier echter een geautomatiseerde applicatie voor
gebruiken zodat deze registraties allemaal ongeveer gelijk worden bijgehouden en digitaal kunnen
worden opgeslagen.
Omdat de stageopdracht vooral over de technische analyse ging kreeg ik van Dolmen een
funcionele analyse. Deze analyse heb ik in de loop van het programmeren van de webapplicatie
deels aangepast.
Het analysedossier droeg de naam “Project ComMaS” wat een afkorting is voor Competence
Management System. ComMaS is dan ook de naam die het uiteindelijke programma gekregen
heeft.
Eindwerk Bram Gadeyne
2007-2008
14
3 Analyse
Onder dit hoofdstuk vind je een stuk terug uit de functionele analyse die ik ontving van Dolmen.
Dit zou je een overzicht moeten geven van wat er van de uiteindelijke applicatie precies verwacht
werd. Sommige onderdelen van de analyse heb ik tijdens mijn stage wat bijgestuurd en deze
worden dan ook toegelicht.
3.1
Doelstelling
Naast de technische analyse die ik moest uitvoeren, was er ook het omzetten van deze functionele
analyse in de praktijk. De competence management applicatie die ik hiervoor ontwikkelde had een
aantal doelstellingen voor de onderneming.
• Een competentere medewerker.
Medewerkers kunnen competenties verwerven aan de hand van de vraag van
klanten of aan de hand van persoonlijke voorkeuren om bijvoorbeeld verder te
kunnen groeien in de onderneming. Als we een overzicht hebben van de huidige
competenties kunnen we sneller en beter de medewerker competenter maken om
aan deze vragen te voldoen.
• Een betere opvolging wie welke opleiding volgde.
Opleidingen die door Dolmen georganiseerd worden moeten kunnen worden
weergegeven en gebruikers moeten er kunnen toegevoegd worden aan sessies. Op
die manier is er altijd een overzicht van wie waar en wanneer welke opleiding in het
verleden volgde of in de toekomst zal volgen.
• Beheer van de actieplannen.
Medewerkers binnen Dolmen hebben een actie plan die acties bevat om bijvoorbeeld
competenties te verwerven. Deze acties moeten digitaal beschikbaar gemaakt
worden.
o Mogelijkheid tot aanvullen van de competentiefiches met extra competenties.
Competentiefiches bevatten verzamelingen van competenties en moeten
dus kunnen worden uitgebreid indien nodig.
3.2
Bestaande situatie
Voor alle verschillende functies binnen Dolmen bestaan er functiebeschrijvingen. Deze
functiebeschrijving omvat de hoofdtaken, plaats in de organisatie en de nodige competenties.
Competenties zijn op te splitsen in technische competenties (kennen, bvb J2EE) en
gedragscompetenties (kunnen, bvb klantgerichtheid).
Bij competentiemanagement is het de bedoeling om mensen te laten groeien en evolueren.
Tijdens een persoonlijk onderhoud wordt de eigen competentie afgewogen ten opzichte van het
functieprofiel. Vanuit deze evaluatie wordt gekeken waar er eventueel tekortkomingen zitten en
waar er bijsturingen en evoluties dienen te gebeuren. Ook het doorgroeien naar andere profielen
wordt op deze manier georganiseerd. (interne jobrotatie)
Indien er bijsturingen noodzakelijk zijn kunnen er opleidingen worden gevolgd, coaching
georganiseerd en/of learning on the job worden toegepast. Er zijn interne en externe opleidingen,
Eindwerk Bram Gadeyne
2007-2008
15
georganiseerd door de chef zelf, door educ en door HR. Er zijn technische trainingen,
vaardigheidstrainingen en persoonlijke groeitrainingen. Sommige van deze trainingen worden in
eigen tijd andere in betaalde tijd gevolgd. Van sommige opleidingen bestaan evaluaties en
actieplannen voor follow up. Er kunnen tevens certificaten gehaald worden op het einde van
sommige opleidingen.
De competentieprofielen zelf worden door de personeelsdienst beheerd in nauw overleg met de
betrokken chefs.
De huidige manier van werken is volledig uitgeschreven in ISO procedures. De gebruikte ISO
procedures:
•
•
•
•
•
•
PS-DOCB-ALG-004 (Beheersproces competence management)
PR-OPBY-ALG-004 (Persoonlijk onderhoud)
PR-DOCB-ALG-003 (Beheer competenties)
PR-OPLI-ALG-002 (Opleiding)
PR-OPLI-ALG-001 (Opleiding van medewerkers)
Voorbeelden van competentiefiches en functiebeschrijvingen
Er zijn een aantal problemen met de huidige manier van werken:
1.
2.
3.
4.
3.3
Geen eenduidige plaats waar iemands competentieprofiel wordt bijgehouden
Geen opvolging van groei en evolutie van de medewerker
Geen overzicht van wie welke opleidingen gevolgd heeft
Geen eenvoudige opvolging van de actieplannen in het kader van competentie
management mogelijk
Functionele eisen
•
•
•
•
•
•
Beheer competenties
o Er moet een overzicht bijgehouden worden van alle competenties die
functiebeschrijving, een opleiding of een medewerker kan bevatten. Deze lijst van
competenties moet kunnen worden aangepast.
Beheer functiebeschrijvingen en –profielen
o Functiebeschrijvingen moeten in een centrale plaats kunnen worden beheert zodat
elke functie in het programma dezelfde betekenis heeft.
Beheer opleidingen
o Dolmen organiseert opleidingen die moeten kunnen weergegeven worden en
waarvoor medewerkers moeten kunnen ingeschreven worden. Medewerkers
kunnen ook opleidingen volgens buiten Dolmen die dan ook weer moeten kunnen
worden bijgehouden.
Beheer acties
o Actieplannen van medewerkers moeten kunnen worden bijgehouden.
Beheer PO verslagen
o PO staat voor persoonlijk overleg. Van alle persoonlijke overleggen tussen chef en
medewerker moet er een verslag kunnen worden bijgehouden.
Beheer klantentevredenheidsonderzoeken
Eindwerk Bram Gadeyne
2007-2008
16
o Een chef kan na een project van een klant een klantentevredenheidsonderzoek
ontvangen. Die kunnen worden bijgehouden bij de medewerker die aan dit project
meewerkte ter referentie.
Niet-functionele eisen
3.4
•
•
•
•
•
3.5
Randvoorwaarden
•
•
•
•
3.6
Gebruiksvriendelijke interface
Informatie eenvoudig te raadplegen
Beperkte offline mogelijkheden. Dienen offline te kunnen worden geraadpleegd:
Compententiefiche, Actieplan, PO verslagen, Klantentevredenheidsonderzoeken,
Functieprofielen, Gevolgde opleidingen (allemaal in functie van een PO).
Er moet snel aan actieplannen kunnen gewerkt worden
De taal van de applicatie moet volgens Dolmen-standaarden gerealiseerd worden. De
applicatie wordt in het Engels opgebouwd, maar de velden kunnen in het Nederlands en
Frans worden weergegeven.
De personeelsdatabank is een Oracledatabank.
De servers van Dolmen werken met Windows 2003.
De applicatie zal moeten werken via de Portal van Dolmen (ook via Windows 2003)
De applicatie kan gebruik maken van de Single Sign-on van de Portal.
Use case diagrams
In de Functionele analyse die ik ontving van dolmen waren alle use cases en use case diagrams
gegeven. Deze heb ik dan ook zo goed mogelijk proberen te integreren in mijn applicatie.
Hieronder vind je een overzicht terug van de use case diagrams die in de analyse terug te vinden
waren om een idee te krijgen van de scope van de applicatie. De Use Cases zelf heb ik niet
opgenomen in dit stageverslag omdat dit niet in de scope van dit verslag thuishoort.
Eindwerk Bram Gadeyne
2007-2008
17
uc Use Case model
Beheer
Functiebeschrijving
PersVA
Beheer
Competentiefiche
Chef
Beheer actieplan
CVappl
Medewerker
Beheer opleiding
PersSec
3.6.1 Beheer Competentiefiche
Het beheer van de competentiefiches is waarschijnlijk het belangrijkste onderdeel van de
applicatie. Dit houdt alle functionaliteiten in die te maken hebben met de relatie tussen Chef en
medewerker. Het beheer van de competenties per medewerker wordt hierin voorzien, samen met
het invoeren van de PO verslagen en de klantentevredenhedenheidsonderzoeken.
Eindwerk Bram Gadeyne
2007-2008
18
uc Use Case Beheer Competentiefiche
Bewerk
Functie In
Competentiefiche
Chef
Voeg
Competentie Toe Aan
Competentiefiche
Toevoegen
klantentevredenheid
Vul
Competentiefiche In
Voer PO
verslag in
Bewerk
KlantenTevredenheidsonderzoeken
Bewerk PO
verslag
Medewerker
3.6.2 Beheer Opleiding
Opleidingen voor medewerkers zijn opgesplitst in 2 grote groepen. Een medewerker kan
opleidingen volgens in zijn vrije tijd. Daarnaast voorziet Dolmen echter ook zelf opleidingen om
zijn medewerkers bij te scholen.
Het beheer van deze opleidingen wordt door deze use case diagram aangegeven.
Eindwerk Bram Gadeyne
2007-2008
19
uc Beheer opleiding
Voeg Eigen
Opleiding Toe
Medewerker
Toevoegen
Opleiding
Chef
Toevoegen
Medewerker aan
opleidingssessie
PersSec
3.6.3 Beheer Actieplan
Het opstellen van acties binnen de applicatie is beschikbaar met als doel om aandachtspunten
voor de toekomst niet uit het oog te verliezen. Elke actie heeft een deadline voor uitvoering ervan.
Een actie kan bijvoorbeeld het resultaat zijn van een aantal besproken punten in een persoonlijk
overleg tussen een chef en een medewerker.
Eindwerk Bram Gadeyne
2007-2008
20
uc Beheer actieplan
Medewerker
Chef
Aanmaken
acties
Bewerken
acties
PersVA
3.6.4 Beheer Functiebeschrijving
De functiebeschrijvingen bestaan uit 2 delen. Het ene deel omvat de beschrijving zelf waarin de
talen van een bepaalde functie worden opgegeven. Daarnaast is er nog een functieprofiel die bij
een functiebeschrijving hoort. In dit profiel worden de competenties waarover een medewerker
moet beschikken weergegeven.
Tijdens een PO kunnen medewerker en chef dan bekijken of een bepaalde medewerker aan de
richtlijnen van een bepaalde functie zou voldoen of welke competenties die nog moet verwerven
alvorens dit mogelijk is. Dit is dus vooral bedoeld om het doorgroeien binnen Dolmen af te kunnen
stellen op de noden en eisen van de medewerker zelf.
Eindwerk Bram Gadeyne
2007-2008
21
uc Use Case Beheer Functiebeschrijving
Creëer
Functiebeschrijving
PersVA
Bewerk
Functiebeschrijving
Creëer
Competentie
Bewerk
Functieprofiel
Ken Score Toe
Chef
3.7
Rapporten
Naast het bijhouden van de informatie in het systeem moest het ook mogelijk zijn om een aantal
rapporten te genereren die dan konden worden afgeprint. Een aantal voorbeelden van rapporten
zijn terug te vinden in de bijlagen.
Dit is nodig voor volgende onderdelen:
•
•
•
•
•
3.8
Competentiefiches van medewerkers
Actielijsten
Lijsten van gevolgde opleidingen van een medewerker
PO verslagen van een medewerker
Functieprofielen
Beschrijving gebruikers
Van het systeem moesten enkele gebruikersgroepen gebruik kunnen maken. Deze gebruikers zijn
ook terug te vinden op de use case diagrams. De beschrijving van deze gebruikersgroepen wordt
hier wat meer toegelicht.
Eindwerk Bram Gadeyne
2007-2008
22
3.8.1 Personeelsverantwoordelijke
Een personeelsverantwoordelijke heeft toegang tot alle documenten met betrekking tot
competentiebeheer. Hij kan tevens een aantal zaken doen. Zo kan een
personeelverantwoordelijke enkele acties aanmaken en bewerken in het actieplan van een
medewerker. Net als een chef kan hij een functieprofiel bewerken. Een
personeelsverantwoordelijke is verantwoordelijk voor het opstellen van een functiebeschrijving en
een functieprofiel. Hij kan ook als enige een functiebeschrijving bewerken.
3.8.2 Personeelssecretariaat
Het personeelssecretariaat voegt opleidingen toe die georganiseerd worden door de HR afdeling.
Daarnaast kan ook het personeelssecretariaat mensen inschrijven voor opleidingen.
3.8.3 Chef
De chef is verantwoordelijk voor heel wat zaken binnen de applicatie. De chef is de meest
betrokken gebruiker van het systeem. Hij beheert de competentiefiches en actieplannen van zijn
medewerkers. Hij is tevens betrokken bij het opstellen en beheren van de functiebeschrijvingen (in
samenspraak met de personeelsverantwoordelijke). De chef is ook verantwoordelijke voor het
toekennen van de scores aan de functieprofielen.
3.8.4 Medewerker
Een medewerker kan acties toevoegen en beheren aan zijn actieplan. Bij het
klantentevredenheidsonderzoek en het PO (persoonlijk overleg) verslag, is er een mogelijkheid
voorzien waarin de medewerker opmerkingen kwijt kan over de documenten.
3.9
Rechten gebruikers
Binnen de ComMaS (Competence Management System) applicatie zal de hiërarchie van Dolmen
gerespecteerd worden. Elke actie die een medewerker kan uitvoeren is ook beschikbaar voor zijn
directe chef. Iedereen die hoger in de hiërarchie staat kan alles wat de gebruikers onder hem
kunnen. Daarnaast kunnen ook de personeelsverantwoordelijken alles uitvoeren voor alle
medewerkers.
Bij het toevoegen van medewerkers aan opleidingssessies kunnen ook chefs die in dezelfde
afdeling zitten medewerkers selecteren van andere chefs.
Eindwerk Bram Gadeyne
2007-2008
23
4 Ontwerp
4.1
Logisch
Een datamodel was gegeven in de analyse van Dolmen. Helaas was dit model nog niet volledig. Bij
de functionele analyse zaten al schermen die de applicatie beschreven en toonden hoe men
verwachtte dat deze er ongeveer uit zouden gaan zien. Om sommige schermen te maken of extra
functionaliteiten toe te voegen heb ik soms het datamodel moeten aanpassen.
Ik heb in het begin van mijn stage al deze schermen overlopen om te controleren of alle gevraagde
gegevens wel degelijk in het gegeven datamodel aanwezig waren. Meestal was een scherm een
lijst of detail weergave van een bepaalde database tabel. Op die manier kon ik gemakkelijk velden
toevoegen op deze locaties in het datamodel. Meestal ging het hier dan over boolean veldjes die
“vergeten” waren in het datamodel. Dit gebeurde volgens het principe van ER waarbij ik me de
vraag stelde of een bepaald veld een relatie had met de tabel (entity). Bijvoorbeeld “een
medewerker heeft een username”.
Op sommige plaatsen heb ik ook een tussentabel toegevoegd. Dit gebeurde op plaatsen waar er
een veel op veel relatie beschreven stond. In de praktijk moet men ook steeds een tussentabel
voorzien in de effectieve databank op veel op veel locaties. Op die plaatsen bleek bij de analyse
van de schermen dat er soms ook nog extra informatie nodig was en dat die in deze
tussentabellen het beste thuis hoorde.
Voorbeelden van extra tussentabellen zijn de tabellen competf_fbeschrijving waar een status aan
toegevoegd werd en de tabel opleiding_competentie waar geen extra informatie nodig was. In
sommige tabellen was er nood aan een extra boolean veldje om waarden van checkboxen in op te
slaan.
Bij het toevoegen van extra functionaliteiten heb ik ook een aantal aanpassingen in het datamodel
moeten doen. Een voorbeeld was de mogelijkheid voor het verzenden van een herinnering voor
deadlines van acties via mail. Hiervoor moest ik beschikken over een e-mailadres in de tabel
medewerker en een boolean veldje in de tabel actie om aan te geven of een herinnering al dan
niet al verzonden werd.
Een overzicht van het uiteindelijke datamodel met de types van de velden vind je hierna in het
schema van het datamodel.
Eindwerk Bram Gadeyne
2007-2008
24
4.1.1 Data-analyse / Datamodel
Eindwerk Bram Gadeyne
2007-2008
25
4.1.2 Objectgeoriënteerd model
Van alle tabellen weergegeven in het datamodel werd een overeenkomstige entity klasse
opgesteld. Een entity klasse is een object georiënteerde weergave van een tabel die als object 1 rij
uit de overeenkomstige tabel zal voorstellen. Het bestaat meestal uit een gewone klasse die alle
velden met een overeenkomstige waarde voorziet van getters en setters. Meer informatie over
entitys is terug te vinden bij het hoofdstuk over persistence.
Voor elk van deze entity klassen werd dan een actie, service en DAO object opgesteld zoals dit
beschreven staat in de architectuur die ik gebruikte. Meer informatie over deze opstelling en wat
de functie is van deze klassen kun je terugvinden bij het hoofdstuk over de architectuur van de
applicatie.
Over de DAO’s waarover hier sprake is kunnen we toch al het één en ander verduidelijken. Ze zijn
opgebouwd in een specifieke hiërarchie die niet echt technologie onafhankelijk is. De code
voorbeelden zijn wel in Java uitgeschreven.
4.1.2.1 Generic DAO’s
Elke entity klasse beschikt over een overeenkomstige DAO (data access object). Elke DAO weet
perfect hoe hij voor zijn eigen entity type een aantal acties kan uitvoeren. Deze acties hebben
allemaal betrekking op een datasource zoals bijvoorbeeld een database. De DAO weet hoe hij deze
datasource kan raadplegen.
Sommige acties waarin een DAO voorziet zijn voor alle DAO’s gelijk. Andere acties zijn dan weer
specifiek voor een bepaalde entity.
Dankzij het gebruik van generics kunnen we een basis DAO maken die alle basisfunctionaliteiten
abstract beschrijft. Een generic maakt het mogelijk om af te dwingen dat een object van een
bepaald (abstract) type is. In ons geval gebruiken we de abstracte generic waarde T en de
abstracte generic waarde ID. T dwingt daarbij af dat een bepaald object een entity klasse is. ID
vraagt in welk objecttype de ID van deze entity klasse opgeslagen is.
Een overzicht van de basis functionaliteiten van een DAO zijn terug te vinden in de onderstaande
interface. Zoals je kan zien worden de generics meegegeven aan de klasse en kunnen die dan
abstract gebruikt worden in de beschrijving van de methoden. Alle entitys zijn immers van het
type T en alle id objecten zijn van het type ID.
Eindwerk Bram Gadeyne
2007-2008
26
public interface IDAO<T, ID extends Serializable> {
T findById(ID id, boolean lock);
List<T> findAll();
List<T> findByExample(T exampleInstance, String... excludeProperty);
T makePersistent(T entity);
T insert(T entity);
void makeTransient(T entity);
@PersistenceContext(unitName = "ProjectCommasPU")
public void setEntityManager(EntityManager em);
public EntityManager getEntityManager();
}
Van deze interface maakte ik dan een abstracte klasse baseDAO. Deze abstracte klasse
implementeert alle methoden die beschreven zijn in de IDAO interface. Het voorziet ook in een
connectie tot een bepaalde datasource. Op die manier zullen alle afgeleide DAO’s gebruik maken
van dezelfde datasource. Hier wordt gebruik gemaakt van een EntityManager als datasource maar
andere datasources kunnen evengoed gebruikt worden. Meer uitleg over de EntityManager en de
Persistence Context kun je terugvinden in het hoofdstuk over Persistence.
Nu werd voor elk entitytype ook weer een interface beschreven van een DAO die afgeleid is van de
IDAO interface. In deze interface werden dan methoden beschreven die specifiek voor deze DAO
van belang zijn.
Een voorbeeld van een interface van een generic DAO voor het entity object Action:
public interface IActieDAO<T, ID extends Serializable> extends IDAO<T, ID> {
List<T> getByMedewerker(Medewerker medewerker);
List<T> getAllNotMailed();
}
Van deze interface werd dan ook weer een nieuwe klasse afgeleid. Ditmaal echter geen abstracte
maar een echte klasse. Deze klasse kan gebruik maken van de functionaliteiten in de baseDAO en
heeft dan ook toegang tot de datasource.
Een voorbeeld van een generic DAO voor het entity object Action. De uitwerking hiervan is
opgemaakt in Java code en maakt gebruik van een entityManager en HQL (een SQL soortgelijke
taal om te gebruiken met Hibernate) Meer informatie over de EntityManager en Hibernate zijn te
vinden bij het hoofdstuk over Persistence en Hibernate.
Eindwerk Bram Gadeyne
2007-2008
27
public class ActieDAO extends BaseDAO<Actie, Long> implements
IActieDAO<Actie, Long> {
@SuppressWarnings("unchecked")
public List<Actie> getByMedewerker(Medewerker medewerker) {
List<Actie> lijst;
try {
lijst = getEntityManager()
.createQuery(
"from Actie as a where a.medewerkerid=?1 order by a.status, a.deadline")
.setParameter(1, medewerker).getResultList();
} catch (RuntimeException e) {
lijst = new ArrayList<Actie>();
}
return lijst;
}
@SuppressWarnings("unchecked")
public List<Actie> getAllNotMailed() {
List<Actie> lijst;
try {
lijst = getEntityManager()
.createQuery(
"from Actie as a where a.mailed = 'N'").getResultList();
} catch (RuntimeException e) {
lijst = new ArrayList<Actie>();
}
return lijst;
}
}
4.1.2.2 Klassen Hiërarchie
Het schema van de Generic DAO’s kan hieronder teruggevonden worden. Bovenaan vinden we de
IDAO terug en de abstracte BaseDAO waarvan respectievelijk de Interfaces en de uiteindelijke
DAO’s zijn afgeleid. Meer informatie over Generic DAO’s kun je in het hoodstukje over Generic
DAO’s terugvinden.
Naast de Generic DAO’s zijn ook de acties op een soortgelijke manier opgebouwd via een IAction
interface die alle basis acties van een Actie beschrijft en een abstracte klasse ListAction die de
basisfunctionaliteit voor lijsten voorziet.
Eindwerk Bram Gadeyne
2007-2008
28
Eindwerk Bram Gadeyne
2007-2008
29
4.2
Architectuur
Voor de uitwerking van mijn stageopdracht raadde men me aan om gebruik te maken van een
gelaagd model. Een gelaagd model heeft als voordelen dat elke laag precies weet wat het moet
doen en dat objecten uit verschillende lagen loosely coupled van elkaar gebruik kunnen maken.
Meer uitleg over de gebruikte architectuur kun je hieronder terugvinden.
4.2.1 Application Architecture
Deze Architectuur bestaat uit 5 lagen die telkens samen kunnen werken met de laag boven of
onder hen. Tussen alle lagen door kunnen Entity objecten gebruikt worden om gegevens door te
geven. Meer uitleg over de verschillende lagen en hun functies zijn terug te vinden in
onderstaande tabel.
Laag
Presentation Layer
Uitleg
Deze bevat alle webpagina’s. In het geval van mijn Seam project zijn dit JSF
en Richfaces pagina’s. Ook pagina’s voor mail rendering, statische html
pagina’s, JSP pagina’s, enz. worden hier gelokaliseerd. De Presentation
layer op zich heeft enkel de functie iets weer te geven. Het afhandelen van
acties of bewerkingen worden dan door de onderliggende lagen
opgeroepen of uitgevoerd.
Application Layer
De presentation layer wordt gebonden (binding) aan bepaalde acties.
Meestal gaat het hier om een druk op de knop die een bepaalde actie
uitvoert of een listener die aan een bepaalde control is gebonden. Acties
worden meestal doorgegeven aan de service laag. In deze laag houdt men
ook objecten bij die een bepaalde status kunnen onthouden. Op die
manier kunnen we de view opnieuw opbouwen aan de hand van de vorige
status. Lijsten kunnen worden omgezet naar lijsten die begrijpbaar zijn
door de presentation layer.
Service Layer
De business logica zoals berekeningen worden hier afgehandeld. Als een
service gegevens moet wegschrijven in een database of gegevens nodig
heeft dan zal hij die opdracht doorgeven aan een DAO. Eigenlijk gaat het
hier dus vooral om logica die moet worden uitgevoerd en waarbij geen
afhankelijkheid bestaat van de view die wordt gebruikt. Op die manier kan
aan elke applicatie een andere view methode worden gekoppeld zoals
Swing voor een desktopapplicatie en JSF voor een webapplicatie.
Data Access Layer In deze layer bevinden zich DAO’s. Deze hebben alle kennis in verband met
(DAO’s)
een bepaalde tabel uit de database en weten hoe ze bepaalde handelingen
op de database via een JPA(in mijn project Hibernate) kunnen uitvoeren.
DAO’s worden meestal opgebouwd via Generics omdat de
basisfunctionaliteit bij elke DAO dezelfde blijft. Alleen kunnen extra
methoden voor sommigen DAO’s gewenst zijn.
Eindwerk Bram Gadeyne
2007-2008
30
Model
Tussen alle lagen door worden objecten doorgegeven. Meestal gaat het
hier over entities of collecties van entities. Deze zijn dan ook beschikbaar
in alle lagen. Het is echter enkel de DAO laag die de entities ook effectief
kan ophalen of wegschrijven naar een databank.
Dankzij deze architectuur kan men in theorie heel gemakkelijk een andere database aan een
bepaalde applicatie koppelen of een andere presentatie techniek zoals swing ipv web gebruiken.
Elke laag is loosely coupled wat wil zeggen dat ze zich eigenlijk niet moeten bezighouden met hoe
de laag boven of onder zich werkt. Wel moeten ze weten hoe ze kunnen communiceren met
andere lagen.
Ook onderhoud van de applicatie kan gemakkelijk gebeuren. Er kan gedelegeerd worden wie
wijzigingen moet aanbrengen in welke laag zonder dat die wijzigingen gevolgen hebben in de rest
van de applicatie. Testen kunnen dan ook gemakkelijk worden geschreven per laag om te
waarborgen dat een laag nooit een andere laag zal beïnvloeden.
4.2.2 Platformonafhankelijkheid
Voor de ondersteuning van platformonafhankelijkheid heb ik gebruik gemaakt van een propertie
file. Hierin heb ik alle verwijzingen naar paden en enkele andere eigenschappen opgeslagen
Eindwerk Bram Gadeyne
2007-2008
31
waardoor deze kunnen worden aangepast buiten de applicatie. Java op zich is
platformonafhankelijk want elke Java file kan worden begrepen door de JVM die per platform
installeerbaar of compileerbaar is. De verwijzingen naar paden op een bepaald bestandssysteem
kunnen ervoor zorgen dat code van de applicatie niet platformonafhankelijk werkt.
Een TimerTask zorgt ervoor dat opties kunnen worden aangepast terwijl de server in werking is en
zonder dat deze moet worden herstart om de wijzigingen van kracht te laten worden. Een
TimerTask start een Thread die volgens een bepaalde frequentie een bepaalde methode zal
uitvoeren.
/**
* Een Timertask die het options.properties bestand inleest volgens het interval
* zoals aangegeven in de options.properties file.
*
*/
private class TimerTaskImpl extends TimerTask {
@Override
public void run() {
InputStream stream = loader
.getResourceAsStream("options.properties");
try {
synchronized (properties) {
properties.load(stream);
}
System.out.print("timertask uitgevoerd.");
} catch (IOException e) {
System.out.print("kon properties niet lezen." + e.getMessage());
} catch (RuntimeException e) {
System.out.print("kon properties niet lezen." + e.getMessage());
}
}
}
4.3
Technisch
De technische analyse nam de grootste tijd van mijn stage in beslag. De doelstelling was om
uiteindelijk het Seam framework te leren gebruiken en er de toepasbaarheid van uit te testen. Om
Seam echter te begrijpen moest ik eerst een kijkje nemen naar enkele andere frameworks waarop
Seam gebaseerd is. JSF en EJB 3.0, die verder nog worden uitgelegd, zijn hiervoor de belangrijkste.
Ook maakt Seam gebruik van Java 5 wat een aantal voordelen met zich meebrengt.
Naast deze frameworks waren er ook nog andere frameworks die extra functionaliteiten voorzien.
Deze worden door Seam ook geïntegreerd in de vorm van componenten.
Deze onderstaande figuur kan u een idee geven over het doel van de verschillende frameworks in
het geheel. Seam zorgt voor een goede integratie tussen JSF en EJB 3.0. Seam voorziet dankzij EJB
3.0 in allerlei componenten die een bepaalde functionaliteit aanbieden. Deze componenten zijn
gebaseerd op frameworks die hun kunnen al meerdere malen bewezen hebben.
In de volgende hoofdstukken geef ik meer uitleg over de verschillende frameworks.
Eindwerk Bram Gadeyne
2007-2008
32
4.3.1 Java 5
Hoewel de nieuwste versie van Java versie 6 is maakt Seam gebruik van Java 5. Dit brengt een
aantal belangrijke nieuwigheden met zich mee, waaronder annotaties en generics die het leven
van de programmeur heel wat aangenamer maakt.
4.3.1.1 Annotaties
Annotaties kennen veel voor- en tegenstanders. Configuratie gebeurt door velen in XML
bestanden. Die zijn gemakkelijk toegankelijk en ze zijn gegroepeerd in een aantal bestanden op
een vaste locatie. Het probleem met deze XML configuratie is dat men soms het gevoel heeft dat
men programmeert in XML en niet langer in Java. Hiervoor heeft Java 5 de nieuwe mogelijkheid
genaamd annotaties geïntroduceerd. Annotaties brengen configuratie die vroeger in XML
bestanden stonden terug naar de code.
Naast configuratie bieden annotaties ook nog de mogelijkheid om in geannoteerde objecten een
bepaald object te injecteren. Annotaties worden at runtime geïnterpreteerd waardoor sommige
servers soms anders reageren op bepaalde annotaties dan andere.
Annotaties zijn gemakkelijk te herkennen in de code omdat ze altijd met het @ symbool beginnen.
4.3.1.2 Generics
Generics is ook één van de nieuwigheden die men in Java 5 heeft geïntroduceerd. Ze maken het
mogelijk om op bepaalde plaatsen af te dwingen dat de te gebruiken objecten van een bepaald
(abstract) type zijn.
Bij het hoofdstuk over Generic DAO’s vind je een voorbeeld terug over de abstracte generics
notatie T en ID.
Generics zijn gemakkelijk te herkennen omdat ze altijd tussen “<” en “>” symbolen staan.
Eindwerk Bram Gadeyne
2007-2008
33
Een voorbeeld met een generic List:
List<Actie> actieLijst=new ArrayList<Actie();
actieLijst kan opgevuld worden met een lijst. In deze lijst mogen echter alleen objecten zitten van
het supertype Actie.
4.3.2 EJB 3.0
De Enterprise JavaBeans-specificatie is één van de Java-APIs in de J2EE-standaard. EJB's zijn
bedoeld om in een meerlagenmodel de zogenaamde businesslogica van een applicatie te
bevatten. In mijn applicatie rijken ze over de Application, Service en Data Access Layer. Deze lagen
bevatten immers de business logica van de applicatie.
Een Enterprise Java Bean bestaat uit een klasse waarvan objecten worden beheerd door een
zogenaamde EJB container. Deze container zal instanties van de objecten aanmaken, bewaren en
vernietigen wanneer dit nodig is. Objecten kunnen dan aan deze EJB container worden
opgevraagd om er bepaalde bewerkingen mee uit te werken.
EJB’s worden tijdelijk opgeslagen in de session scope. Een scope laat toe om Beans, objecten of
variabelen op te slaan gedurende een bepaalde tijd die de scope omvat. De session als voorbeeld
van een scope beschrijft dan meestal de periode tussen het aan en afmelden van een bepaalde
gebruiker.
We onderscheiden 2 soorten Session EJB’s. De Stateless Beans en de Stateful Beans.
4.3.2.1 Stateless
Bij Stateless Session Beans wordt een instantie van de Bean aangemaakt wanneer deze wordt
opgevraagd. Bij het aanmaken hiervan worden de dependencys geïnjecteerd en worden eventueel
methoden uigevoerd die met de annotatie @PostConstruct gedefinieerd zijn. Dependencys zijn
andere EJB’s die aan de te initialiseren EJB moeten worden gekoppeld en waarvan deze EJB
afhankelijk is. Dit gebeurt aan de hand van een techniek die Injection wordt genoemd.
Wanneer een Stateless Session Bean door de garbage collector verwijderd wordt, dan wordt bij
het opnieuw opvragen van deze Session Bean gewoon een nieuwe instantie teruggegeven. In een
Stateless Session Bean kun je dus in principe geen status opslaan over een lange periode omdat je
nooit weet of een Bean dezelfde is als de vorige.
Eindwerk Bram Gadeyne
2007-2008
34
4.3.2.2 Stateful
Bij de Stateful Session Bean kun je in tegenstelling tot de Stateless wel een status opslaan.
Een Bean die een eindje niet gebruikt wordt, wordt dan passief gemaakt. Via de 2 methoden die
met de 2 annotaties @Remove en @Predestroy geannoteerd zijn kun je nog enkele zaken laten
uitvoeren alvorens deze Bean passief wordt gemaakt. Als men deze Bean opnieuw opvraagt dan
wordt de Bean opnieuw actief gemaakt en kun je dus verder werken met dezelfde Bean. Stateful
Session Beans belasten hierdoor het systeem wel meer dan Stateless Session Beans.
4.3.2.3 Gebruik
Een EJB bestaat steeds uit minimum 2 klassen. Een interface die de @Local annotatie gebruikt en
een daarvan afgeleide klasse die dan de invulling van de EJB bevat. Dit is eigenlijk omdat EJB werkt
volgens het systeem van RMI. Een EJB wordt opgezocht via zijn JNDI naam (Java Naming and
Directory Interface). JNDI geeft je dan een Proxy (stub) terug die de interface van de EJB
implementeert en die met de effectieve (lokale) EJB kan praten.
JNDI maakt het mogelijk om objecten via hun opgegeven naam op te zoeken in een bepaald
register.
Onderstaand voorbeeld toont hoe de werking van RMI in elkaar zit. Er wordt van een bepaalde
klasse een implementatie gemaakt en een interface. Van deze implementatie zal dan een Stub
object worden gegenereerd. Dit stub object wordt in een register geplaatst die via JNDI
geraadpleegd kan worden. De client kent de interface van het object die hij op de server zou
willen raadplegen. Hij vraagt de Stub, die dezelfde interface geïmplementeerd heeft, op aan het
register via de JNDI-naam van dit object. Nu kan de client door zijn interface via de stub
communiceren met de stub aan de server kant die op zijn beurt dan communiceren met het
effectieve object op de server. Voor de client lijkt het alsof het object op de client zelf zou
Eindwerk Bram Gadeyne
2007-2008
35
aanwezig zijn. Natuurlijk hoeft de client hier niet een effectieve andere computer te zijn maar kan
dit ook binnen dezelfde computer gebruikt worden.
In een standaard Java applicatie wordt er gebruik gemaakt van RMI om een EJB via zijn Proxy op te
halen uit een EJB Container. Dit lijkt misschien omslachtig maar dit blijkt nodig te zijn als we met
injecties willen werken.
Dankzij injecties kunnen we vanuit de ene EJB A een andere EJB B raadplegen zonder dat de A
precies weet met welke B hij communiceert. Zo moet A ook niet weten of B een statefull of
stateless bean is. Wel moet B zeker dezelfde interface gebruiken als die van zijn Proxy. Een injectie
hierbij is het opzoeken van een bepaalde stub in het JNDI register en deze koppelen aan een
interface die men wil gebruiken in een de EJB.
Natuurlijk kunnen we dan ook EJB Containers gaan raadplegen vanuit verschillende servers. Op die
manier kunnen we dan weer functionaliteit, verantwoordelijkheden en processing time
Eindwerk Bram Gadeyne
2007-2008
36
balanceren over verschillende servers. Dit systeem heb ik natuurlijk niet toegepast op mijn stage
maar kan eventueel bij hele grote en zware applicaties worden gebruikt.
4.3.3 JSF
Java Server Faces is een onderdeel van Java EE (Enterprise Edition) en voorziet in een makkelijke
conversatie tussen de view (JSP) en de business laag (bijvoorbeeld java beans of EJB’s). Via een
speciale EL (Expression Language) kunnen bepaalde actions (methoden) gemakkelijk gebonden
(binding) worden aan business acties en kunnen values gebonden worden aan object values. JSF
voorziet ook in een State Saving mechanisme waardoor de status van pagina’s wordt onthouden
door de server. Dit is handig als je moet terugkeren naar een eerdere pagina.
JSF voorziet in een aantal componenten zoals inputTextBoxen, booleanSelectBoxen,
outputTextBoxen, … Al deze componenten moeten tussen de <h:form></h:form> tags staan. Ze
zijn te herkennen aan de tags die steeds beginnen met “h:” of “f:”
4.3.3.1 Expression Language (EL)
Als we willen programmeren in JSF dan is kennis over de EL wel handig. Dankzij EL kunnen we in
de JSF pagina’s bepaalde attributen opvullen met values. Values staan steeds tussen #{} tags. In EL
kunnen we ook wiskundige berekeningen uitvoeren of boolean statements maken. De vertaling
tussen de Java operators en de EL operators vind je in onderstaande tabel.
Java
+
/
%
*
&&
||
!
Eindwerk Bram Gadeyne
EL
+
div
mod
*
and
|| of or
not
2007-2008
37
<
<=
>
>=
==
!=
lt
le
gt
ge
eq
ne
4.3.3.2 Bindings
Bindings in JSF zijn dankzij het gebruik van EL heel gemakkelijk begrijpbaar en gebruikbaar. In JSF
gebeurt de configuratie altijd in een faces-config.xml file. Hieronder zie je een sterk gereduceerd
voorbeeld. Als we vroeger objecten wilden “bekend” maken voor JSF dan moesten we die een
“managed-bean-name” geven. Met die beanname kon de bean dan worden aangesproken. Dit
kunnen we doen voor gewone instanties van POJO’s maar ook voor instanties van EJB’s zoals
Entity klassen.
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<managed-bean>
<managed-bean-name>managedBean</managed-bean-name>
<managed-bean-class>Bean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
Een voorbeeld van onze Bean.class is dan
public class Bean {
public Bean() {
}
String tekst;
public String getTekst() {
return tekst;
}
public void setTekst(String tekst) {
this.tekst = tekst;
}
}
We zien dat in Bean.class een value gedefinieerd is. Dit zou bijvoorbeeld een Entity kolomwaarde
kunnen zijn die we later willen versturen naar de database. We kunnen nu deze waarde koppelen
via binding aan bijvoorbeeld een h:inputText.
<h:inputText value="#{managedBean.tekst}">
Eindwerk Bram Gadeyne
2007-2008
38
Zoals u kunt zien gebruiken we de managedBeanName om de bean op te roepen. Als value
gebruiken we niet een getter of setter maar de overeenkomstige value naam zoals hier tekst. Dit is
mogelijk dankzij de Java conventies voor getters en setters.
Bij het laden van de pagina zal de getter van de value worden opgeroepen. Wanneer men dan een
submit doet van het form waarin de inputText zich bevindt dan zal respectievelijk de setter van die
value worden opgeroepen. Op die manier kunnen we dan in de back-end van ons programma
verder werken met deze value zonder dat we ons zorgen hoeven te maken over het transport van
die value tussen de client en de server via bijvoorbeeld een POST parameter of iets dergelijks.
4.3.3.3 Navigatie
Navigatie tussen pagina’s is natuurlijk noodzakelijk in webapplicaties. In JSF gebeurt het surfen
niet door het aanroepen van URL’s. De locatie van een webpagina kan op die manier veranderen
en men kan nog acties laten uitvoeren alvorens effectief te navigeren naar een andere pagina.
De configuratie kunnen we instellen nadat een bepaald woord “outcome” werd opgeroepen op
een bepaalde pagina of nadat een bepaalde method werd uitgevoerd.
Een voor beeld:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<navigation-rule>
<navigation-case>
<from-outcome>home</from-outcome>
<to-view-id>/home.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
Wanneer JSF nu ergens de outcome “home” opvangt zal hij navigeren naar de view-id (pagina)
home.xhtml. Op zich zal hij niet forwarden naar de effectieve pagina maar zal de pagina door JSF
worden gerenderd en geladen. Renderen van een pagina houdt in dat de pagina door de JSF
servlet wordt gelezen en dat de tags van deze pagina zullen worden omgezet naar HTML tags. Een
JSF pagina moet dus altijd gerenderd worden om omgezet te worden naar HTML. Na het renderen
van de JSF pagina zal deze verzonden worden onder de vorm van HTML. We kunnen dan zien wat
onze url geworden is http://.../../home.seam.
Via een Button kunnen we een navigatie afdwingen.
<h:commandButton value="Home"
action="#{navigator.goHome()}" />
We zien hier dat de button een waarde “Home” zal krijgen. Bij de action voeren we hier een
method goHome() uit. Deze method kan een void method zijn waardoor we na het uitvoeren
ervan op dezelfde pagina zullen blijven. Als de method een String terugkeert wordt naar de
Eindwerk Bram Gadeyne
2007-2008
39
overeenkomstige view-ID gesurft. Als we een lege String teruggeven dan zal ook opnieuw de
huidige pagina geladen worden.
We kunnen eveneens in het action gedeelte de gewenste String definiëren als het oproepen van
een method niet nodig is.
@Name("navigator")
public class Navigator
{
public String goHome()
{
//doe iets
return "home";
}
}
4.3.3.4 Lijsten
In JSF kunnen we niet alleen gewone waarden doorgeven aan de JSF pagina. We kunnen ook
collections doorgeven. Op die collections zit geen controle op het type object dat zich in de
collection bevindt. We kunnen wel in de back-end via generics ervoor zorgen dat we enkel
objecten van een bepaald type in de collection willen.
<h:dataTable value='#{bean.collection}' var='item'>
<h:column>
<f:facet name="header">
<h:outputText value="Naam"/>
</f:facet>
<h:outputText value="#{item.naam}"/>
</h:column>
</h:dataTable>
Deze dataTable is een tabel met slechts 1 kolom ter illustratie. We krijgen ergens een collection
met de naam Collection binnen. Elk item uit de collection stel ik voor door de naam “item” zoals
aangegeven bij het attribuut var. Als we nu zeker weten dat item een value bevat “naam” dan
kunnen we die weergeven met bijvoorbeeld een outputText. De werking is ook weer dezelfde
waarbij we niet de getter of setter naam gebruiken maar de effectieve naam van de value.
We zien nog dat er een f:facet gedefinieerd is. Dit is telkens de waarde die we bovenaan in de
kolom header zullen zien verschijnen. In ons geval gebruiken we hier een outputText met als value
“Naam”.
4.3.3.5 Templating in JSF
Na het genereren van een Seam project viel het me op dat hiervoor een soort templating werd
voorzien waardoor andere pagina’s eigenlijk in een template worden geopend.
De definitie van het template zelf ziet er uit als een gewone html pagina. In de body van de html
pagina vinden we echter de volgende codes terug.
Het eerste voegt een menu toe en vult een parameter in die door dit menu kan worden
opgehaald.
Eindwerk Bram Gadeyne
2007-2008
40
<h:form>
<ui:include src="menu.xhtml">
<ui:param name="projectName" value="ComMaS"/>
</ui:include>
</h:form>
Het tweede definieert waar een bepaalde “ui” code met als naam body uit de oproepende pagina
zal worden toegevoegd.
<div class="body">
<ui:insert name="body"/>
</div>
In een oproepende pagina vinden we dan de volgende tag rond de uiteindelijke inhoud terug.
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
template="/layout/template.xhtml">
<ui:define name="body">
<h:form>
<!--enige vorm van jsf-inhoud -->
</h:form>
</ui:define>
</ui:composition>
Bemerk dat als attribuut van de ui:composition het veld template wordt meegegeven. Deze
verwijst dan naar de locatie van waar de template zich bevindt. Het ui:define blok heeft als naam
“body” zodat het op de juiste plaats kan worden ingevoegd in de template.
4.3.4 Seam
De rode draad doorheen mijn stage was niet zozeer het
analyseren maar het ontwikkelen met de nieuwe Java
technologie Seam waar ondertussen de nieuwe standaard
webbeans op gebaseerd is.
Seam is een open - source project van “JBoss , a devision of Red
Had”.
Het is niet een framework die volledig nieuwe zaken wil
ontwikkelen. De doestelling van de Seam programmeurs is om
bestaande “Proven Technology” (technologie die zijn kunnen al vaak heeft bewezen) te gebruiken
en te vergemakkelijken in een nieuw framework. Zo neemt het bijvoorbeeld de moeilijke weg
doorheen configuratie van verschillende frameworks in XML weg en vervangt deze door het
Eindwerk Bram Gadeyne
2007-2008
41
gebruik van annotaties. Seam voorziet ook in een aantal tools die veel gebruikte
standaardcomponenten kunnen vervangen. Zo denk ik maar aan het authenticatiesysteem waarin
Seam voorziet.
De 2 belangrijkste frameworks waarop het Seam framework is
gebaseerd zijn JSF en EJB 3.0. Seam wenst gebruik te maken van
de standaarden en gebruikt daarom deze 2 frameworks voor
respectievelijk de presentation en de business layer van een
applicatie. Meer uitleg over EJB 3.0 en JSF zijn terug te vinden in
de vorige hoofdstukken.
Daarnaast wordt ook gebruik gemaakt van logging frameworks en Persistence met Hibernate die
later in dit verslag nog verder zullen worden uitgelegd.
Voor de uitwerking van de extra functionaliteiten voorziet Seam in objecten die gemakkelijk via
injections (zoals bij EJB) kunnen worden gekoppeld. Op die manier kun je Seam objecten
raadplegen via een Proxy en zal het uiteindelijke component de gevraagde functionaliteit
uitvoeren. De configuratie van al deze componenten heeft Seam gecentraliseerd in de kleine XML
file components.xml. Maar over al deze zaken vind je verder in dit stageverslag nog veel
informatie.
4.3.4.1 Starten van een nieuw project
Seam voorziet in een tool met de naam “seam-gen”. Het maakt een volledig nieuw project met
eventueel zelfs al pagina’s waarmee je acties over de verschillende databanktabellen kan
uitvoeren.
Door het installeren van de JBoss Tools in de Eclipse IDE kun je gemakkelijk zo’n nieuw project
laten genereren.
4.3.4.2 EJB 3.0 in Seam
4.3.4.2.1 Injecties
De JNDI naam van een EJB werd vroeger in een ejb-config.xml bestand beschreven. Op die manier
kon men dan injecties uitvoeren van beans in andere beans.
Seam houdt niet zo van configuratie bestanden. Om de JNDI naam te specificeren in Seam moet je
gebruik maken van de @Name(“JNDINaam”) annotatie.
Om dan de bean te kunnen injecteren in een andere maken we gebruik van de @In annotatie. De
@In annotatie voorziet in een parameter create die een boolean waarde true of false kan krijgen.
Als deze op true staat dan wil dit zeggen dat er mogelijks van die bepaalde te injecteren Bean nog
geen instantie bestaat. Als dit zo is dan zal door de create=true optie de Container een nieuwe
instantie van de EJB creëren.
Soms willen we echter een aangepaste bean terugplaatsen op een bepaalde scope. Dit kunnen we
ook gemakkelijk doen door de @Out annotatie te definiëren bij een bepaalde variabele.
Een voorbeeld:
Eindwerk Bram Gadeyne
2007-2008
42
@Stateless
@Name(“beanOne”)
public class BeanOne implements IBeanOne
{
//deze method moet ook beschreven staan in de interface IBeanOne om ze toegankelijk te
//maken in de geïnjecteerde Bean.
public void doIets()
{
//voert iets uit
}
//enkele datamembers en methoden
}
@Stateless
@Name(“beanTwo”)
public class BeanTwo implements IBeanTwo
{
@In(create=true)
IBeanOne beanOne;
public void doeIetsAnders()
{
beanOne.doIets();
}
//enkele methoden en datamembers.
}
Zoals we kunnen zien moeten we steeds de Interface gebruiken van de bean die we willen
raadplegen omdat we via RMI een proxy (stub) krijgen met een referentie naar de bean en niet de
implementatie van de bean zelf. De proxy implementeert wel dezelfde interface als de bean.
4.3.4.2.1.1 Contexts
Een ander voordeel aan Seam is dat je POJO’s (Plain Ordinary Java Objects) of EJB’s kunt
annoteren met de @Scope annotatie. We kunnen dan kiezen om ons object in 1 van de 7 contexts
van Seam op te slaan. Seam zal steeds alle contexts overlopen om een proxy voor een JNDI naam
te vinden. Hij zal daarbij beginnen bij de context die de kleinste levensduur heeft. We kunnen bij
het opzoeken van een bean via injectie echter ook opgeven in welke context Seam zal moeten
zoeken.
•
•
Stateless context
o Deze context heeft niet echt een functie. We kunnen echter elk object in deze
context stoppen als we ze op een stateless manier willen behandelen.
Session context
o De Sessie context wordt vaak gebruikt bij webapplicaties. Het is eigenlijk een plaats
waarin je objecten kunt bewaren die doorheen de gehele duur van een sessie
beschikbaar zijn. Meestal is dit dan vanaf het moment dat een gebruiker zich
aanmeldt totdat deze zich terug afmeldt.
Eindwerk Bram Gadeyne
2007-2008
43
•
•
•
•
•
Application context
o In deze context kunnen objecten worden geplaatst die niet zullen verschillen tussen
de verschillende gebruikers en dus gedurende de hele levensduur van de applicatie
zullen bestaan. Als je hier een Statefull EJB in plaatst, werkt de application context
eigenlijk ook als een singleton. DAO’s zijn bijvoorbeeld objecten die voor iedereen
hetzelfde zullen zijn. De meeste componenten die voorzien zijn door Seam zijn ook
in de application context opgeslagen.
Event context
o Deze is de kleinste context van allemaal. In deze context worden objecten geplaatst
die slechts beschikbaar moeten zijn tussen het moment van een submit op een
form tot dat het antwoord wordt gestuurd.
Page context
o Hierin kunnen objecten worden bewaard voor de lengte van een page request.
Zolang een pagina dezelfde blijft zal bij een refresh informatie bijvoorbeeld niet
opnieuw moeten worden opgehaald uit de databank. Het is een manier om
misbruik van de sessie te voorkomen. Het is een manier om professioneler te
werken zonder request scope zodat niet bij elke refresh de databank opnieuw moet
worden geraadpleegd.
Conversation context
o Deze context is ontworpen om het probleem met sessies over verschillende
tabbladen in een browservenster op te lossen. Het is zo dat wanneer we een nieuw
tabblad in een nieuwe browser openen we nog steeds in dezelfde sessie zitten. De
conversation context maakt dan een soort virtuele sessies die met elkaar kunnen
communiceren. Hierdoor zal de applicatie perfect over tabbladen kunnen werken
en zal het lijken alsof we een nieuwe sessie hebben gestart.
Business Process context
o Deze context is ontworpen om business processen in te laten werken. Deze
processen kunnen heel lang duren en worden soms automatisch opgestart.
4.3.4.3 Bingings in Seam
In Seam houdt men niet van dergelijke configuratie. De manier van oproepen en het schrijven van
de bean blijft dezelfde. Maar de volledige configuratie in de faces-config.xml file valt weg. Het
configureren van de beanName gebeurt dan met de Seam annotatie @Name(“value”). Een
aangepast voorbeeldje voor onze Bean.class
import org.jboss.seam.annotations.Name;
Eindwerk Bram Gadeyne
2007-2008
44
@Name("managedBean")
public class Bean {
public Bean() {
}
String tekst;
public String getTekst() {
return tekst;
}
public void setTekst(String tekst) {
this.tekst = tekst;
}
}
Het oproepen in de JSF pagina blijft dan als volgt:
<h:inputText value="#{managedBean.tekst}">
4.3.5 Rich Web Applications (Web 2.0)
Om tegemoet te komen aan het idee van Web 2.0 voorziet Seam standaard in een implementatie
van Richfaces. Richfaces is een library die p JSF is gebaseerd en componenten voorziet die goed
samenwerken met AJAX.
Web 2.0 is een begrip die binnen de webwereld de laatste tijd veel gebruikt wordt. Helaas bestaat
er geen echte definitie van Web 2.0 omdat Web 1.0 nooit is beschreven en omdat Web 2.0 een
toekomstvisie is zoals men graag de websites naar een nieuw niveau zou willen laten zien
evolueren. Dankzij frameworks als Richfaces die gebruik maken van Ajax om hun componenten af
te beelden en laten samenwerken, krijg je al een mooi voorbeeld van hoe Web 2.0 eruit zou
kunnen gaan zien.
4.3.5.1 Richfaces
Natuurlijk is JSF een basistaal en standaard waarop vele andere frameworks of componenten
gebaseerd zijn. Ze maken natuurlijk allemaal wel gebruik van JSF. JSF op zich bevat wel enkele
dynamische componenten waarmee je bijvoorbeeld lijsten, knoppen, linkbuttons, labels,
tekstboxen, chekboxen, … kunt maken. De layout van al deze zaken is dan de standaard layout
omdat de HTML die gegenereerd wordt de gewone HTML tags bevat.
Frameworks zoals Richfaces voorzien in mogelijkheden om aan templating te doen. Ze voorzien
dan een aantal css bestanden waarmee je via drag en drop al een hele mooie webpagina verkrijgt
die meestal in alle webbrowsers mooi worden afgebeeld.
Daarnaast bieden frameworks zoals Richfaces tegenwoordig ook ondersteuning voor AJAX. Dankzij
Ajax kunnen we eigenlijk applicaties ontwikkelen die er ongeveer uit gaan zien als een lokale niet
webapplicatie, omdat het effect van de steeds ladende pagina’s wegblijft.
Eindwerk Bram Gadeyne
2007-2008
45
4.3.5.1.1 Componenten
Richfaces voorziet in enkele handige componenten die het ontwikkelen voor een webapplicatie
nog leuker maken.
4.3.5.1.1.1 rich:calender
Één van de meest in het oog springende componenten is het kalender component. Door deze lijn
code op een webpagina te plaatsen verschijnt de mooie kalender. De value wordt gebonden aan
een Date object. Het datePattern is een optionele parameter maar geeft je de mogelijkheid om de
datum in de plaatselijke weergave weer te geven.
<rich:calendar value="#{actie.deadline}" datePattern="yyyy-MM-dd HH:mm" />
4.3.5.1.1.2 rich:panel
Om pagina’s op te delen kunnen panelen worden gebruikt. Deze kunnen dan op een heel
gemakkelijke wijze voorzien worden van een header.
<rich:panel>
<f:facet name="header">
<h:outputText value="aanpassen type" />
</f:facet>
...
</rich:panel>
Eindwerk Bram Gadeyne
2007-2008
46
4.3.5.1.1.3 rich:tabPanel
Werken met tabbladeren in een webapplicatie was nog nooit zo gemakkelijk als met deze control.
Het tabpanel heeft een verzameling met tabs die op zich weer code kunnen bevatten. Standaard
worden de tabs geladen via Ajax. We zien in dit voorbeeld dat er een action is opgegeven. Bij het
switchen naar een ander tabblad kunnen we dus ook een method in de back-end laten uitvoeren.
De UI:include is een tag die niet afkomstig is vanuit Richfaces maar uit facelets van JSF. Met deze
tag kun je probleemloos andere pagina’s in een andere pagina includen. Deze pagina’s zullen dan
ook weer gerenderd worden. Op die manier kun je eigenlijk handige componentjes zelf schrijven
die op die manier ook hergebruikbaar zijn doorheen de applicatie. Het gebruik ervan in
tabbladeren zorgt ervoor dat je de tabbladen op zich in apparte files kunt beschrijven wat het
overzicht over de tabbladen behoudt.
<rich:tabPanel id="tabPabel1" switchType="ajax">
<rich:tab id="medewerkerTab" label="personen"
action="#{medewerkerAction.clearMedewerker()}">
<ui:include src="/medewerker/lijst.xhtml" />
</rich:tab>
</rich:tabPanel>
4.3.5.1.1.4 rich:dataTable
Net zoals JSF heeft richfaces een eigen implementatie van de DataTable control. Niet alleen de
layout van dit component maakt het zo interessant. De samenwerking met Ajax is fenomenaal
vooral als het samen wordt gebruikt met het volgende component de dataScroller.
Eindwerk Bram Gadeyne
2007-2008
47
<rich:dataTable id="actieTable" value="#{bean.collectie}"
rows="10" var="item">
<f:facet name="header">
<rich:columnGroup>
<rich:column>
<h:outputText value="naam" />
</rich:column>
...
</rich:columnGroup>
</f:facet>
<rich:column>
<h:commandLink action="#{actieAction.detailSetup()}"
value="#{item.titel}" />
</rich:column>
</rich:dataTable>
4.3.5.1.1.5 rich:dataScroller
Als we een tabel hebben waarvan we niet alle records willen laten zien dan kunnen we dankzij
deze scroller gemakkelijk onze tabel dynamisch opvullen. In het vorige voorbeeld hadden we
bijvoorbeeld het aantal rijen (rows) op 10 ingesteld. Het opvullen van de gegevens gebeurt dan
ook via Ajax waardoor dit relatief snel verloopt.
<rich:datascroller for="actieTable" />
4.3.5.1.1.6 rich:inputSlider
Een leuk component is de inputSlider waarmee men een waarde visueel kan voorstellen tussen 2
waarden.
<rich:inputNumberSlider minValue="1" maxValue="5" value="#{bean.value}" />
Eindwerk Bram Gadeyne
2007-2008
48
4.3.5.1.1.7 rich:inputSpinner
Geeft net als de inputSlider de mogelijkheid om waarden gemakkelijk te veranderen. Ikzelf vind
dat deze control niet echt een meerwaarde biedt. Het aantal toetsaanslagen zal meestal kleiner
zijn dan het aantal muisklikken.
<rich:inputNumberSpinner value="#{bean.value}">
4.3.5.1.1.8 rich:tree
Een component die ik ook veel heb gebruikt is een RichTree. Een tree programmeren voor het web
is moeilijk maar dankzij Richfaces nu dus gemakkelijker dan ooit. Al is het Tree component toch
één van de moeilijkste componenten om te gebruiken binnen Richfaces.
<rich:tree id="tree" switchType="ajax" showConnectingLines="false"
value="#{competentieAction.treeNode}" var="item"
nodeFace="#{item.type}" ajaxSubmitSelection="true">
<rich:treeNode type="type" icon="/img/openfolder.png"
iconLeaf="/img/closefolder.png">
<h:outputText value="#{item.typenaam} " />
</rich:treeNode>
<rich:treeNode type="competentie" icon="/img/multicomp.png"
iconLeaf="/img/comp.png">
<h:outputText value="#{item.naam} " />
</rich:treeNode>
</rich:tree>
Eindwerk Bram Gadeyne
2007-2008
49
De value die aan deze Tree gekoppeld wordt is van het type “org.richfaces.model.TreeNode”. Dit is
echter alleen maar een abstracte klasse. Het uiteindelijke object dat we gebruiken om de Nodes
voor te stellen zijn er van het type “org.richfaces.model.TreeNodeImpl”. Het belangrijkste wat we
aan een dergelijke TreeNode kunnen meegeven is data in de vorm van gelijk wel Object. Ook
kunnen we aan elke Node een collectie van ChildNodes toevoegen waardoor we de
boomstructuur verkrijgen.
Nu kunnen we opgeven welke nodes op welke manier in de tree moeten worden weergegeven.
Dit doen we door bijvoorbeeld een @Transient veld type op te vullen. (meer informatie over @
Transient vind je bij het hoofdstuk over Persistence). In het bovenstaande voorbeeld wordt dit dan
opgegeven als nodeFace. De juiste TreeNode wordt dan gekozen aan de hand van dit type.
Per TreeNode kunnen we dan bepaalde looks veranderen zoals de icoontjes die moeten
verschijnen voor een node.
4.3.5.1.1.9 Handige attributen
Bij elke richfacescomponent kun je nog enkele attributen opgeven die soms wel handig kunnen
zijn. Meestal zijn het attributen die een beperking voor de ingave verzorgen of die de layout van
het component laten veranderen. Er zijn echter ook enkele attributen die bijna elk richfaces- of
JSF-component voorziet.
•
•
•
Disabled: met dit attribuut kun je een boolean waarde opgeven die ervoor zorgt dan een
component wel zichtbaar is maar niet wijzigbaar.
Render: met dit attribuut kun je een boolean waarde meegeven die aanduidt of het
component en zijn subcomponenten moeten worden weergegeven. Dit kan handig zijn om
delen van het programma bijvoorbeeld af te schermen voor gebruiker die niet voldoende
rechten hebben.
ID: Elke component kunnen we een ID geven. Dit kan handig zijn bij het gebruik van Ajax.
Eindwerk Bram Gadeyne
2007-2008
50
4.3.5.1.2 Problemen met de Tree
Het gebruik van de Tree was in mijn project redelijk cruciaal. Het opvullen van de Tree en het
afbeelden op zich vormden geen enkel probleem en werkten mooi samen met AJAX.
Interactie op een Tree om bijvoorbeeld Nodes toe te voegen was iets wat moeilijk was. Het was
een moeilijke opgave om te weten te komen welke Node nu precies geselecteerd was. Ik heb
hiervoor 2 methodes uitgezocht waarvan ik uiteindelijk de laatste heb gebruikt.
4.3.5.1.2.1 De NodeSelectListener
Bij de Tree kun je een attribuut opgeven die verwijst naar een methode en die werkt onder de
vorm van een listener.
nodeSelectListener="#{competentieAction.treeListener}"
In mijn geval was dit dus de methode treeListener in mijn competentieAction Bean. De methode
zag er ongeveer als volgt uit.
public void treeListener(NodeSelectedEvent event) {
UITree tree = (UITree) event.getComponent();
Object fromEvent = tree.getRowData();
try {
if (fromEvent.getClass().equals(Type.class)) {
Type type = (Type) fromEvent;
// doe iets
}
if (fromEvent.getClass().equals(Competentie.class)) {
Competentie competentie = (Competentie) fromEvent;
//doe iets
}
} catch (RuntimeException e) {
}
}
Zoals je kunt zien kun je bij elke NodeSelectedEvent die zich voordoet te weten komen welke
Node nu precies geselecteerd was en welke Data hij bevatte. Helaas werkte deze listener niet
perfect. Het gebeurde heel vaak dat een bepaalde Node uit de Tree 2 maal moest geselecteerd
worden alvorens hij echt geselecteerd bleek te zijn. Hoewel bij het debuggen en dergelijke alles
zeer normaal leek te verlopen aan de kant van de server, bleek dat de opnieuw gerenderde delen
aan de client kant niet overeenstemden met de keuze.
Ik merkte dat dit probleem zich vaker voordeed wanneer de server zwaar belast werd. Een echte
oorzaak voor het probleem heb ik echter niet gevonden. Daarom ging ik op zoek naar een
alternatief.
4.3.5.1.2.2 Checked Tree oplossing
Wat mij ook was opgevallen bij mijn eerste oplossing was dat ik nooit visueel kon zien of de server
nu begrepen had dat ik een bepaalde node had geselecteerd. Daarom plaatste ik een checkbox in
mijn TreeNode.
<h:selectBooleanCheckbox value=”select me">
Eindwerk Bram Gadeyne
2007-2008
51
<a4j:support event="onclick" actionListener="#{bean.listener}" />
</h:selectBooleanCheckbox>
Aan een selectbox kan een Listener worden gehangen. Meer uitleg hierover vind je in het
hoofdstuk over A4J (Ajax for JSF).
public void listener(ActionEvent event) {
Object o = findSelected(treeNode.getChildren());
setFalseVars();
if (o != null) {
if (o.getClass().equals(Type.class)) {
type = (Type) o;
fromEvent=o;
competentie = new Competentie();
nodeSelected = true;
eType=true;
type.setSelected(false);
}
if (o.getClass().equals(Competentie.class)) {
competentie = (Competentie) o;
fromEvent=o;
type = new Type();
nodeSelected = true;
eComp=true;
competentie.setSelected(false);
}
}
}
@SuppressWarnings("unchecked")
private Object findSelected(Iterator it) {
Object foundObject = null;
while (it.hasNext() && foundObject == null) {
Entry e = (Entry) it.next();
TreeNode node = (TreeNode) e.getValue();
Object o = node.getData();
if (o.getClass().equals(Type.class)) {
Type t = (Type) o;
if (t.isSelected()) {
foundObject = t;
}
}
if (o.getClass().equals(Competentie.class)) {
Competentie c = (Competentie) o;
if (c.isSelected()) {
foundObject = c;
}
}
if (foundObject == null) {
foundObject = findSelected(node.getChildren());
}
}
return foundObject;
}
De value van de chekbox was gebonden aan een @Transient boolean veld “selected”. Wanneer
men dus ergens in de tree een selectbox aanvinkte dan werd deze selected value voor het Object
op true gezet en werd de checkBoxListener uitgevoerd.
Eindwerk Bram Gadeyne
2007-2008
52
Wanneer de Listener werd uitgevoerd werd eerst het geselecteerde object gezocht en indien die
bestond teruggegeven. Met dat geselecteerde object konden we dan het gewenste uitvoeren.
Deze manier bleek beter te werken. Je moest geen 2 maal het gewenste item selecteren en de
gebruiker ziet ook visueel welke node hij/zij geselecteerd heeft. Dit visuele aspect is wel
browserafhankelijk. Sommige browsers zullen een geselecteerd item geselecteerd laten terwijl
anderen het zullen deselecteren.
4.3.5.1.3 Javascript in Richfaces
Om een boodschap te verkrijgen die verschijnt met de vraag of ik zeker het gevraagde object wil
verwijderen heb ik een eenvoudig javascript scriptje op het internet gevonden en bewerkt.
<script language="JavaScript">
<!-// source: http://www.shiningstar.net/articles/articles/javascript/confirmsubmit.asp
function confirmSubmit()
{
var agree=confirm("Verwijderen?");
if (agree)
return true ;
else
return false ;
}
// -->
</script>
Ik wou dit script laten uitvoeren in een A4J commandLink. Daarin kun je een onclick event
definiëren. Eerst had ik gewoon confirmSubmit() opgeroepen maar toen bleek zowel bij een true
of false antwoord dat het verdere script niet werd uitgevoerd. Via de tool fireBug van Firefox kon
ik gemakkelijk de gegenereerde javascriptcode bekijken. Richfaces voegt zelf ook nog code toe aan
het onclick event. Omdat dit scriptje iets returnde, werd in ieder geval de rest van deze Richfaces
javascript code niet meer uitgevoerd. Uiteindelijk heb ik dit probleempje dan kunnen oplossen
door de confirmSubmit() methode als volgt op te roepen.
onclick="if(!confirmSubmit()) return false"
4.3.5.2 Ajax For JSF (A4J)
De ondersteuning voor Ajax in Richfaces zit intern ingebouwd maar maakt gebruik van A4J.
Componenten op zich kunnen samenwerken met elkaar en gebruiken daarbij soms Ajax. Het
TabPanel is daar 1 van de mooiste voorbeelden voor.
Als programmeur heb je natuurlijk zelf ook graag de touwtjes in handen. Daarom kun je A4J
gebruiken. Het voorziet in een aantal componenten die het mogelijk maken om Ajax support toe
te voegen aan de gewone JSF componenten.
Het voorziet ook in een paar componenten zoals buttons of links.
Eindwerk Bram Gadeyne
2007-2008
53
4.3.5.2.1 Controls
4.3.5.2.1.1 A4J:CommandButton
De A4J commandButton heeft een attribuut reRender. Bij dit attribuut kun je de id van een
component opgeven die gererendered moet worden. De button kan uiteraard ook een actie
uitvoeren.
<a4j:commandButton action="#{bean.someAction()}"
value="dit is een knop" reRender="idVanRichComponent">
</a4j:commandButton>
4.3.5.2.1.2 A4J:CommanLink
De commandLink heeft dezelfde functionaliteiten als de commandButton. Ze wordt alleen
weergegevens als een link in plaats van een knop.
<a4j:commandLink action="#{bean.someAction()}"
value="dit is een knop" reRender="idVanRichComponent">
</a4j:commandLink>
4.3.5.2.1.3 A4J:support
<h:selectBooleanCheckbox value=”select me">
<a4j:support event="onclick" actionListener="#{bean.listener}" />
</h:selectBooleanCheckbox>
De A4J:support voegt mogelijkheden toe aan een JSF component om toch via AJAX te kunnen
werken. Het belangrijkste attribuut dat we moeten opgeven is het event attribuut waarin we elk
event type uit de gewone html kunnen opgeven. In dit voorbeeld voegen we een actionListener
toe aan de checkbox.
4.3.5.2.1.4 A4J:status
Dit component voorziet in een mogelijkheid om visueel weer te geven wanneer een Ajax request
bezig is. Hieronder zien we een voorbeeldje. Tijdens de request wordt de tekst “loading…”
weergegeven op de gewenste locatie.
<a4j:status startText="loading..."></a4j:status>
4.3.6 Seam Logging
Één van de eerste componenten die ik gebruikt heb en waarin Seam voorziet is een logging
mechanisme gebaseerd op het framework Log4J.
Het loggen van gebeurtenissen die zich voordoen binnen een applicatie wordt door sommige
programmeurs gedaan door een volledige stacktrace in de serverlog op te slaan. Mensen die zich
bezighouden met het deployen van een applicatie hebben hier echter niet veel aan. Voor hen is
het gemakkelijker om bijvoorbeeld een foutcode door te geven aan een programmeur die dan de
fout kan reproduceren of traceren.
Eindwerk Bram Gadeyne
2007-2008
54
Ook het gebruik van System.out.println(“”); statements is hierbij niet echt een goede zaak. Soms
kan het handiger zijn dat logging code weggeschreven wordt naar een database of naar een
andere vorm van dataopslag. Frameworks bieden een oplossing voor deze problemen.
Seam heeft een eigen implementatie van Log4J van apache geïmplementeerd. Op die manier kun
je gemakkelijk kiezen of een loggingstatement moet output geven naar een io.writer, een a4j
server of vele andere outputmanieren. De gelogde messages kun je opdelen in een aantal niveaus
TRACE, DEBUG, INFO, WARN, ERROR en FATAL. Aan de hand van deze niveaus kan de
programmeur sneller weten om welk door messages het gaat en eventueel de ernst van de fout
bepalen.
Seam voorziet in een Log object die gemakkelijk via injectie kan geraadpleegd worden. Door de
volgende code in een EJB te plaatsen kunnen we deze loggen. Het zal ook steeds bij een
logstatement weergeven uit welk object het gelogde statement komt.
@Logger
Log log;
Het loggen zelf gebeurt dan automatisch. Het enige wat we zelf nog moeten voorzien zijn log
statements. Voor een infobericht kan dit het volgende zijn.
log.info("createSetup uitgevoerd.");
Een error bericht die we meestal in een catch blok zetten kan dit zijn.
try{
//iets
} catch (Exception e) {
log.error("kon createSetup niet uitvoeren." + e.getMessage());
}
De configuratie van de logging kan voor de jboss server gebeuren via het configuratie bestand
jboss-log4j.xml. Seam zal de implementatie van de Log4J van de JBoss server gebruiken. Enkele
problemen die ik echter tegenkwam bij het gebruik van de JBoss logging kun je terugvinden bij het
hoofdstuk over JBoss AS 4.
4.3.7 Seam Mail
Seam voorziet in een mail component die je toelaat om gemakkelijk mails op te stellen in
samenwerking met JSF. Hiervoor gebruikt Seam een implementatie van JavaMail
Mail wordt gegenereerd via een Renderer object. Zoals alle andere objecten in Seam kun je de
Renderer via injection opvragen.
@In(create = true)
private Renderer renderer;
Hieronder een codevoorbeeld voor het versturen van mails. Hier wensen we bijvoorbeeld een
object actie met als EL-naam actieconv te gebruiken in onze mail. Daarna laten we de renderer de
Eindwerk Bram Gadeyne
2007-2008
55
mail renderen en plaatsen een informatiebericht in onze log. De Seam Mail syntax ziet er als volgt
uit:
Contexts.getConversationContext().set("actieconv", actie);
renderer.render("/mail/actiemail.xhtml");
log.info("reminder sent for actie");
Hierna vind je een voorbeeld van de mail die we graag zouden versturen. We merken de “m:” tags
die afkomstig zijn uit Seam Mail. Ze laten ons toe om standaard onderdelen van een mail zoals de
verzender, ontvanger, onderwerp, body, attachments, … te configureren en in te vullen.
<m:message xmlns="http://www.w3.org/1999/xhtml"
xmlns:m="http://jboss.com/products/seam/mail"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<m:from name="ComMaS" address="[email protected]" />
<m:to name="#{actieconv.medewerkerid.voornaam} #{actieconv.medewerkerid.naam}"
address="#{actieconv.medewerkerid.mail}"></m:to>
<m:subject>Reminder for action</m:subject>
<m:body>
<!--de ingevulde body met gebruik van het actie object actieconv -->
<p>Title:</p>
<p> #{actieconv.titel}</p>
</m:body>
</m:message>
Het opstellen en verzenden van een mail in Seam is dus zeer eenvoudig geïmplementeerd.
4.3.8 Seam Timer
Seam voorziet in een mogelijkheid om methoden te definiëren die asynchroon kunnen worden
uitgevoerd. Dit wil zeggen dat ze bijvoorbeeld eenmalig op een bepaald tijdstip of meerdere malen
dankzij een bepaalde frequentie zullen worden uitgevoerd. Hiervoor gebruikt Seam een
implementatie van het framework Quartz die dezelfde functionaliteit wil aanbieden.
Een voorbeeld van een Asynchrone methode is
@Asynchronous
public Timer processIets(@IntervalDuration Long interval, @Expiration Date when) {
System.out.println(“iets gedaan”);
return null;
}
Als we deze methode in een interface definiëren moeten we ook daar deze annotaties voorzien.
Het starten van een Asynchrone methode kan gewoon gebeuren door deze op te roepen en de
overeenkomstige values in te vullen.
De @IntervalDuration annotatie geeft de frequentie in milliseconden aan tussen het uitvoeren van
de methode. De @Expiration annotatie bevat een datum waarop de assynchrone uitvoering van
deze method zal worden gestopt.
Eindwerk Bram Gadeyne
2007-2008
56
4.3.9 Seam Timer met Seam Mail
Op een gegeven moment kwam er de vraag om via Seam automatische mail generatie te voorzien.
Omdat zowel het mailen binnen Seam perfect werkte alsook het uitvoeren van een Asynchrone
methode leek de combinatie van de 2 een heel eenvoudige oplossing. Helaas ben ik na lang
zoeken tot de vaststelling moeten komen dat de werking van die 2 functies binnen Seam samen
niet ondersteund is.
De Seam Mail maakt gebruik van een component Renderer die ergens in de ApplicationContext
opgeslagen is. Helaas kan men vanuit een Seam Timer die in een andere Thread wordt uitgevoerd
deze Context niet opvragen waardoor het uitvoeren van de render methode onmogelijk is en dus
ook het automatisch versturen van Mails. Binnen JBoss is dit probleem gekend en staat hetzelfde
probleem vermeld op de volgende 2 aan elkaar gelinkte Jira websites. Jira is een framework die
voorziet in bug management voor projecten. Op die manier kunnen bugs binnen een bepaald
project gemakkelijk worden gevolgd en opgelost. JBoss belooft een oplossing voor dit probleem in
de volgende release van Seam namelijk Seam 2.1.0 GA.
http://jira.jboss.com/jira/browse/JBSEAM-2915
http://jira.jboss.com/jira/browse/JBSEAM-2507
4.3.10 Seam authenticatie
Authenticatie is tegenwoordig zeer belangrijk geworden bij het gebruik van webapplicaties. Een
gebruiker is meestal voorzien van een gebruikersnaam en een paswoord om taken op de
webapplicatie uit te voeren. Ook hier heeft Seam een oplossing voor.
Het zogeheten Identity object laat toe om een gebruiker voor de duur van een sessie in te laten
loggen. Via die Identity zal Seam de rollen waarvan de gebruiker lid is kunnen terugvinden en zo
de applicatie beveiligen.
4.3.10.1 Het Gebruik
@In()
Identity identity;
identity.addRole(“een rol”);
In JSF kunnen we dan gemakkelijk controleren of de huidige gebruiker een bepaalde rol heeft door
het rendered attribuut van het JSF component op te vullen met de s:hasRole(“rol”) functie.
rendered="#{s:hasRole('c') or s:hasRole('pv') or s:hasRole('a')}"
We kunnen ook pagina’s afschermen op basis van de rollen van een gebruiker. Dit kunnen we
doen in de pages.xml file.
<page view-id="/admin.xhtml" login-required="true">
<restrict>#{s:hasRole('c') or s:hasRole('ps') or s:hasRole('pv') or s:hasRole('a')}</restrict>
</page>
Eindwerk Bram Gadeyne
2007-2008
57
We moeten zorgen dat layout items nooit login required zijn. De kans bestaat anders dat onze
applicatie raar reageert wanneer een pagina moet worden weergegeven. De helft van de layout
zou kunnen verdwenen lijken. Daarom heb ik ook nog de volgende regels in mijn pages.xml
toegevoegd.
<!-- layout items mogen niet login-required zijn -->
<page view-id="/layout/*" login-required="false" />
<page view-id="/img/*" login-required="false" />
<page view-id="/stylesheet/*" login-required="false" />
Een method kunnen we ook voorzien van een @Restrict annotatie waarin we dan net zoals in JSF
de EL-expressie s:hasRole(“”) kunnen gebruiken.
@Restrict("#{s:hasRole('c') or s:hasRole('pv') or s:hasRole('a')}")
public String uploadKlantentevredenheid() {
fileUploaderService.uploadKlantentevredenheid(data, fileName);
return "medewerker_detail";
}
4.3.10.2 De Configuratie
In de components.xml file moeten we de security:identity tag opvullen om aan te geven welke
method we willen gebruiken om de login te verifiëren.
<security:identity authenticate-method="#{loginService.login}" remember-me="true" />
4.3.11 Seam Fileupload/filedownload
FileUpload is in Seam heel gemakkelijk geïntegreerd. Over het effectieve transport van gegevens
tussen client en server hoef je je als programmeur eigenlijk geen zorgen meer te maken. Hiervoor
maakt Seam gebruik van de library’s uit het commons fileupload project. Commons is een project
van Apache die graag functionaliteiten wil groepen voor veel gebruikte (common in het engels)
functionaliteiten.
In de JSF pagina kunnen we gebruik maken van het Seam component s:fileUpload.
<s:fileUpload id="artwork" data="#{fileUploader.data}"
fileName="#{fileUploader.fileName}" size="40" maxlength="40"
required="true" >
</s:fileUpload>
De belangrijkste zaken die we hier gebruiken zijn de data en filename binding. In onze bean
voorzien we dan ook een getter en setter voor deze 2 zaken. We kunnen dan via een button een
action laten uitvoeren zoals uploadKlantentevredenheid(). De data-array moeten we in de
constructor instantiëren op een bepaalde lengte. De data-array zal dan in de service
weggeschreven worden naar een file met de bepaalde fileName.
@Stateless
@Name("fileUploader")
@Scope(ScopeType.APPLICATION)
Eindwerk Bram Gadeyne
2007-2008
58
public class FileUploaderAction implements IFileUploader {
public FileUploaderAction() {
data = new byte[10000];
}
@In(create = true)
@Out
IFileUploaderService fileUploaderService;
private byte[] data;
private String fileName;
public String uploadKlantentevredenheid() {
fileUploaderService.uploadKlantentevredenheid(data, fileName);
return "medewerker_detail";
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
Om een bestand opnieuw te downloaden voorziet Seam, voor zover ik heb kunnen achterhalen,
echter niet echt een oplossing. Ik heb na lang zoeken toch een oplossing gevonden die via de
gewone JSF kan worden gebruikt.
Om een bestand te downloaden voorzien we ergens op een webpagina een knop die een actie kan
uitvoeren. Deze knop mag geen A4J button zijn want om een bestand door te zenden willen we
geen AJAX verwerking gebruiken. Hieronder zien we een voorbeeld om het downloaden van
bestanden tussen een client en een server mogelijk te maken. JSF is gebaseerd op JSP. JSP is dan
weer gebaseerd op servlets. In dit voorbeeld moeten we teruggaan naar de basisarchitectuur van
java webapplicatie. Een servlet bevat steeds een HttpServletRequest en een HttpServletResponse
die overeen komen met de request en response van een http event. Via de response heeft een
servlet toegang tot een outputstream die gebruikt wordt om de http-content zoals webpagina’s
naar de client te kunnen verzenden.
In JSF gaan alle webpagina’s door 1 zo’n servlet genaamd de “faces servlet”. Die heeft natuurlijk
ook toegang tot zo’n OutputStream. In dit voorbeeld hieronder zal de method
writeToOutPutStream() de OutputStream van de “faces servlet” opvragen. Hij zal ook een
InputStream maken die het mogelijk maakt om een File uit het systeem te lezen.
Eindwerk Bram Gadeyne
2007-2008
59
Als laatste zal de streamCopy() methode de bytes uit de InputStream kopiëren naar de
OutputStream.
Als dit gebeurt is dan wordt de OutputStream geflusht (leeggemaakt) en gesloten. Er wordt een
responseComplete() vlag opgeroepen zodat JSF weet dat hij nu de gehele inhoud van de
OutputStream mag doorsturen naar de client.
Hier onder het uitgewerkte voorbeeld voor een download method in Seam.
@Name("fileUploaderService")
@Stateless
@Scope(ScopeType.SESSION)
public class FileUploaderService implements IFileUploaderService {
@Logger
Log log; //meer info over de logger in het hoofdstuk over Seam logging
public void downloadKlantentevredenheid(Klantentevredenheid kt) {
String fileDest = “…” // een bestandslocatie
writeToOutputStream(fileDest, kt.getBestand());
}
public void writeToOutputStream(String fileDest, String fileName) {
try {
File file = new File(fileDest);
FileInputStream iStream = new FileInputStream(file);
ExternalContext ectx = FacesContext.getCurrentInstance()
.getExternalContext();
HttpServletResponse response = (HttpServletResponse) ectx
.getResponse();
try {
OutputStream out = response.getOutputStream();
response.setHeader("Content-disposition",
"attachment; filename=" + fileName);
streamCopy(iStream, out);
out.flush();
out.close();
FacesContext.getCurrentInstance().responseComplete();
file.delete();
} catch (IOException ex) {
file.delete();
}
} catch (FileNotFoundException e) {
log
.error("kon geen writeToOutputStream uitvoeren"
+ e.getMessage());
}
}
public void streamCopy(FileInputStream fileInputStream,
OutputStream outputStream) throws IOException {
I f (fileInputStream == null || outputStream == null)
return;
byte abyte0[] = new byte[8192];
int i;
synchronized (fileInputStream) {
synchronized (outputStream) {
while ((i = fileInputStream.read(abyte0)) != -1)
outputStream.write(abyte0, 0, i);
Eindwerk Bram Gadeyne
2007-2008
60
}
}
}
}
4.3.12 Seam Taalondersteuning
Een applicatie niet kunnen vertalen is ondenkbaar geworden bij het maken van grote projecten. In
Java gebruikt men hiervoor messages.properties bestanden. Properties-bestanden zijn bestanden
die sleutels (keys) bevatten aan de hand van welke we een waarde (value) kunnen opvragen. Het
bestand Messages.properties bevat hiervoor dan de defaultwaarden. Messages_nl.properties
bevat dan de waarden voor een Nederlandstalige pagina.
Seam zal de juiste taal kiezen aan de hand van de ingestelde locale van de browser van de client.
We kunnen deze natuurlijk zelf verzetten dankzij het gebruik van de EL en door het localeSelector
component van Seam.
Een voorbeeld met een selectbox in Seam.
<h:selectOneMenu value="#{localeSelector.language}">
<f:selectItem itemLabel="English" itemValue="en"/>
<f:selectItem itemLabel="Deutsch" itemValue="de"/>
<f:selectItem itemLabel="Francais" itemValue="fr"/>
</h:selectOneMenu>
<h:commandButton action="#{localeSelector.select}" value="Change"/>
Hier zal een gebruiker een taal kunnen kiezen en dit bevestigen door op een knop “Change” te
klikken.
Ik heb echter zelf een andere implementatie gebruikt door middel van linkButtons omdat er dan
slechts 1 druk op de knop nodig is om de gewenste taal te kiezen.
<h:commandLink value="NL" action="#{localeSelector.selectLanguage('nl')}" />
Er bestaan ook mogelijkheden om dynamisch alle beschikbare locales op te vragen via de
localeSelector om daarmee dan een selectOneMenu dynamisch op te kunnen vullen.
In een component zelf kunnen we de key van een bijhorende value gemakkelijk linken door de key
op te vullen met de code zoals “commas.hello” in het volgende voorbeeld. Aan de hand van deze
key zal de value worden opgevuld met de waarde van de bijhorende locale. De key in onderstaand
voorbeeld is “commas.hello”.
<h:outputText value="#{messages['commas.hello']}" />
4.3.13 Persistence – Hibernate
Persistence is niet meer weg te denken bij de creatie van nieuwe webapplicaties. Het is een hele
handige tool om datamodellen om te zetten in objecten of omgekeerd. Zo’n omgezet object wordt
dan een entity genoemt.
Eindwerk Bram Gadeyne
2007-2008
61
Een entity bevat voor elke kolom in een bepaalde tabel een waarde met de bijhorende getter en
setter. Een tabel heeft meestal ook een aantal referenties naar andere tabellen. Deze andere
tabellen kunnen ook omschreven worden als een entity klasse. Om de referenties weer te geven
wordt er dan gebruik gemaakt van collecties die entity klassen bevatten. Voor een many to one
relatie wordt een instantie van het gerelateerde entity object bijgehouden.
Een entity klasse heeft ook steeds een id. Deze id kan een veld zijn die geannoteerd is met de @Id
annotatie zoals in onderstaand voorbeeld. Een id kan ook samengesteld zijn uit een aantal velden.
In zo’n geval moeten we een samengestelde id definiëren. In zo’n geval wordt een nieuwe klasse
opgesteld met daarin deze velden en hun getters en setter. Deze klasse wordt dan @Embeddable
gedefinieerd. In de entity wordt dan een instantie van deze embeddable klasse bijgehouden en
geannoteerd met @EmbeddedId.
Boven een Collectie kan men een CascadeType opgeven. Dit geeft aan wat er moet gebeuren met
de gerelateerde rijen in andere tabellen wanneer deze entity zou worden verwijderd.
Een voorbeeld van een medewerker entity object:
Eindwerk Bram Gadeyne
2007-2008
62
@Entity
public class Medewerker implements Serializable {
@Id
@GeneratedValue(generator = "MedewerkerSeq")
@SequenceGenerator(name = "MedewerkerSeq", sequenceName = "MEDEWERKER_SEQ",
allocationSize = 1)
private Long id;
private String persnr;
private String mail;
private String naam;
private String verkortenaam;
private String voornaam;
private String username;
private Long password;
private String rol;
@ManyToOne
@JoinColumn(name = "CHEF")
private Medewerker chef;
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "medewerkerid")
private Set<GevolgdeOpleiding> gevolgdeOpleidingCollection;
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "medewerkerid")
private List<Competentiefiche> competentieficheCollection;
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "medewerkerid")
private Set<PersoonlijkeOpleiding> persoonlijkeOpleidingCollection;
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "medewerkerid")
private Set<PoVerslag> poVerslagCollection;
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "medewerkerid")
private Set<Actie> actieCollection;
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "medewerkerid")
private Set<Klantentevredenheid> klantentevredenheidCollection;
//getters en setters
}
Seam gebruikt voor zijn persistence laag hibernate. Hibernate is een framework die voorziet in
persistence mogelijkheden Omdat Seam streeft naar het gebruik van standaarden wordt echter
persistence gebruikt via JPA. JPA is een standaard van Sun waaronder een bestaand persistence
framework kan gekoppeld worden Het gebruik van hibernate zelf merk je dus niet echt. Een ander
voorbeeld van een persistence framework is bijvoorbeeld Toplink van Oracle.
Als programmeur moet je het configuratiebestand persistence.xml invullen (of Seam doet dit voor
jou wanneer je een nieuw project start). Een voorbeeld van zo’n xml bestand vind je hieronder.
Zoals je kan zien zal een persistence-unit aangemaakt worden met een bepaalde naam. Hiervoor
zal een bepaalde provider gebruikt worden. In ons geval is dit dan hibernate.
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
Eindwerk Bram Gadeyne
2007-2008
63
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="ProjectCommasPU">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/jdbc/OracleDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="true"/>
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/ProjectCommasEntityManagerFactory"/>
</properties>
</persistence-unit>
</persistence>
Door persistence te configureren kunnen we gebruik maken van een entity manager. Zo’n
manager weet hoe hij connectie kan maken met de datasource en kent een aantal acties om rijen
uit de database om te zetten naar entity objecten en voorziet in CRUD(create, read, update,
delete) mogelijkheden voor deze objecten in de databank. Het oproepen van de entity manager is
dankzij JPA heel gemakkelijk. Dankzij de annotatie @PersistenceContext wordt voor ons een entity
manager geïnjecteerd op de geannoteerde locatie. Een voorbeeld:
@PersistenceContext(unitName = "ProjectCommasPU")
private EntityManager entityManager;
Seam voorziet echter ook zelf in een implementatie van zo’n entity manager waardoor we zelfs de
unitName van de gewenste entity manager niet moeten kennen. Dit is de manier om een entity
manager op te vragen in Seam.
@In(create=true)
private EntityManager entityManager;
In mijn project heb ik af en toe ook gebruik gemaakt van de @Transient annotatie die het mogelijk
maakt om een extra veld toe te voegen aan een entity zonder dat deze effectief beschikbaar is in
de database. Persistence zal dit veld dan ook negeren bij het wegschrijven van waarden naar een
nieuwe of een geüpdate rij.
4.3.14 Rapportering
Voor het maken van rapporten heb ik gebruik gemaakt van Jasperreports van JasperSoft. Een IDE
die het mogelijk maakt om Jasperreports te genereren is IReport die ook van JasperSoft is. Ze
worden beiden hieronder wat meer toegelicht.
4.3.14.1 IReport
Om de rapporten te kunnen ontwerpen heb ik gebruik gemaakt van IReport van Jaspersoft. Deze
handige tool maakt het gemakkelijk om via wizards de jrxml files te genereren. Deze jrxml files
bevatten de beschrijving van een rapport in XML. IReport kan via een plugin ook zorgen voor het
compileren van deze jrxml files naar jasper files welke Jasperreports nodig heeft om het
uiteindelijke rapport te kunnen genereren.
Eindwerk Bram Gadeyne
2007-2008
64
In IReport kunnen we aan de hand van een wizard een datasource definiëren. Die laat ons dan toe
om een query te schrijven. Uit de query zal IReport alle benodigde Fields halen en ze in een
rapport verwerken. We kunnen dan detailweergaven maken die op basis van groepsbreking van
een aantal velden werkt. We kunnen ook Subrapporten toevoegen die ons toelaten extra
informatie via een bepaalde parameter en query aan het rapport toe te voegen.
In IReport kunnen we de rapportgeneratie al testen door het gebruik van de actieve datasource
connectie.
Hieronder zien we een screenshot van een rapport in IReport. Bovenaan kunnen we allerlei
componenten toevoegen als tekstvelden, grafieken, afbeeldingen en subrapporten. Het rapport is
opgedeeld in een titelblad, een paginabegin, detailweergave die per record zal worden ingevuld en
een pagina footer.
4.3.14.2 JasperReports
JasperReports laat toe om rapporten te genereren vanuit een datasource. Die rapporten kun je
dan bijvoorbeeld naar PDF, xml, webpagina’s, tekst en nog andere laten afdrukken. Jasperreports
heeft hiervoor .jasper files nodig of .jrxml files waaruit je *.jasper files kun compileren.
Eindwerk Bram Gadeyne
2007-2008
65
Om PDF’s te kunnen genereren maakt JasperReports gebruik van de IText library. IText is een
gratis Java library die PDF’s kan genereren.
Op zich is JasperReports dus een library die functionaliteit voorziet om rapporten te genereren in
een aantal formaten en door het gebruik van een datasource. Ook grafieken laten genereren van
allerlei gegevens is mogelijk met JasperReports.
4.3.15 Testing
Testing is een onderdeel van de programmatie van een applicatie waar tegenwoordig veel belang
aan wordt gehecht. Een goede test kan nadien uitwijzen of de applicatie na het aanbrengen van
wijzigingen nog steeds goed zal werken.
4.3.15.1 JUnit 4
Standaard testen worden in het framework JUnit geschreven. In de nieuwe JUnit 4 worden testen
geschreven door ze te annoteren met de @Test annotatie.
We kunnen ook een @Before methode definiëren om voor elke test een aantal zaken uit te laten
voeren.
Via assert methoden kunnen we dan enkele uitkomsten vergelijken om te laten blijken of onze
test gelukt is of niet. Een niet opgevangen Exception laat ook onze test falen.
Een voorbeeld van een JUnit 4 test klasse:
Eindwerk Bram Gadeyne
2007-2008
66
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
public class LoginActionTest {
ILoginAction loginAction;
@Before
public void setUp() throws Exception {
loginAction=new LoginAction();
}
@Test
public void testLoginTrue() {
//iets doen zodat een positieve login plaatsvindt
assertEquals("medewerker_detail", loginAction.login());
}
@Test
public void testLoginFalse() {
//iets doen zodat een negatieve login plaatsvindt
loginService.setIncome(false);
assertEquals("", loginAction.login());
}
}
4.3.15.2 DBUnit
Omdat JUnit standaard buiten een Application Server en dus gewoon in een IDE wordt uitgevoerd
kunnen we standaard geen persistence testen of andere testen die gebruik maken van een
bepaalde Container (zoals EJB) uitvoeren. Voor het gebruik van Persistence is immers een
connectie met een databank en een PersistenceContext nodig. DBUnit voorziet een uitbreiding op
JUnit die wel toelaat om een PersistenceContext te gebruiken.
In onderstaand voorbeeld kunnen we de werking van DBUnit volgen. Deze klasse test onze
ActieDAO.
•
•
•
•
Onze testklasse extends van BaseSessionBeanFixture<ActieDAO>. BaseSessionBeanFixture
is een abstracte klasse die via Generics onze ActieDAO beschikbaar zal maken als een
SessionBean met toegang tot een PersistenceContext.
In de klasse definiëren we een class[] waar we al onze entity klassen in opsommen.
In de constructor roepen we de super constructor op met als argumenten de ActieDAO
klasse en de array van entity klassen.
In een methode kunnen we dan onze te testen ActieDAO opvragen door de
getBeanToTest() methode op te roepen.
Eindwerk Bram Gadeyne
2007-2008
67
/**
* The Class ActieDAOTest.
*/
public class ActieDAOTest extends BaseSessionBeanFixture<ActieDAO> {
/** The Constant usedBeans. */
@SuppressWarnings("unchecked")
private static final Class[] usedBeans = { Actie.class, Sessie.class,
Medewerker.class, Opleiding.class, GevolgdeOpleiding.class,
Competentiefiche.class, Klantentevredenheid.class, PersoonlijkeOpleiding.class,
Competentie.class, Type.class, PoVerslag.class, Onderwerp.class, Todo.class,
OpleidingCompetentie.class, CompetfFbeschrijving.class,
Functiebeschrijving.class,
Functieprofiel.class, PersoonlijkeCompetentie.class, VerwachteCompetentie.class,
Task.class};
/**
* Instantiates a new actie dao test.
*/
public ActieDAOTest() {
super(ActieDAO.class, usedBeans);
}
/**
* Test get by medewerker.
*/
public void testGetByMedewerker()
{
Medewerker medewerker=new Medewerker();
medewerker.setId(1L);
final ActieDAO dao = getBeanToTest();
List<Actie> lijst=dao.getByMedewerker(medewerker);
assertNotNull(lijst);
}
4.3.15.3 MockObjecten
Ik wou testen uitvoeren voor alle klassen. Het probleem bij een gelaagd model is echter dat de
testen moeten uitwijzen of de klasse op zich de gewenste uitwerking heeft en niet of de
onderliggende lagen hun werk goed doen. Wijzigingen in de ene laag mogen immers ook geen
gevolgen hebben op de andere.
Vandaar dat ik gebruik maakte van MockObjecten om testen uit te voeren. Een MockObject is een
object dat gebaseerd is op de interface van een klasse van een onderliggende laag. Op zich
returnen alle methoden van een MockObject een lege lijst of een nieuwe instantie van het te
returnen object. Je kunt ook Objecten of lijsten laten teruggeven die op zich ook wel iets meer
instantiatie hebben gekend als dat belangrijk zou zijn. Het belangrijkste is dat de uitkomst van een
dergelijk MockObject steeds dezelfde is zodat de testen hierop gebaseerd kunnen worden.
4.3.15.4 Problemen met testing in Seam en EJB3
In Seam wordt vaak gebruik gemaakt van Injectie. Dit gebeurt echter niet op de standaard manier
via de @EJB annotatie maar met de @In en @Out annotatie van Seam. Een JUnit test herkent
deze Injecties echter niet waardoor zich tijdens het testen NullPointExceptions kunnen voordoen.
Eindwerk Bram Gadeyne
2007-2008
68
Ook het gebruik van de @Logger annotatie bracht NullPointExceptions met zich mee waardoor
overal in de code hiervoor een try catch blok moest worden voorzien.
Seam heeft weliswaar een eigen integratie van het TestNG framework die een tegenhanger is voor
JUnit 3. Helaas wordt deze testomgeving minder vaak gebruikt. Zeker omdat nu JUnit 4 de meeste
problemen van JUnit 3 zou aangepakt hebben.
4.3.16 Exception handling
Seam voorziet in een manier om aan exception handling te doen. Soms valt het voor dat er zich in
Seam een fout voordoet die niet kan opgevangen worden. Ook in de code van de programmeur
kan dit uiteraard voorvallen. Om dit probleem op te vangen kun je in de pages.xml file een stukje
XML code toevoegen die zal uitgevoerd worden bij het voorvallen van bepaalde Exceptions. Een
voorbeeld om ViewExpiredExceptions op te vangen is de volgende.
<exception class="javax.faces.application.ViewExpiredException">
<redirect view-id="/login.xhtml">
<message>The session has expired</message>
</redirect>
</exception>
Helaas is dit onderdeel van Seam nog lang niet in orde. Er zijn heel wat fouten binnen Seam die
zelfs na het instellen op de pages.xml file niet zullen worden opgevangen.
Op de volgende JIRA-site van JBoss kun je één van dergelijke fouten terugvinden. Een oplossing
voor het probleem belooft men in de toekomst.
http://jira.jboss.com/jira/browse/JBSEAM-2719.
4.3.17 Servers
4.3.17.1 Jboss AS 4
JBoss voorziet naast frameworks zoals Seam en Richfaces ook in zijn welbekende open-source
Application Server. Deze server is veel lichter dan bijvoorbeeld een Glassfish server. Een nadeel is
wel dat configuratie niet in een mooie IDE kan gebeuren maar via verschillende XML files moet
gebeuren. Het voorziet ook in ondersteuning voor J2EE webapplicaties. Op zich is het gebaseerd
op de andere open-source Java AS Apache Tomcat.
Voor het gebruik van Seam is de JBoss AS heel handig omdat bij de AS ook alle benodigde libraries
voor Seam alsook de Seam library zelf voorzien is. Seam zou natuurlijk ook op andere Application
Servers moeten werken.
Ik heb helaas bij het gebruik van JBoss AS 4 ook 2 grote problemen ondervonden.
4.3.17.1.1
Server Log
Op een gegeven moment kreeg ik van Windows de opmerking dat mijn harde schijf nog maar 100
MB schrijfruimte vrij had. Enkele ogenblikken later was dit zelfs gereduceerd tot 0MB. Toen ik op
zoek ging naar de oorzaak van het probleem bleek dat de Server log van de JBoss Server ongeveer
Eindwerk Bram Gadeyne
2007-2008
69
3,5 GB groot was geworden. De oorzaak van dit probleem was terug te vinden in de configuratie
van de Log4J implementatie waarin de JBoss Server ook standaard voorziet.
Logging gebeurde standaard op debug niveau waardoor een enorme hoeveelheid aan debug
informatie in de serverlog werd weggeschreven. De Log werd nooit leeggemaakt omdat dit
geregeld werd via tijd en deze limiet nooit werd overschreden.
Ik heb dit probleem opgelost door 2 zaken in de jboss-log4j.xml file te wijzigen:
Ik heb het op tijd gebaseerde kuisen van de serverlog vervangen door het op bestandsgrootte
gebaseerde kuisen van de serverlog. Hierbij heb ik de maximum grootte dan ingesteld op 2000 KB.
Natuurlijk is dit voor een eigenlijke server niet zo handig omdat heel ver teruggaan in de tijd dan
moeilijk wordt maar voor een testServer is een log van 3,5 GB ook niet handig.
<!-- A size based file rolling appender -->
<appender name="FILE" class="org.jboss.logging.appender.RollingFileAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="File" value="${jboss.server.log.dir}/server.log"/>
<param name="Append" value="false"/>
<param name="MaxFileSize" value="2000KB"/>
<param name="MaxBackupIndex" value="1"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
</layout>
</appender>
Op zich kun je ook instellen dat bepaalde niveaus niet moeten worden weggeschreven naar de
serverlog. Zo heb ik alle loggings van enkele libraries pas laten wegschrijven vanaf het WARN of
INFO niveau. Hierna volgt een voorbeeld van een configuratie waarbij ik de logging van
org.jboss.seam pas heb laten wegschrijven vanaf het WARN niveau en niet het oorspronkelijke
DEBUG niveau. Meer uitleg over de niveaus is terug te vinden bij het hoofdstuk over Log4J
<!-- 22/05/08 - Limit the org.jboss.seam to INFO as its DEBUG is verbose -->
<category name="org.jboss.seam">
<priority value="WARN"/>
</category>
4.3.17.1.2
Deployment
Deployment in een JBoss AS server werkt uiteraard goed. Alleen is bij een re-deploy veelal een
herstart van de server nodig. Bij het testen van een applicatie is dit natuurlijk geen probleem al
kan dit toch veel tijdverlies met zich meebrengen.
Er bestaan wel systemen om hotdeployment mogelijk te maken binnen JBoss maar die waren
volgens mijn collega’s te ingewikkeld om te gebruiken bij een testServer of door niet JBoss AS
experts.
Eindwerk Bram Gadeyne
2007-2008
70
4.3.17.2 Oracle XE
Als databankomgeving gebruikte ik versie 10 van de gratis Oracle XE server. Werken op een Oracle
XE server is bijna gelijk aan het werken op andere servers. Alleen bestaat er in Oracle geen
oplossing voor automatisch verhogende ID’s of boolean Values.
4.3.17.2.1
Sequence
Om een automatische verhoging van een ID na te bootsen moet je in Oracle gebruik maken van
een sequentie.
Een sequentie creëren, kan men doen aan de hand van een IDE zoals “SQL developer van Oracle”
of via een SQL script. Per tabel maak je dan best een sequentie aan om mooi opeenvolgende ID’s
te laten genereren.
CREATE SEQUENCE
"PERSOONLIJKE_OPLEIDING_SEQ"
MINVALUE
999999999999999999999999999 INCREMENT BY 1 START WITH 1;
1
MAXVALUE
Bij het gebruik van Persistence samen met Oracle moet een speciale definitie van de primary key
worden gehanteerd om deze door Persistence automatisch te laten invullen bij een nieuwe insert.
We moeten gebruik maken van de @SequenceGenerator annotatie om een referentie te leggen
naar de gewenste Sequentie voor de entity.
@Id
@GeneratedValue(generator = "ActieSeq")
@SequenceGenerator(name = "ActieSeq", sequenceName = "ACTIE_SEQ", allocationSize = 1)
private Long id;
4.3.17.2.2
Boolean values
In Oracle kent men geen Boolean values. Een andere oplossing bestaat erin om een veld te
voorzien van het type varchar2 met als lengte 1. In dit veld kan dan een value worden opgeslagen
bijvoorbeeld Y die true voorstelt en N die false voorstelt. In een Entity klasse moeten we er dan
voor zorgen dat onze boolean getter en setter omgezet kan worden naar de overeenkomstige
String.
Hieronder het voorbeeld voor de “boolean” certificaat.
Eindwerk Bram Gadeyne
2007-2008
71
private String certificaat;
public boolean isCertificaat() {
if (certificaat == null) {
return false;
} else {
return certificaat.equals("Y");
}
}
public void setCertificaat(boolean certificaatValue) {
if (certificaatValue) {
this.certificaat = "Y";
} else {
this.certificaat = "N";
}
}
Eindwerk Bram Gadeyne
2007-2008
72
5 Programmatie
5.1
Gebruikte hardware
•
5.2
PC’s
o Toestel AWS00369 van Dolmen.
IBM Thinkcentre
1GB RAM geheugen
Pentium 4 2,80 Ghz
o Persoonlijke laptop
IBM Thinkpad T43p
1GB RAM geheugen
Pentium M processor 2,00 Ghz
o Medion USB Stick voor back-up
512 MB
Gebruikte software
5.2.1 Besturingssystemen
5.2.1.1 Windows XP Servicepack 2
Op de pc die ik van Dolmen kreeg werkte ik op het bekende besturingssysteem Windows XP van
Microsoft. Windows XP was in dit geval uitgerust met Servicepack versie 2 waar bijvoorbeeld een
betere beveiliging door een firewall en integratie met anti virus programma’s beloofd worden.
5.2.1.2 Ubuntu Linux 8.04
Op mijn persoonlijke laptop werk ik meestal in het op Linux gebaseerde besturingssysteem van
Canonical genaamd “Ubuntu”. Ubuntu streeft ernaar om zo gebruiksvriendelijk mogelijk linux ter
beschikking te stellen van de wereld. Ubuntu is dan ook in bijna alle talen beschikbaar.
Naast Ubuntu zijn er nog vele andere Linux distributies maar Ubuntu is wel één van de beste en
bekendste. Ze slagen er beetje bij beetje toch in om alle commando gebaseerde acties binnen
linux om te zetten naar GUI’s. Alternatieve programma’s zoals Open Office worden er standaard
op geïnstalleerd en zijn onmiddellijk gebruiksklaar wat de gebruiksvriendelijkheid ook verhoogt.
Ubuntu is zeker een duidelijke verzameling voorbeelden van open-source software die niet moet
onderdoen voor commerciële pakketten.
Het is te downloaden via de site www.ubuntu.com.
5.2.2 Servers
5.2.2.1 Webservers
5.2.2.1.1 JBoss AS 4.2.2 GA
Als Webserver gebruikte ik de JBoss AS 4.2.2 GA server waarover je bij het hoofdstuk over JBoss
Server meer informatie kan vinden. Ik gebruikte de JBoss Server omdat de meeste frameworks
Eindwerk Bram Gadeyne
2007-2008
73
waarvan ik gebruik maakte ook van JBoss waren en er een goede integratie van JBoss was met de
eclipse IDE en de JBoss server.
5.2.2.1.2 Glassfish
Glassfish gebruikte ik in het begin van mijn stage omdat ik er gebruik van had gemaakt op school.
Glassfish is een Java EE server waarbij de configuratie in tegenstelling tot de JBoss server wel via
een webinterface kan gebeuren.
Sun heeft zijn SDK gebaseerd op de Glassfish server.
5.2.2.2 Database
5.2.2.2.1 Mysql 5.0
In het begin van mijn stage maakte ik gebruik van de Mysql server omdat ik deze gebruikte op
school. Ik heb er dan ook mijn demo applicatie mee geschreven.
5.2.2.2.2 Oracle XE 10
Een vereiste van de applicatie die ik uiteindelijk schreef voor Dolmen was dat deze moest werken
op een Oracle database. Daarom heb ik ook leren werken met deze versie van Oracle. Meer uitleg
over de Oracle server is terug te vinden bij het gelijknamige hoofdstuk.
5.2.2.2.3 Derby
Derby is een database systeem die eigenlijk in het intern geheugen gestart wordt en die op Java
gebaseerd is. Ik maakte hier ook kennis mee in het begin van mijn stage. Deze server is vooral
geschikt voor gebruik in een testomgeving of in een ontwikkel omgeving.
5.2.3 IDE
5.2.3.1 Eclipse Europe 3.2.2
Als IDE voor het programmeren in Java maakte ik vooral gebruik van de eclipse IDE. Deze IDE is
uitbreidbaar met plugins waaronder de plugin van JBoss. Hierdoor was de eclipse IDE ook meer
geschikt voor het gebruik met Seam.
5.2.3.1.1 JBoss Tools 2.0.0 GA All plugins
Om te programmeren in Seam kon ik de JBoss tools installeren in eclipse. Dit is een suite van
plugins die voorziet in onder andere ondersteuning voor drag and drop ontwikkeling in Richfaces
en een toolkit voor het genereren van een Seam project.
De JBoss Tools zijn eigenlijk de gratis plugins van JBoss voor eclipse die eclipse omtoveren naar
een IDE die vergelijkbaar is met de “JBoss Developer Studio”. Deze studio is ook op eclipse
gebaseerd maar is betalend waardoor er natuurlijk wel meer support voor bestaat. Meer uitleg
over het gebruik en de installatie van de JBoss Tools en Eclipse is terug te vinden bij het hoofdstuk
over een project starten
Eindwerk Bram Gadeyne
2007-2008
74
5.2.3.2 NetBeans 6.0
Op school maakten we gebruik van de NetBeans IDE. Ik heb er gedurende mijn stage af en toe nog
gebruik van gemaakt om terug te kijken naar projecten die ik in het verleden had gemaakt.
NetBeans werkt echter niet goed samen met de JBoss frameworks en de JBoss server waardoor
programmeren van mijn stageopdracht bij voorkeur niet gebeurde in NetBeans.
5.2.3.3 Oracle SQL Developer
Als IDE om de Oracle database te bevragen maakte ik gebruik van de SQL Developer.
5.2.4 Programmeertalen
5.2.4.1 JDK 1.6 update 5
De basis van het Seam framework is de programmeertaal Java. Ik maakte dan ook gebruik van de
op dat moment laatste nieuwe JDK (Java Developer Kit) versie 1.6 update 5.
5.2.4.2 Seam 2.0.2 GA
De versie van de Seam library die ik gebruikte was versie 2.0.2. Meer uitleg over het Seam project
is terug te vinden in het hoofdstuk over Seam.
5.2.4.3 Library’s
Naast dit alles maakte ik gebruik van een aantal Librarys die in dit stageverslag ook nog uitvoerig
zijn uitgelegd bij de overeenkomstige hoofdstukken. Ik som ze hieronder nog even op.
Richfaces 3.2.0 GA
JUnit
DBUnit
Persistence (Hibernate)
JasperReports
IText
5.2.5 Tekstverwerkers
5.2.5.1 Microsoft Word 2003
Dit stageverslag is geschreven in Microsoft Word 2003 hoewel sommige onderdelen geschreven
werden in Open Office.
5.2.5.2 OpenOffice 2.4
De handleiding die ik maakte over de installatie onder Linux werd geschreven in OpenOffice 2.4
die standaard geïnstalleerd wordt in Ubuntu. OpenOffice is een opensource Office pakket die
volledig compatibel is met de Microsoft Office documenten tot en met Microsoft Office 2003.
Ondersteuning voor de nieuwe formaten van MS Office 2007 zal worden voorzien in OpenOffice 3.
Eindwerk Bram Gadeyne
2007-2008
75
5.2.6 Beeldverwerker
5.2.6.1 The Gimp
Om enkele afbeeldingen op linux te bewerken maakte ik gebruik van The Gimp die te vergelijken is
met een gereduceerde open-source versie van Adobe Photoshop.
5.2.7 Varia
5.2.7.1 IReport
IReport gebruikte ik voor het genereren van JasperReports. Meer informatie hierover is terug te
vinden bij het gelijknamige hoofdstuk.
5.2.7.2 CWD4ALL
Om het database schema opnieuw te genereren van de aangepaste oracle database maakte ik
gebruik van de trial versie van deze tool. Het resultaat is het datamodel geworden.
5.2.7.3 Webbrowsers
5.2.7.3.1 Firefox
Firefox was de browser die ik vooral gebruikte om tijdens het programmeren mijn applicatie uit te
testen. Ik maakte er ook gebruik van de plugin Firebug om de css van mijn applicatie op een
gemakkelijke manier te kunnen aanpassen en om de AJAX requests te kunnen volgen.
Dit is een voorbeeld waarbij firebug gebruik wordt om AJAX requests te volgen. Als we de
tabbladeren veranderen dan worden telkens AJAX requests verzonden.
Eindwerk Bram Gadeyne
2007-2008
76
Dit is een voorbeeld waarbij firebug gebruikt wordt om CSS gemakkelijk te lezen. Hier bekijken we
de knop personen door de optie inspect te gebruiken. De HTML code van de knop personen wordt
weergegeven en de bijhorende css klassen worden rechts onderaan weergegeven. We kunnen
hier dan wijzigingen in de CSS code toevoegen die dan ook onmiddellijk op de pagina wijzigingen
zullen aanbrengen.
5.2.7.3.2 Microsoft Internet Explorer 7
Ter controle van de aangepaste css maakte ik gebruik van MS Internet Explorer 7. CSS opmaak
wordt door de meeste browsers op een andere manier geïnterpreteerd dus controle in een andere
browser was noodzakelijk.
5.3
Een nieuw project starten
Hieronder zal ik wat meer uitleg geven over het starten van een nieuw Seam project. Vooraf
moeten reeds een Oracle database en een JBoss Server geïnstalleerd zijn. Meer informatie over de
installatie van deze 2 zijn terug te vinden in de installatie handleidingen.
Eerst overlopen we de installatie van Eclipse en hoe we die dankzij de JBoss Tools kunnen
omvormen tot een soortgelijke JBoss Developer Studio.
Daarna worden de mogelijkheden van de drag en drop pagina ontwikkeling voor Richfaces
overlopen.
Eindwerk Bram Gadeyne
2007-2008
77
5.3.1 Installatie van Eclipse
Op http://www.eclipse.org/downloads/ kunnen we de laatste nieuwe versie van eclipse
downloaden. We kiezen hiervoor de versie voor EE developers en de correcte versie voor ons
besturingssysteem.
De installatie van eclipse gebeurt door het unzippen van het gedownloade zip bestand in een map
naar wens. Als we deze map dan openen vinden we het eclipse.exe bestand (voor Windows)
waarmee we eclipse kunnen opstarten.
Eindwerk Bram Gadeyne
2007-2008
78
Bij het eerste maal opstarten van eclipse zal eclipse ons vragen waar we onze projecten willen
opslaan. Hij stelt hiervoor een standaardlocatie voor. We kunnen echter een andere locatie
opgeven zoals hier in dit voorbeeld.
5.3.2 Installatie van de JBoss Tools.
Na de installatie van eclipse zullen we de JBoss Tools toevoegen. Deze plugins bevatten alles wat
we nodig hebben voor onze eclipse omgeving om een Seam project te kunnen starten. Het bevat
ook ondersteuning voor het gebruik van Richfaces.
In het menu Help Software Updates kiezen we voor “Find and Install…”. In dit menu kunnen we
zowel updates voor eclipse als voor geïnstalleerde plugins opzoeken en downloaden.
We kiezen daarna voor “Search new features to install”.
Eindwerk Bram Gadeyne
2007-2008
79
We kiezen nu voor “New Remote Site”. We vullen als naam “JBoss Tools” in en we stellen de url in
op “http://download.jboss.org/jbosstools/updates/stable”. Daarna zorgen we dat deze nieuwe
“Remote Site” aangevinkt staat en we klikken op “Finish”.
Nu geeft eclipse ons een overzicht van de gevonden updaten. We vinken alles aan en klikken op
“Next”.
Eindwerk Bram Gadeyne
2007-2008
80
Daarna moeten we nog een licentie overeenkomst accepteren. We vinken “I accept the terms in
the license agreement” aan en klikken op “Next”.
Daarna klikken we nog op “Finish” waarna eclipse alle updates zal installeren.
Eindwerk Bram Gadeyne
2007-2008
81
Eclipse vraagt ons na het downloaden of we zeker zijn dat we deze updates willen installeren. We
kiezen voor “Install All”. Daarna zal ons gevraagd worden om eclipse te herstarten.
5.3.3 Installatie van de Seam Runtime
Later tijdens het opzetten van ons project zullen we ook de “Seam Runtime Environment” nodig
hebben. Deze is te downloaden van http://www.seamframework.org/Download. We kiezen er
voor de laatste production versie. Bij ons was dit “jboss-seam-2.0.2.SP1”. We slaan de zip versie
ergens op onze harde schijf op. Bijvoorbeeld ons bureaublad.
De “Seam Runtime Environment” bevat alle Seam librarys en andere librarys die Seam nodig zou
hebben.
We unzippen deze zip-file naar een locatie op onze harde schijf. Hier koos ik bijvoorbeeld voor de
“c:/” locatie.
Eindwerk Bram Gadeyne
2007-2008
82
We zullen deze runtimelibrarys verder bij de creatie van een Seam project, toevoegen aan eclipse.
5.3.4 Creatie van een nieuw Seam project.
We volgens hier de stappen die moeten ondernomen worden om een nieuw project op te zetten.
5.3.4.1 Een nieuw project
We kiezen voor in het Filemenu van eclipse voor “New Project”.
We vinden nu een aantal soorten projecten terug die we kunnen aanmaken. Wij kiezen hier onder
de map Seam voor “Seam Web Project” en klikken op next.
Eindwerk Bram Gadeyne
2007-2008
83
We moeten nu een nieuwe projectnaam opgeven. We kiezen onderaan voor een “Dynamic Web
Project with Seam 2.0”. De Target Runtime en Server Runtime worden in de volgende
hoofdstukjes verder uitgelegd.
Eindwerk Bram Gadeyne
2007-2008
84
5.3.4.2 De Runtimes
Daarnaast moeten we ook een Target Runtime opgeven. Hiermee bedoeld men de Runtime van
onze JBoss Server. We kiezen hier een Runtime versie die overeenkomt met onze gedownloade
JBoss Server. Bij ons is dit versie 4.2.
We geven onze Runtime nu een naam en tonen de locatie van onze JBoss Server. We kiezen de
gewenste JRE (Java Runtime Environment). Als we voorgaande instellingen correct hebben
ingegeven dan kunnen we kiezen voor 3 soorten configuraties. We kiezen de default versie. We
klikken hierna op Finish.
Eindwerk Bram Gadeyne
2007-2008
85
Nu moeten we ook nog onze Server opgeven die we willen gebruiken om ons project op te
deployen en te testen. Deployen is eigenlijk het kopiëren en installeren van een webapplicatie op
een “Application Server”. Na het deployen kan een webapplicatie via een browser worden
uitgevoerd.
We kiezen hier ook weer voor versie 4.2. Onderaan zien we dat onze hier boven geïnstalleerde
Runtime ook al geselecteerd staat.
Eindwerk Bram Gadeyne
2007-2008
86
Op het volgende scherm kunnen we nog een admin paswoord en een username opgeven. Deze
kunnen we ook leeg laten want we hebben geen paswoorden ingesteld voor onze Server. Daarna
kunnen we nog projecten toevoegen die mogen gedeployed worden maar er zijn nog geen
projecten dus we kiezen hier ook weer voor “finish”
Als alles goed verlopen is dan zouden volgende instellingen te zien moeten zijn op het hoofdblad
voor het aanmaken van een nieuw project.
Eindwerk Bram Gadeyne
2007-2008
87
5.3.4.3 Project Facets
Nu wordt ons gevraagd welke standaard librarys we willen toevoegen en configureren voor ons
project. We vinken hier naast de standaard instellingen ook nog “Java Persistence” aan.
Eindwerk Bram Gadeyne
2007-2008
88
5.3.4.4 De Web Module
Op het volgende scherm kunnen we instellingen instellen die te maken hebben met de Web
Module van onze webapplicatie. De “Context Root” zal hat adres zijn waar we naartoe zullen
kunnen surfen die na het serveradres komt. Zo is bijvoorbeeld “SeamExample” de “Context Root”
in het adres http://localhost/SeamExample.
5.3.4.5 De JPA Module
Het volgende scherm vraagt ons de instellingen voor JPA. We kunnen er een connectie toevoegen
naar onze oracle database. We kiezen voor een “Generic JDBC Connection”. Daarna geven we een
naam op voor onze connectie bijvoorbeeld “oracle local”. Daarna moeten we een driver voor de
Oracle XE connectie opgeven. We kiezen daarvoor versie 10 en moeten nu de driver toevoegen.
Deze is bij een standaard installatie van oracle te vinden op de locatie
“C:\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib”. Je kan kiezen voor driver ojdbc_14 of
ojdbc14_g. Ik kies hier altijd versie ojdbc14_g.
We installeren JPA om op die manier gemakkelijk later entity klassen met eclipse te kunnen laten
genereren. Er zal hiervoor een datasource file aangemaakt worden in ons project die een
beschrijving bevat van hoe het project verbinding kan maken met de database. Op de webserver
zullen we later zelf nog een datasource moeten instellen. Meer informatie hierover is terug te
vinden in de installatie handleiding.
Eindwerk Bram Gadeyne
2007-2008
89
Daarna kunnen we de geïnstalleerde driver kiezen als te gebruiken driver en kunnen we op “ok”
klikken.
Als we nu alle gegevens correct hebben ingevuld dan kunnen we via test connection testen of
onze connectie effectief werkt.
Eindwerk Bram Gadeyne
2007-2008
90
We zorgen dan dat de instellingen op het hoofdscherm als volgt staan ingevuld.
Eindwerk Bram Gadeyne
2007-2008
91
5.3.4.6 De JSF Module
Op het volgende scherm kunnen we configuraties uitvoeren voor JSF. Hier staat normaalgezien
alles ingevuld naar wens. Onderaan zien we dat JSF de extensie .xhtml zal omzetten naar de
extansie .seam. Hierdoor zullen alle pagina’s die opgeroepen worden met de .seam extensie door
de Faces Servlet worden gerenderd alvorens ze door te sturen.
5.3.4.7 De Seam Module
Nu moeten we het Seam gedeelte invullen. Hier zullen we onze Runtime moeten instellen. Zorg
ervoor dat de versie ingesteld staat op versie 2.0!
Eindwerk Bram Gadeyne
2007-2008
92
We zorgen dat de instellingen overeen komen zoals in onderstaande afbeelding. Er wordt hier
nogmaals gevraagd om de connectie met de database op te geven en het database type te
selecteren. Ik heb voor dit voorbeeld gebruik gemaakt van dezelfde database als die van het
project ComMaS. De schema naam hiervan was COMMAS. Dit kan eventueel ook leeg gelaten
worden.
Eindwerk Bram Gadeyne
2007-2008
93
Daarna klikken we op finish en ons project wordt voor ons aangemaakt. Men vraagt ons nog of we
het Seam perspectief willen openen. Hier kiezen we voor ja.
5.3.5 Het project starten
Seam heeft nu voor ons een nieuw project aangemaakt met behulp van de seam-gen tool. We zien
links in eclipse een overzicht van de 4 delen van ons project. Het SeamExample gedeelte bevat alle
inhoud die nodig is voor het webgedeelte van onze applicatie. SeamExample-ear bevat alle
overkoepelende instellingen en librarys. SeamExample-ejb zal alle EJB’s en klassen van onze
applicatie bevatten. Daarnaast hebben we ook nog SeamExample-test waarin we onze testen
zullen kunnen aanmaken.
We kunnen dit project reeds uitvoeren. We selecteren ons SeamExample-ear project en klikken
dan op het groene pijltje die in de voorgaande afbeelding terug te vinden is in de bovenste
werkbalk. Men vraagt ons op welke server we dit project willen uitvoeren. We kiezen daarvoor
onze geïnstalleerde JBoss 4.2 server. Daarna vraagt men ons welke modules we willen deployen.
We zorgen dat alle modules toegevoegd worden. Als we geen datasource hebben geïnstalleerd op
de server kunnen we ook voorlopig de door Seam gegenereerde datasource deployen. Die is terug
te vinden in het ear project onder resources. We kunnen deze deployen door “Deploy To Server”
te kiezen nadat we er met de rechtermuisknop op hebben geklikt.
Na het starten van de server zien we in de console onderaan hoe onze server opgestart wordt.
Nadat de server opgestart is kunnen we binnen de browser die zich in eclipse ondertussen
geopend heeft surfen naar http://localhost:8080/SeamExample.
We krijgen dan onderstaande voorbeeldwebsite te zien. Dit is een demoapplicatie van de Seamgen waarin je al enkele richfaces componenten te zien krijgt. Het gaat hier vooral om een menubar
en panels. We kunnen reeds fictief inloggen op deze demosite. Dit toont de handige werking van
het Identity object. Hierover is meer informatie te vinden bij het hoofdstuk over Seam
authenticatie.
Eindwerk Bram Gadeyne
2007-2008
94
5.3.6 Werken met de JBoss Tools
Na het genereren van ons nieuwe project werd ons gevraagd of we het “Seam perspectief” wilden
openen. Dit is eigenlijk een layout voor eclipse waarbij de JBoss Tools zichtbaar worden.
De JBoss Tools voorzien in enkele functionaliteiten die toegevoegd worden aan eclipse om een
betere ondersteuning voor de JBoss producten te voorzien. Onderaan vinden we bijvoorbeeld het
tabblad “JBoss Server View” waarin we allerlei configuraties aan de server kunnen veranderen.
5.3.7 Richfaces drag and drop demo
Ik zal hierna nog een klein voorbeeld geven voor de drag and drop mogelijkheden voor richfaces.
Stel dat we op onze home pagina een calender componenten willen toevoegen dan kunnen we
dat in een aantal klikken doen. In de WebContent map vinden we het bestand home.xhtml terug.
Dit bestand wordt geopend aan de hand van een template waarover in dit stage verslag onder
“templating in JSF” meer terug te vinden is. We zullen op de home pagina een calendar
toevoegen.
We zien hieronder het geopende home.xhtml bestand. We zien de HTML, JSF en Richfaces code en
onderaan een WYSIWYG editor die ons onmiddellijk een overzicht van de webpagina geeft.
Eindwerk Bram Gadeyne
2007-2008
95
We slepen nu de calendar die terug te vinden is in het menu recht onder JBoss Richfaces naar een
gewenste locatie in onze code. Tijdens het slepen toont men een scherm waarin we alle attributen
al kunnen invullen. We doen dit echter niet en laten dus alle standaardwaarden staan door
gewoon op “Finish” te klikken. In dit scherm konden we bijvoorbeeld al de value van het calendar
object koppelen aan een waarde van één van onze backing beans.
Eindwerk Bram Gadeyne
2007-2008
96
Als we dan nu kijken naar de WYSIWYG editor zien we dat er een calender object werd
toegevoegd en in de code merken we de “<rich:calendar></rich:calendar>” tags op.
Als we nu deze pagina opslaan en we onze webpagina refreshen in de browser binnen eclipse zien
we onmiddellijk onze wijzigingen in de effectieve webpagina.
Hotdeployment op een JBoss Server werkt op niveau van webpagina’s alhoewel we toch ook af en
toe een server restart zullen moeten doen. Als we EJB’s of andere zaken zouden willen wijzigen
moeten we wel een volledige server restart doen.
Eindwerk Bram Gadeyne
2007-2008
97
5.4
Algoritmes
Om de TreeNode voor de RichTree componenten op te vullen maakte in gebruik van een
recursieve methode. Hoogste nodes in de tree’s was steeds het type van de onderliggende
competenties. Daaronder zaten dan steeds competenties die op hun beurt weer competenties
konden hebben.
Om nodes aan te maken moest een node steeds een uniek nummer bevatten op zijn niveau. Deze
werd bijgehouden in de counter en werd verhoogd na elke toevoeging van een nieuwe node.
treeNode is de rootNode van de tree. Onder treeNode werden steeds TreeNodeImpl objecten
toegevoegd met als data een type.
Na het toevoegen van een type werden dan alle competenties die geen parentcompetentie
hadden toegevoegd onder dit type. Onder deze competententies werden dan recursief
competenties toegevoegd die als parentcompetentie de toegevoegde competentie hadden.
/** The tree node. */
@SuppressWarnings("unchecked")
private TreeNode treeNode;
/** The counter. */
private Integer counter;
Eindwerk Bram Gadeyne
2007-2008
98
@SuppressWarnings("unchecked")
public void loadTree() {
try {
counter = 1;
treeNode = new TreeNodeImpl();
treeNode.setData("Types");
List lijst = typeService.getAllOrderedByTypenaam();
for (int i = 0; i < lijst.size(); i++) {
Type type = (Type) lijst.get(i);
TreeNode node = new TreeNodeImpl();
node.setData(type);
treeNode.addChild(counter, node);
counter = counter + 1;
loadCompetenties(type, node, counter);
counter = counter + 1;
}
try {
log.info("loadTree uitgevoerd.");
} catch (NullPointerException e) {
}
} catch (RuntimeException e) {
log.error("kon loadTree niet uitvoeren" + e.getMessage());
}
}
@SuppressWarnings("unchecked")
public void loadCompetenties(Type type, TreeNode node, Integer counter) {
List<Competentie> lijst = competentieService.getByType(type);
Iterator<Competentie> it = lijst.iterator();
while (it.hasNext()) {
Competentie comp = it.next();
if (comp.getParentid() == null) {
TreeNode subNode = new TreeNodeImpl();
subNode.setData(comp);
node.addChild(counter, subNode);
counter = counter + 1;
loadChildCompetenties(comp, subNode, counter);
counter = counter + 1;
}
}
}
@SuppressWarnings("unchecked")
public void loadChildCompetenties(Competentie competentie, TreeNode node,
Integer counter) {
List<Competentie> lijst = competentieService
.getByParentCompetentie(competentie);
Iterator<Competentie> it = lijst.iterator();
while (it.hasNext()) {
Competentie comp = it.next();
TreeNode subNode = new TreeNodeImpl();
subNode.setData(comp);
node.addChild(counter, subNode);
counter = counter + 1;
loadChildCompetenties(comp, subNode, counter);
counter = counter + 1;
}
}
Eindwerk Bram Gadeyne
2007-2008
99
6 Bespreking van het programma
6.1
Gebruikershandleiding
In deze gebruikershandleiding geven we wat meer uitleg bij de schermen die beschikbaar zijn in de
applicatie. Eerst komen een aantal algemene zaken die voor elke gebruiker hetzelfde zijn. Daarna
volgen vooral de uitleg van de schermen zoals een personeelsverantwoordelijke of administrator
ze zullen zien. Voor de andere gebruikers zal er steeds uitgelegd worden wat ze niet kunnen
uitvoeren of hoe sommige zaken voor hen werken.
6.1.1 Gebruikerstypes
In deze applicatie maken we gebruik van 5 gebruikerstypes. Het is zo dat elke gebruiker die zich
hoger in de hiërarchie bevindt ook steeds alles moet kunnen doen wat een gebruiker onder hem
kan uitvoeren.
•
•
•
•
•
Administrator
o Dit is de hoofdgebruiker die alle rechten heeft over de volledige applicatie. Hij is
ook de enige die andere gebruikers kan benoemen tot administrator.
Personeelsverantwoordelijke
o Heeft alle rechten over de gehele applicatie. De hoofdtaak van de
personeelsverantwoordelijk is echter het opstellen van de functiebeschrijvingen en
het beheren van de gebruikers.
Personeelssecretariaat
o Het personeelssecretariaat beheert vooral opleidingen binnen Dolmen en kan
gebruikers toevoegen aan sessies.
Chef
o Kan medewerkers toevoegen en ze aanduiden als zijn medewerkers. De Chef kan
medewerkers beheren die aangeduid zijn als zijn medewerkers. Daarnaast kan een
chef ook functiebeschrijvingen en opleidingen beheren.
Medewerker
o De medewerker kan zijn eigen voortgang op vlak van competenties volgen en kan
PO verslagen nalezen en er opmerkingen toevoegen. De medewerker kan ook zijn
eigen acties volledig beheren.
6.1.2 Algemeen
We bespreken hier de onderdelen van de applicatie die voor alle gebruikers dezelfde werking
hebben. Het gaat hier meestal niet over effectieve schermen maar over handelingen die op
dezelfde manier kunnen gebeuren.
6.1.2.1 inloggen
Elke gebruiker kan zijn/haar gegevens invullen bij het surfen naar de webpagina. Standaard
hebben alle gebruikers het paswoord “paswoord” die wel door een beheerder kan worden
aangepast.
Eindwerk Bram Gadeyne
2007-2008
100
We kunnen een gebruikersnaam onthouden om de volgende keer gemakkelijk onder dezelfde
naam opnieuw in te kunnen loggen. Dit doen we door het vinkje naast onthouden aan te vinken.
Het kan ook zijn dat we na surfen naar een bepaalde URL in onze applicatie ook dit inlogscherm te
zien krijgen. Dit komt omdat we geen enkele pagina kunnen bezoeken waar we geen rechten toe
hebben. Zelfs niet als we de juiste URL ervoor kennen.
6.1.2.2 Uitloggen
Rechts bovenaan in het menu vinden we een knop om onszelf uit het programma uit te loggen.
We krijgen hierna opnieuw de mogelijkheid om onszelf in te loggen in het systeem.
6.1.2.3 Paswoorden wijzigen
We kunnen een paswoord wijzigen door na het inloggen op de knop “paswoord wijzigen” in het
menu te klikken. We moeten dan ons oud paswoord ter verificatie en het nieuwe gewenste
paswoord invullen.
Eindwerk Bram Gadeyne
2007-2008
101
6.1.2.4 Taal wijzigen
Het programma is vertaald in de 3 talen Nederlands, Frans, Engels. Al naargelang waar de
webapplicatie geopend wordt zal de respectievelijke taal worden gebruikt. Als we een andere taal
wensen te gebruiken dan kunnen we in het menu op de gewenste taal klikken.
6.1.2.5 Werken met lijsten
Het programma bestaat bijna volledig uit lijsten die bepaalde gegevens weergeven. Aan zo’n
lijsten kunnen we meestal gegevens toevoegen, verwijderen of er gegevens van aanpassen. Op
sommige plaatsen in ons programma is het mogelijk om van sommige items in een lijst de
detailweergave te openen.
6.1.2.5.1 Toevoegen
Een nieuw item toevoegen kunnen we doen door links onder een lijst op de knop “nieuw” te
klikken.
We zien hier het voorbeeld van een lijst waarbij we personen kunnen toevoegen. Als we alle
gegevens correct hebben ingevuld dan kunnen we nadien op de knop “toevoegen” klikken. Daarna
zal het gewenste item toegevoegd worden aan de lijst.
Als we foutieve gegevens invullen zal het programma ons daarover waarschuwen en zullen we die
eerst moeten aanpassen voordat we de gegevens zullen kunnen opslaan.
6.1.2.5.2 Aanpassen
Een voorbeeld voor het aanpassen en verwijderen van item uit een lijst.
Eindwerk Bram Gadeyne
2007-2008
102
We zien in de lijst een kolom met als naam opties. In deze kolom zullen we steeds acties kunnen
terugvinden die we kunnen uitvoeren voor het item van de bijhorende rij. Hier hebben we
bijvoorbeeld de opties “aanpassen” gekozen voor de gebruiker met als gebruikersnaam
“gadeynebram”.
Onderaan de lijst zal dan steeds een paneel verschijnen waar we de waarden van de geselecteerde
rij kunnen aanpassen. De wijzigingen doorvoeren kunnen we doen door op de knop “opslaan” te
klikken.
Onderaan het paneel kunnen nog extra opties beschikbaar worden voor de geselecteerde rij. In dit
geval kunnen we voor de geselecteerde gebruiker het paswoord herzetten door op de knop
“paswoord herzetten” te klikken.
Als we foutieve gegevens invullen zal het programma ons daarover waarschuwen en zullen we die
eerst moeten aanpassen voordat we de gegevens zullen kunnen opslaan.
6.1.2.5.3 Verwijderen
Als we in een lijst de mogelijkheid hebben om een rij te verwijderen dan zal, na het klikken op
deze optie, ons gevraagd worden of we deze rij daadwerkelijk willen verwijderen.
Eindwerk Bram Gadeyne
2007-2008
103
Door op de knop “Ok” te klikken wordt de bijhorende rij verwijderd.
6.1.2.5.4 Detailweergave
Van sommige onderdelen zien we graag een detail weergave. Bij ons voorbeeld van personen is de
detailweergave heel uitgebreid. Om een detailweergave op te roepen klikken we op een
kolomwaarde die vet gedrukt staat. Bij personen is dit bijvoorbeeld de kolom “persnr”. Door op
deze vetgedrukte waarde te klikken wordt voor ons de bijhorende detailweergave geopend.
Het is mogelijk dat we in een detailweergave ook weer lijsten terugvinden waar we op hun beurt
een detailweergave van kunnen opvragen. Terugkeren naar vorige schermen kunnen we dan doen
door op de knop “terug” te klikken die onderaan links op deze pagina’s te vinden is.
6.1.2.5.5 Door gegevens scrollen
Een lijst heeft standaard een lengte van 10 regels. De beheerder van de applicatie kan dit
eventueel wijzigen. Om te kunnen navigeren in een lijst kunnen we onder deze lijst klikken op de
gewenste pagina of op de pijltjes die ons door de lijst laten navigeren.
6.1.2.5.6 Zoeken in gegevens
In sommige lijsten is er een mogelijkheid ingebouwd om te kunnen zoeken. Hiervoor is boven een
lijst een paneel “zoeken” voorzien waar we dan op enkele kolommen kunnen zoeken. Als we
gegevens in een zoekveld intypen zal de lijst automatisch verkleind worden met gegeven die
voldoen aan de zoekterm.
De zoekterm verloopt volgens het patroon %zoekterm% waarbij % wil zeggen 0 of meer tekens. De
zoekterm is wel hoofdletterafhankelijk.
Eindwerk Bram Gadeyne
2007-2008
104
6.1.2.6 Werken met Treeviews
Treeviews zijn heel handige tools om een boomstructuur weer te geven. In deze applicaties
worden ze vooral gebruikt om Competenties te beheren.
6.1.2.6.1 De Opbouw
We zien in onderstaande figuur hoe een tree is opgebouwd. We zien 2 “types” die een groepering
maken van competenties. In dit geval zijn dit “SE” en “WEB”. Types worden voorgesteld door een
mapje. Als we op een pijltje klikken dan worden alle onderliggende items geladen. Onder een Type
vinden we tandwieltjes en sleutels. Een tandwiel is een competentiegroep. Een sleutel is een
deelcompetentie van zo’n competentiegroep. Als we een node selecteren dan worden onder de
tree soms opties zichtbaar die het toelaten om zo’n node te bewerken. Opslaan van de wijzigingen
kan gebeuren door 1 maal te klikken op een node.
6.1.2.6.2 Dubbele Trees
Op sommige pagina’s vinden we ook Trees terug die een splitsing maken tussen items die door de
geselecteerde detailview in gebruik zijn of net niet. Door op een type te klikken worden alle
competentiegroepen voor zit type verwijderd of toegevoegd aan de detailview. Hetzelfde geldt
Eindwerk Bram Gadeyne
2007-2008
105
voor de selectie van een competentiegroep. Voor sommige competenties kunnen we dan soms
nog extra opties invullen maar dit is afhankelijk van de locatie in het programma.
6.1.3 Het admin paneel
De eerste grote groep van gebruikersschermen zitten vervat onder de schermen van het
adminpaneel. Ze hebben de functie om globale configuraties te doen dan de configuratie op het
niveau van één enkele gebruiker.
Personen uit de medewerker gebruikersgroep hebben geen toegang tot alle schermen in het
adminpaneel. Personen uit de personeelssecretariaatsgroep hebben enkel rechten op het
onderdeel “opleidingen”.
6.1.3.1 Gebruikers beheren
Het eerste tabblad geeft ons een overzicht van personen. Gebruikers kunnen er toegevoegd,
verwijderd of aangepast worden.
6.1.3.1.1 Allen
Bij het toevoegen of aanpassen van gegevens gebeurt er een foutcontrole. Als er iets mis ingevuld
wordt dan zal ons dat gemeld worden met een bericht die in het rood terug te vinden is rechts van
het foutieve veld.
Bij het niet invullen van het emailadres zal het programma automatisch een e-mailadres maken in
de vorm van [email protected]. We kunnen een ander adres opgeven door hier
zelf iets in te vullen.
Een gebruiker kan enkel andere gebruikers promoveren tot een gebruikersgroep die lager is of
gelijk aan de groep waarin ze zich zelf bevinden.
In de lijst met medewerkers kan er gezocht worden op de naam en de voornaam van een
medewerker.
Eindwerk Bram Gadeyne
2007-2008
106
6.1.3.1.2 De chef
Een chef heeft echter een ander beeld. Deze persoon is enkel geïnteresseerd in zijn eigen
medewerkers en de medewerkers die momenteel geen chef hebben.
De personen die onderaan te zien zijn, zijn de personen die momenteel geen chef hebben. Hier
gaat het dus enkel om “vrije medewerkers”. Door op de knop toevoegen te klikken kan een chef
een medewerker toevoegen als zijn medewerker.
Een Chef kan personen aanpassen waarvan hij chef is. Daarnaast kan een chef personen ook weer
verwijderen uit de lijst van zijn medewerkers. Een chef kan dus geen personen effectief en blijvend
uit het systeem verwijderen.
Eindwerk Bram Gadeyne
2007-2008
107
6.1.3.2 Opleidingen beheren
In dit Tabblad kunnen we de opleidingen beheren die binnen Dolmen worden ingericht. Alle
gebruikers die toegang hebben tot het adminpaneel hebben de toegang tot dit opleidingspaneel.
We zien in deze lijst ook welke sessies er al zijn ingericht voor een bepaalde opleiding. Door op de
titel van een opleiding te klikken kunnen we diens gegevens en sessies aanpassen. We zien ook dat
we voor een opleiding bijhorende competenties kunnen toevoegen die verworven kunnen worden
door een opleiding te volgen.
Eindwerk Bram Gadeyne
2007-2008
108
Voor een sessie kunnen we een maximum aantal deelnemers instellen. In de detailweergave van
een sessie kunnen we gebruikers toevoegen aan zo’n sessie die dan deze sessie zullen bijwonen.
Als het aantal maximum toe te voegen personen overschreden wordt, dan zal er een bericht
getoond worden. In dit voorbeeld hieronder zien we links de tekst “Er zijn geen plaatsen meer vrij
in deze sessie” verschijnen.
Voor elke persoon in een sessie kunnen we ook nog aanvinken of deze opleiding een certificaat
oplevert en/of op de CV zal worden weergegeven.
Eindwerk Bram Gadeyne
2007-2008
109
6.1.3.3 Functiebeschrijvingen beheren
Functiebeschrijvingen kunnen beheerd worden door alle groepen die toegang hebben tot het
adminpaneel behalve door de leden van de groep personeelssecretariaat.
In dit lijstscherm kunnen we functiebeschrijvingen toevoegen. Door op omschrijving te klikken
kunnen we de detailweergave van een functiebeschrijving bekijken en aanpassen.
Onderaan de lijst vinden we ook een knop “rapport” terug waarmee we een rapport kunnen
ophalen in PDF-formaat die alle functiebeschrijvingen bevat.
In de detailweergave vinden we enkele detailgegevens in verband met een functiebeschrijving. Die
kunnen we aanpassen en opslaan door op de knop aanpassen te klikken onderaan de pagina.
We kunnen voor een functiebeschrijving taken toevoegen die zullen moeten worden uitgevoerd
door de functionaris.
Competenties die benodigd zijn kunnen worden toegekend. We kunnen de details van een
competentie in gebruik een minimum score en een prioriteit invullen voor een competentiegroep
of voor een competentie.
Eindwerk Bram Gadeyne
2007-2008
110
Als laatste kunnen we onderaan de pagina ook nog eens de gebruikers zien die momenteel deze
functie hebben en we kunnen andere gebruikers eraan toevoegen.
Onderaan de pagina is er een mogelijkheid voorzien om een samenvattend rapport van de
functiebeschrijving in pdf-formaat op te halen.
Eindwerk Bram Gadeyne
2007-2008
111
6.1.3.4 Competenties beheren
Competenties kunnen beheerd worden door alle groepen die toegang hebben tot het
adminpaneel behalve door de groep personeelssecretariaat.
Competenties beheren gebeurt via een tree. Navigeren hierin kan door op de pijltjes te klikken.
Om een type of een competentie te bewerken kruisen we diens vinkje aan. Het item blijft
geselecteerd totdat we een ander item selecteren. Voor het geselecteerde item komt onmiddellijk
de optie om die aan te passen. We kunnen ook kiezen om een nieuw type toe te voegen, een
nieuwe competentie toe te voegen of het geselecteerde item en alle onderliggende items te
verwijderen.
Zolang we geen nieuw item selecteren zullen we competenties kunnen toevoegen onder het
laatste geselecteerde type of competentie.
Pas op! Bij het verwijderen van een competentie of type worden ook alle overeenkomstige items
elders in het programma verwijderd. Dit zijn dan bijvoorbeeld persoonlijke competenties van
medewerkers, opleiding competenties of verwachte competenties uit functiebeschrijving. We
krijgen wel een waarschuwing als we een item willen verwijderen.
Eindwerk Bram Gadeyne
2007-2008
112
6.1.3.5 Mail
Een personeelsverantwoordelijke of administrator kan in ons programma de opdracht geven om
mails te verzenden. Deze mails houden herinneringen in voor acties waarvan de deadline binnen
de komende 3 dagen afloopt. Deze aantal dagen parameter kan ook door een beheerder van het
programma worden aangepast. De herinnering voor een actie wordt slechts 1 maal verzonden.
6.1.4 Het Gebruiker Menu
Het gebruikers menu opent de detailweergave van de huidig ingelogde gebruiker. Deze
detailweergave is eveneens de detailweergave die we verkrijgen wanneer we de detailweergave
van een persoon uit de lijst van personen in het adminpaneel opvragen.
De voorbeelden die we hier zullen volgen zijn er waarbij een personeelsverantwoordelijke, een
administrator of een chef wijzigingen aanbrengt bij de persoon dummy1. Dit omdat deze personen
meestal alle rechten hebben om wijzigingen aan te brengen.
Een medewerker kan meestal enkel zaken raadplegen of heeft geen toegang tot bepaalde
tabbladen. Ook kan een medewerker sommige rapporten afdrukken.
De personen uit de groep personeelssecretariaat kunnen enkel het tabblad details raadplegen. De
overige tabbladen zullen door hen nooit gebruikt moeten worden.
6.1.4.1 Details
Op het details tabblad krijgen we een overzicht van de gegevens van de geselecteerde of
ingelogde gebruiker. We zien ook de functies die een gebruiker al heeft gehad, momenteel heeft
of in de toekomst graag zou verkrijgen.
Eindwerk Bram Gadeyne
2007-2008
113
6.1.4.1.1 De personeelsverantwoordelijke, administrator en chef
Deze personen kunnen functies toevoegen of verwijderen van een persoon. Ze kunnen tevens
instellen of een functie een vorige, huidige of toekomstige functie is.
6.1.4.1.2 De medewerker en leden van de personeelssecretariaat groep
Deze personen zien enkel de detailweergave van hun gegevens en een lijst van hun functies. Zij
kunnen deze lijst echter niet aanpassen. Ze kunnen wel de omschrijving van de functie raadplegen.
6.1.4.2 PO
PO verslagen worden ingevuld door de chefs van hun medewerkers. Ze kunnen ook worden
aangepast door de administrators of personeelsverantwoordelijken. Een medewerker zelf kan
deze wel raadplegen maar enkel het veld “opmerkingen” aanpassen.
Als een chef een persoonlijk overleg heeft gehouden met één van zijn medewerkers moet hij
daarvoor een verslag bijhouden. In dit menu vinden we een overzicht van de verslagen en kunnen
we verslagen toevoegen.
Eindwerk Bram Gadeyne
2007-2008
114
Als we nu de detailweergave van een item een po verslag openen kunnen we deze invullen. De
detailweergave kunnen we openen door op de titel van het verslag te klikken. We kunnen er de
besproken onderwerpen invullen. De zaken die als resultaat van de vergadering in orde moeten
worden gebracht, worden ingevuld bij “te doen”. Er is een veld opmerking voorzien waarin een
medewerker nog opmerkingen over de vergadering kan toevoegen.
Opslaan van al deze gegevens kan gebeuren door op de knop opslaan te klikken. We kunnen de
wijzigingen in het veld “titel” en “opmerkingen” ook negeren door op de knop “annuleren” te
klikken.
6.1.4.3 Klantentevredenheid
De klantentevredenheidsonderzoeken zijn enkel toegankelijk voor de personen uit de groepen
chef, administrator of personeelsverantwoordelijke
Als een project afgelopen is, kunnen klanten soms een klantentevredenheid opsturen. Een chef
kan deze dan toevoegen als referentie voor de medewerker. De functie waarin de medewerker
het project uitwerkte moet worden geselecteerd via het lijstje met de functies die de medewerker
uitgevoerd heeft. De datum kunnen we invullen aan de hand van het kalendertje dat verschijnt.
Na het toevoegen van de klantentevredenheid kunnen we een bestand uploaden door op het
groene icoontje te klikken.
Eindwerk Bram Gadeyne
2007-2008
115
Daarna wordt ons dan gevraagd om een bestandslocatie op te geven. Door op bladeren te klikken
kunnen we deze locatie opgeven. Als we daarna op uploaden klikken dan wordt het bestand naar
de server weggeschreven.
Nadat we het bestand hebben geüpload kunnen we dit ook terug downloaden door op het witte
icoontje naast bestand te klikken.
We kunnen het verwijderen door op het rode icoontje te klikken naast bestand.
6.1.4.4 Acties
Het menu Acties is beschikbaar voor alle gebruikers behalve de gebruikers uit de groep
personeelssecretariaat.
Acties zijn meestal opdrachten die moeten vervuld worden tegen een bepaalde deadline. In dit
menu kunnen beheerd worden. De medewerker heeft hier net als alle andere gebruikers alle
rechten op. We kunnen van alle acties een lijst afdrukken door op de knop rapport te klikken.
Eindwerk Bram Gadeyne
2007-2008
116
Als we op de titel van een actie klikken wordt de detailweergave geopend waar we nog meer
informatie over de actie kunnen invullen.
Opslaan van deze wijzigingen kunnen we opslaan door op de knop “opslaan” te klikken.
6.1.4.5 Opleiding
Tot dit menu hebben alle gebruikers toegang behalve diegene die tot de groep
personeelssecretariaat behoren. Een medewerker kan op deze pagina enkel gegevens raadplegen
en bestanden downloaden. Hij kan ze dus niet wijzigen of nieuwe toevoegen.
We krijgen een overzicht van persoonlijke opleidingen die een medewerker gevolgd heeft. Ook
hiervoor kunnen we zoals bij de klantentevredenheden bestanden uploaden als bewijs van de
gevolgde opleiding. Deze bestanden worden dan certificaten genoemd.
Onderaan zien we een overzicht van de opleidingen die een medewerker gevolgd heeft of zal
volgen binnen Dolmen. Deze opleidingen kunnen hier echter niet worden toegevoegd maar zijn
het resultaat van het toevoegen van een medewerker aan een sessie van een opleiding. Zie het
onderdeel opleidingen in het adminpaneel voor meer informatie.
We kunnen ook een overzichtsrapport laten afdrukken van dit alles door op de knop “rapport” te
klikken.
Eindwerk Bram Gadeyne
2007-2008
117
6.1.4.6 Competenties
De chefs, administrators en personeelsverantwoordelijken kunnen competenties van een
medewerker aanpassen en toevoegen of verwijderen. Een medewerker kan enkel een overzicht
van zijn verkregen competenties raadplegen en er de details van weergeven. Hij kan niks
aanpassen.
Een medewerker beschikt over bepaalde competenties. Deze kunnen we via dit tabblad
toevoegen of verwijderen. We kunnen er ook een bepaalde score aan geven of een bepaalde
gewenste score. Een voorbeeld hiervan is het aanpassen van de gewenste score na een PO of een
wens om een andere functie binnen het bedrijf te kunnen verkrijgen.
Ook van de competenties kunnen we een overzicht laten afdrukken in de vorm van een rapport.
Eindwerk Bram Gadeyne
2007-2008
118
Eindwerk Bram Gadeyne
2007-2008
119
6.2
Installatiehandleiding Windows
Tijdens mijn stage werd me gevraagd om een handleiding te maken voor de installatie van mijn
applicatie. Het resultaat ervan kunt u terugvinden in bijlage 1.
6.3
Installatiehandleiding Linux
Naast de installatie handleiding voor Windows maakte ik er ook één voor Linux. Dit deed ik niet
alleen om mijn passie voor Linux tijdens mijn stage te kunnen gebruiken, maar ook om de
platformonafhankelijkheid van mijn applicatie uit te kunnen testen. Het resultaat is terug te
vinden in bijlage 2.
Eindwerk Bram Gadeyne
2007-2008
120
7 Conclusies
Seam’s like future, de titel die ik koos toen ik begon met schrijven aan dit eindwerk. Voor mij was
het een hele ervaring om te programmeren in een gloed nieuw framework tevens een JEE
omgeving. De snelheid waarmee het project in het begin vorderde en er dus al bruikbare
functionaliteit voor de gebruikers beschikbaar was, vond ik fenomenaal. Het ging in dat stadium
vooral om lijstschermen met CRUD (create, read, update, delete) mogelijkheden.
Seam voorziet zelfs een mogelijkheid om CRUD schermen te genereren van een bestaande
database. Dit deed ik echter niet omdat ik niet echt geloof in het gebruik van automatisch
gegenereerde code. Als programmeur wordt alles voor jou gemakkelijk gemaakt door wizards die
je voorzien van allerlei functionaliteiten. Ik denk dat je dan als programmeur op een gegeven
moment wel gaat vervreemden van je eigen programmeertaal. Ik koos er dan ook bewust voor om
zelf alle webpagina’s te schrijven. Één van mijn wensen van een stage was immers dat ik veel
zaken zou bijleren.
Naar mate ik echter vorderde in mijn stageopdracht, en er dus ook moeilijkere functionaliteiten
moesten worden toegevoegd, hoe moeilijker en trager het ontwikkelen van de applicatie verliep.
De weinige documentatie waarover ik beschikte kon me bij sommige problemen niet onmiddellijk
helpen. Ik heb dan ook veel beroep moeten doen op forums of blogs waar ik soms dagenlang op
heb zitten zoeken naar de oplossing voor een probleem. Documentatie van de Seam
componenten is ook niet echt uitgebreid. Meestal moest ik mij tevreden stellen met een miniem
voorbeeldje die in sommige gevallen werkte en in andere dan weer niet. Veelal waren problemen
in het algemeen bekend maar waren oplossingen ver te zoeken.
Ondanks het soms lang zoeken naar een oplossing voor een probleem, heb ik toch voor bijna elk
probleem een oplossing gevonden. Alleen het probleem waarbij ik automatisch mails moest
verzenden heb ik nooit kunnen oplossen. Soms heb ik gebruik moeten maken van libraries die
helemaal niet van Seam zijn. Gelukkig laat Seam het gebruik van andere libraries toe waardoor het
opvangen van problemen op die manier toch goed waren.
Ik ben overtuigd dat Seam met zijn visie over zijn framework een stap in de goede richting heeft
gezet. Met de Java standaarden wordt in sommige frameworks geen rekening gehouden waardoor
compatibiliteit soms een probleem vormt. Seam wil deze standaarden net wel gebruiken en
voorziet een goede integratie tussen de standaarden. De componenten waarin Seam voorziet en
die mogelijkheden als mailen, authenticatie en logging beschikbaar maken, zijn volgens mij ook
een goede stap in de juiste richting. Algemeen gezien zijn deze componenten gebaseerd op
frameworks die veel gebruikt worden maar is de integratie met de Java standaarden verbeterd.
Spring is hier ook een voorbeeld die voorziet in deze mogelijkheden alleen werkt het soms naast
de standaarden.
Natuurlijk kent Seam wel het probleem dat onder de kap van de mooie visie en de
gebruiksvriendelijkheid er ook nog wat moet gesleuteld moet worden aan de effectieve uitwerking
en stabiliteit. Sommige componenten binnen Seam kunnen niet goed met elkaar samenwerken en
hebben af en toe te kampen met bugs uit het frameworks. Ik geloof er echter in dat wanneer
Seam meer zal gebruikt worden deze bugs zullen verdwijnen en het framework daardoor veel aan
stabiliteit zal winnen.
Eindwerk Bram Gadeyne
2007-2008
121
Seam’s like future vond ik dus een goede naam voor dit eindwerk en is tevens toepasbaar op de
conclusie. Het kan gelezen worden in 2 contexten. De ene met de positieve klank die zegt dat
Seam toekomst in zich heeft. De creatie van de nieuwe standaard webbeans die op Seam is
gebaseerd is daar een mooi voorbeeld van. De andere iets negatievere omdat Seam momenteel
misschien nog niet volledig klaar is om al in echt grote applicaties te worden gebruikt. Wanneer
het framework na enkele jaren van gebruik aan stabiliteit heeft gewonnen dan zal het pas echt
klaar zijn om door de weide wereld gebruikt te worden.
Eindwerk Bram Gadeyne
2007-2008
122
8 Kritische Reflectie
Het begin van mijn stage bestond uit het analyseren van de doelen van de vele frameworks die ik
ging moeten gebruiken, en hoe ik ermee kon werken. Ik heb telkens geprobeerd om zaken op te
zoeken naar gelang ik die nodig had bij de uitwerking van de applicatie of na feedback van mijn
mentor. Het probleem hierbij was dat ik soms een groot aantal webpagina’s of klassen heb
moeten aanpassen. Dit om toch een andere maar meestal betere oplossing of framework te
gebruiken voor een bepaald probleem. Ik geef hieronder 3 voorbeelden
Ten eerste een voorbeeld uit het begin van mijn stage. Ik voerde soms controles uit op mijn code
om bepaalde statussen van variabelen tijdens het uitvoeren te weten te komen. Dit deed ik dan
via de System.out.println functie. Na verloop van tijd bleek het echter beter om een logger te
gebruiken om de gelogde data gemakkelijk te kunnen filteren en wegschrijven naar gewenste
locaties. Hiervoor kon ik dan de log.info() functie van de Seam logger gebruiken.
Een tweede probleem was een voorbeeld waarbij ik de lijsten die gemaakt werden volledig
dynamisch wilde laten opvullen met een vast aantal rijen. Via pijltjes moest dan door de lijst
kunnen gescrolled worden. Ik had hiervoor een stuk code gebruikt uit een vorig project van Java
die perfect werkte. Helaas bleek een tijdje later dat er in Richfaces een component bestond
waarmee ik met 1 lijntje op een veel betere manier en via AJAX mijn lijst dynamisch kon laten
werken. Deze control is de rich:dataScroller geworden. Hieronder heb ik er een afbeelding van
geplaatst.
Een laatste voorbeeld was het vertalen van mijn applicatie. Ik had in het begin van mijn stage wel
gezien dat de applicatie vertaalbaar moest zijn maar had hier geen rekening mee gehouden in de
eerste weken van de implementatie. Hierdoor heb ik op het einde ook weer de meeste pagina’s
moeten aanpassen om ze vertaalbaar te maken. Dit kon ik dan doen dankzij de
messages.properties files en de Seam EL expressies messages[‘key’].
Natuurlijk zijn dit 3 zaken die ik nu dankzij de opgedane ervaring in de toekomst wel rekening mee
zal houden en waar ik bij gevolg geen uren of dagen werk mee zal verliezen. Ik denk wel dat ik in
het vervolg misschien beter alle vereisten van de applicatie vooraf goed doorneem en voor alle
vereisten eerst een oplossing zoek alvorens ze effectief te gaan implementeren. Zo had ik
misschien beter een klein stuk van de applicatie volledig op punt kunnen stellen om dan het
overige deel van de applicatie op een goede manier aan te vullen. Ik had dan op dit kleine stuk
misschien ook sneller feedback kunnen krijgen waardoor ik in de overgebleven tijd de applicatie
zelf nog had kunnen verbeteren.
In het begin van een project met technische analyse denk ik dat het dus beter is om deze analyse
zo goed mogelijk uit te voeren aan de hand van de noden. De prioriteit mag dan dus niet bij de te
maken applicatie liggen.
Eindwerk Bram Gadeyne
2007-2008
123
9 Voor akkoord verklaard
Frederik Dierickx
Stagementor
Hans De Neve
Stagementor
Sylvia Di Bono
Stagegever
Corneel Theben-Terville
Stagebegeleider
Eindwerk Bram Gadeyne
2007-2008
124
10 Literatuurlijst
10.1 Boeken
• Beginning JBoss Seam
o Autheur: Joseph Faisal Nusairat
o Drukkerij: Apress
o ISBN-10: 1-59059-792-3
• Practical Jboss Seam Projects
o Autheur: Jim Farley
o Drukkerij: Apress
o ISBN-10: 1-59095-863-6
• Seam In Action (Covers Seam 2.0)
o Autheur: Dan Allen
o Unedited Draft
10.2 Webpagina’s
• Demosite over Richfaces 3.2
o http://livedemo.exadel.com/richfaces-demo/index.jsp
• Jira pagina’s van JBoss
o http://jira.jboss.org
• Het JBoss Forum
o http://www.jboss.com/index.html?module=bb
Eindwerk Bram Gadeyne
2007-2008
125
11 Bijlagen
11.1 Installatie onder Windows
Eindwerk Bram Gadeyne
2007-2008
126
Installatie van Project Commas
In Windows
Eindwerk Bram Gadeyne
2007-2008
127
Inleiding
In dit document bespreken we hoe we het project Commas kunnen gebruiksklaar maken. We
zullen beginnen met het installeren en configureren van de verschillende servers. Daarna
configureren we het project nog zodat deze aangepast wordt aan de omgeving.
Downloaden van de benodigde software
De laatste versie van de Java JDK
Deze applicatie is geschreven in Java. Hierdoor hebben we dan ook de Java runtime environment
(JRE) nodig om de applicatie uit te kunnen voeren.
U kunt de laatste versie van JDK downloaden van de website van Sun ( http://java.sun.com) . Daar
kunt u onder downloads kiezen voor downloads voor Java SE. Bij die downloads kies je dan voor
de laatste JDK voor Windows. U kunt kiezen voor een offline installatie of een online installatie die
dan de benodigde onderdelen voor u van het internet zal downloaden.
JBOSS Server
Onze applicatie wordt gehost vanaf een Applicatie Server. Wij kozen de JBOSS Server. Deze kunt u
downloaden van http://labs.jboss.com/jbossas/downloads
De huidige versie is versie 4.2.2 GA. U kunt het beste de gewone zip file downloaden. In onze geval
jboss-4.2.2.GA.zip.
Oracle Express Edition
Op de achtergrond van onze applicatie draait een database. In ons geval de Oracle express edition.
Deze kunt u downloaden van
http://www.oracle.com/technology/software/products/database/xe/index.html
Daar kiezen we voor de Windows versie. Let wel, u moet geregistreerd zijn op de website alvorens
u de server kunt downloaden. Na het accepteren van de overeenkomst kunnen we de Oracle XE
versie downloaden die we nodig hebben. We kiezen voor de “Western European” versie.
Nu moeten we inloggen met onze gegevens van oracle.com of kunnen we een nieuw account
aanmaken. Daarna kunt u de server downloaden.
Oracle SQL Developer
Om de database te kunnen installeren zullen we gebruik maken van deze software. U kunt het
downloaden van http://www.oracle.com/technology/software/products/sql/index.html
Voor deze download hebben we ook weer een oracle.com login nodig zoals bij het downloaden
van Oracle Express. We kunnen hiervoor dezelfde login gegevens gebruiken. We kiezen de versie
zonder JDK aangezien we de laatste versie van JDK al hebben gedownload.
Eindwerk Bram Gadeyne
2007-2008
128
Installatie van de benodigde software
Installatie van Java JDK
Open de net gedownloade JDK installatie file. Accepteer de licentie overeenkomst
Daarna ziet u welke onderdelen er standaard zullen geïnstalleerd worden. Ook kunt u kiezen om
het installatie pad te veranderen. Wij laten het staan op de default waarden.
Eindwerk Bram Gadeyne
2007-2008
129
Nu wordt Java geïnstalleerd op de computer die als server zal dienen.
Nu krijgt u nog de mogelijkheid om een aantal onderdelen aan te passen aan uw behoeften. We
laten echter alles standaard staan.
Eindwerk Bram Gadeyne
2007-2008
130
Hierna is de installatie van Java afgelopen.
Installatie van JBOSS Server
We unzippen de gedownloade zipfile in C:\Program Files. Op die manier krijgen we daar een
mapje “jboss-4.2.2.GA” waarin alle bestanden van onze server aanwezig zijn.
Voordat we onze server kunnen starten moeten we nog de JAVA_HOME Variabele definiëren in
onze systeemvariabelen. Daarvoor gaan we naar het configuratiescherm waar we kiezen voor
Systeem. Op het tabblad geavanceerd kiezen we voor “Omgevingsvariabelen”.
Eindwerk Bram Gadeyne
2007-2008
131
Eindwerk Bram Gadeyne
2007-2008
132
Door op nieuw te klikken kunnen we de JAVA_HOME variabele toevoegen. We laten deze nu
verwijzen naar het installatie pad van onze JDK.
Daarna klikken we over op "ok".
We kunnen nu testen of onze installatie gelukt is. Dit kunnen we doen door in de bin map van de
installatie map van de JBOSS Server het bestandje “run.bat” te openen. Nu zie je in een
commando venster de server opstarten.
Als we dit de eerste maal doen zal de firewall van Windows XP ons vragen of we Java SE willen
blokkeren of niet. We kiezen hier voor Blokkering opheffen.
Als alles goed verloopt, moet er op het einde iets te zien zijn zoals “16:33:28,890 INFO [Server]
JBoss (MX MicroKernel) [4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=200710221139)] Started
in 19s:703ms”
Eindwerk Bram Gadeyne
2007-2008
133
Sluit het commando venster niet! We kunnen nu surfen naar http://localhost:8080/web-console/.
Als we dan volgende pagina te zien krijgen is de installatie gelukt.
Installatie van Oracle XE
Hiervoor hebben we de oracleXE.exe file nodig die we daarnet hebben gedownload.
Eindwerk Bram Gadeyne
2007-2008
134
Tijdens de installatie van Oracle XE starten we ook de server van JBOSS op. Om te weten hoe dit
moet zie het hoofdstuk “installatie van JBOSS Server”. We moeten dit doen omdat onze JBOSS
server op poort 8080 werkt standaard. Onze Oracle XE heeft echter ook een webconsole die op
dezelfde poort draait. Als deze poort tijdens de installatie niet in gebruik is kunnen we ook niet
een andere poort voor deze console kiezen.
Open het bestand oracleXE.exe
Nadat we op volgende hebben geklikt, moeten we de licentie overeenkomst accepteren.
We kunnen nu kiezen om Oracle op een andere da de standaard locatie te installeren. We laten dit
staan en klikken op volgende.
Eindwerk Bram Gadeyne
2007-2008
135
Omdat poort 8080 bezet is wordt ons gevraagd om een andere poort te kiezen voor de
webconsole. Oracle stelt poort 8081 voor. U kunt deze waarde accepteren door op next te klikken.
De standaard gebruiker in Oracle is de “SYSTEM” gebruiker. Oracle vraagt ons nu om een
paswoord op te geven voor de SYSTEM gebruiker.
Eindwerk Bram Gadeyne
2007-2008
136
Er wordt nog een overzichtje gegeven van de installatie die wordt gestart nadat we op install
hebben geklikt.
Na de installatie wordt ons gevraagd of we de database homepage willen openen. We zullen dit
accepteren om een nieuwe gebruiker aan te kunnen maken. (via het menu start kan er eventueel
later ook nog naar deze webpagina worden gegaan.
Eindwerk Bram Gadeyne
2007-2008
137
We kunnen nu inloggen met de username SYSTEM en het paswoord die we daarnet hebben
opgegeven tijdens de installatie.
Op de volgende pagina kiezen we ervoor om een nieuwe gebruiker aan te maken zoals
aangegeven in onderstaande afbeelding.
Eindwerk Bram Gadeyne
2007-2008
138
We geven nu een gebruikersnaam en paswoord op voor onze nieuwe gebruiker. Wij kozen voor
COMMAS als gebruikersnaam en paswoord als paswoord. Deze gebruiker is de gebruiker die we
zullen gebruiken voor ons programma. Op die manier kan ons programma dan toegang krijgen tot
de database. We kunnen deze gebruiker ook alle rechten geven op onze databank door alle vinkjes
aan te vinken.
Eindwerk Bram Gadeyne
2007-2008
139
U Kunt eventueel nog extra gebruikers aanmaken indien gewenst.
Oracle SQL Developer installeren
De installatie van Oracle SQL Developer bestaat enkel uit het unzippen van het zipbestand die we
hebben gedownload.
U kiest daarvoor een locatie zoals “C:\Program Files”. U kunt SQL Developer opstarten door
sqldeveloper.exe uit te voeren die te vinden is in de unzipte map.
De eerste maal dat we sqldeveloper opstarten wordt ons gevraagd naar de locatie van de java.exe
file. Deze is te vinden in C:\Program Files\Java\jdk1.6.0_05\jre\bin\java.exe. Of in de jre/bin map
van de Java installatie folder als u deze op een andere locatie zou geïnstalleerd hebben.
Eindwerk Bram Gadeyne
2007-2008
140
Daarna wordt ons gevraagd om settings van een vorige versie te migreren maar omdat dit een
nieuwe installatie is kiezen we dus voor “No”.
Door rechts te klikken op Connection en te kiezen voor new connection kunnen we nu een nieuwe
connectie aanmaken.
Nu moeten we inloggen met ons COMMAS account. Deze gebruiker beschikt over de rechten op
de Commas databank.
Eindwerk Bram Gadeyne
2007-2008
141
Door op test te klikken kunnen we ook onmiddellijk al testen of onze gegeven correct zijn.
Daarna klikken we op connect.
We zien nu dat er nog geen tabellen zijn aangemaakt in de COMMAS databank. Hiervoor kunnen
we het script export.sql uitvoeren.
Via het menu File-> Open kunnen we de locatie van het script aantonen. Daarna kunnen we het
laten uitvoeren door op de knop script uitvoeren te klikken.
Er wordt ons dan gevraagd via welke connectie we het script willen laten uitvoeren. We kiezen
daarvoor onze Oracle local connectie.
Eindwerk Bram Gadeyne
2007-2008
142
Als we nu recht klikken op tables en kiezen voor refresh dan zouden we daar onze 21 tabellen
moeten zien verschijnen. We kunnen ook refresh kiezen bij sequences en daar zouden 20
sequences te vinden moeten zijn.
Configuratie server
JNDI connectie
Onze Application Server (JBOSS Server) moet kunnen communiceren met onze database (Oracle).
Daarvoor moeten we een JNDI connectie voorzien. Deze moet een unieke naam hebben die ook
binnen ons project gekend is. Bij ons is dit “jdbc/OracleDS”.
Het bestand oracle-ds.xml bevat de configuratie voor onze Oracle connectie.
Eventueel kunt u de username en het paswoord nog aanpassen indien u tijdens de installatie een
andere zou gebruikt hebben.
Eindwerk Bram Gadeyne
2007-2008
143
Dit bestand plaatsen we dan in de map “C:\Program Files\jboss-4.2.2.GA\server\default\deploy”.
Of in de server\default\deploy map indien u een andere installatie locatie zou gekozen hebben.
We plaatsen ook het bestand ojdbc14_g.jar in de \server\default\lib. Op die manier beschikt onze
server over een Driver om connectie te kunnen maken met de Oracle Database.
Deployment van het project
Één van de laatste zaken die moeten gebeuren is het uiteindelijke project op de server plaatsen.
Dit doen we door de “ProjectCommas-ear.ear” map in onze deploy map te zetten. Dit is dezelfde
locatie als waar we de databank connectie hebben geplaatst. In ons geval dus “C:\Program
Files\jboss-4.2.2.GA\server\default\deploy”.
Option.Properties
In de WEB-INF\classes map van onze war file vinden we het bestand option.properties.
Hierin kunnen we enkele opties veranderen die de werking van onze applicatie kunnen
beïnvloeden. De opties.properties file wordt automatisch om de minuut ingelezen door onze
webserver. Op die manier kunnen we opties veranderen zonder de webserver te moeten opnieuw
opstarten.
Directory’s
In deze directory’s worden bestanden opgeslaan soms tijdelijk, soms permanent. De locatie
hiervan kan dus worden gewijzigd.
•
•
•
•
Mail
rapportendir=C:/Program Files/commas/rapporten/
pdfdir=C:/Program Files/commas/pdf
klantentevredenheidfilesdir=C\:/Program Files/commas/files/Klantentevredenheid/
certificatenfilesdir=C\:/Program Files/commas/files/Certificaat/
Deze 2 opties bepalen de locatie van de smpt mailserver van onze applicatie alsook de frequentie
waarop automatisch op te verzenden mails moet worden gecontroleerd.
mailserver=HUSEXV02.dolmen.be
mailtimertask=60000
Varia:
Als laatste hebben we ook nog enkele opties die gebruikt worden om de werking van ons
programma te veranderen. Listsize geeft de lengte van de weergegeven lijsten terug. nrOfPages
geeft weer hoeveel pagina’s er moeten worden weergegeven door de datascrollers. Defaultpass is
de instelling van het paswoord die standaard wordt gebruikt bij het aanmaken van een nieuwe
medewerker. Timertaks is de instelling in milliseconden van om de hoeveel tijd de
options.properties file moet worden ingelezen.
Eindwerk Bram Gadeyne
2007-2008
144
Opgelet! De timertask optie zal enkel veranderingen teweeg brengen bij het opnieuw opstarten
van de server.
•
•
•
•
listsize=5
defaultpass=paswoord
timertask=60000
nrOfPages=5
Commas map
In de Program Files map op de C-schijf plaatsen we de map “commas” waarin een aantal
belangrijke mappen zitten voor ons project voor fileupload.
Project testen
We controleren in de commas map het bestand options.properties of alle waarden wel correct zijn
ingegeven. Daarna beginnen we met het opstarten van de server (zie installatie JBOSS Server voor
meer uitleg). Als alles goed verloopt dan kunnen we nu surfen naar
http://localhost:8080/ProjectCommas/ . Je kan er inloggen met de gebruikersnaam
“administrator” en het paswoord “paswoord”.
Eindwerk Bram Gadeyne
2007-2008
145
11.2 Installatie onder Linux
Eindwerk Bram Gadeyne
2007-2008
146
Installatie van Project Commas
onder Linux
Eindwerk Bram Gadeyne
2007-2008
147
Inleiding
In dit document bespreken we hoe we het project Commas kunnen gebruiksklaar maken onder
linux. We zullen beginnen met het installeren en configureren van de verschillende servers.
Daarna configureren we het project nog zodat deze aangepast wordt aan de omgeving.
Downloaden van de benodigde software
De laatste versie van de Java JDK
Deze applicatie is geschreven in Java. Hierdoor hebben we dan ook de Java runtime environment
(JRE) nodig om de applicatie uit te kunnen voeren.
U kunt de laatste versie van JDK downloaden van de website van Sun ( http://java.sun.com) . Daar
kunt u onder downloads kiezen voor downloads voor Java SE. Bij die downloads kies je dan voor
de laatste JDK voor linux. U kunt kiezen voor een offline installatie of een online installatie die dan
de benodigde onderdelen voor u van het internet zal downloaden.
In Ubuntu Linux kunnen we echter deze installatie ook automatisch laten gebeuren. Dit doen we
door in Synaptic pakketbeheer te kiezen voor jdk 6 (of de laatste versie van de jdk).
Eindwerk Bram Gadeyne
2007-2008
148
JBOSS Server
Onze applicatie wordt gehost vanaf een Applicatie Server. Wij kozen de JBOSS Server. Deze kunt u
downloaden van http://labs.jboss.com/jbossas/downloads
De huidige versie is versie 4.2.2 GA. U kunt het beste de gewone zip file downloaden. In onze geval
jboss-4.2.2.GA.zip.
Oracle Express Edition
Op de achtergrond van onze applicatie draait een database. In ons geval de Oracle express edition.
Deze kunt u downloaden van:
http://www.oracle.com/technology/software/products/database/xe/index.html
Daar kiezen we voor de linux versie. Let wel, u moet geregistreerd zijn op de website alvorens u de
server kunt downloaden.
Na het accepteren van de overeenkomst kunnen we de Oracle XE versie downloaden die we nodig
hebben. We kiezen voor de “Western European” versie.
Nu moeten we inloggen met onze gegevens van oracle.com of kunnen we een nieuw account
aanmaken.
Daarna kunt u de server downloaden.
Oracle SQL Developer
Om de database te kunnen installeren zullen we gebruik maken van deze software.U kunt het
downloaden van http://www.oracle.com/technology/software/products/sql/index.html
Voor deze download hebben we ook weer een oracle.com login nodig zoals bij het downloaden
van Oracle Express. We kunnen hiervoor dezelfde login gegevens gebruiken. We kiezen de versie
zonder JDK aangezien we de laatste versie van JDK al hebben gedownload.
Installatie van de benodigde software.
Installatie van de JDK 1.6
Om JDK te installeren onder een andere distributie van Linux kunt u installatie instructies vinden
op de site van SUN of op de site van uw distributie.
In Ubuntu Linux kunnen we deze installatie automatisch laten gebeuren. Dit doen we door in
Synaptic pakketbeheer te kiezen voor jdk 6 (of de laatste versie van de jdk).
Eindwerk Bram Gadeyne
2007-2008
149
Installatie van JBOSS Server
We unzippen de gedownloade zipfile ergens op de linux computer. Bijvoorbeeld
/home/bram/Bureaublad. Op die manier krijgen we daar een mapje “jboss-4.2.2.GA” waarin alle
bestanden van onze server aanwezig zijn.
Voordat we onze server kunnen starten moeten we nog de JAVA_HOME Variabele definiëren in
onze systeemvariabelen. In Ubuntu Linux werd voor ons de JAVA_HOME variabele al
geconfigureerd. Om te weten hoe dit moet voor uw distributie kunt u op de site van Sun
raadplegen of de site van uw distributie.
oracle-xe installatie
We openen het gedownloade *.deb bestand die de installatie bestanden van onze oracle XE server
bevat. Daarna krijgen we volgend scherm te zien.
Eindwerk Bram Gadeyne
2007-2008
150
We klikken op pakket installeren en alle benodigde libraries worden voor ons gedownload en
geïnstalleerd. Let wel dat je hiervoor best een actieve internet connectie hebt.
Eindwerk Bram Gadeyne
2007-2008
151
Na de installatie voeren we zoals aangegeven het commando sudo /etc/init.d/oracle-xe configure
uit in de terminal.
Eindwerk Bram Gadeyne
2007-2008
152
Nu kunnen we surfen naar http://127.0.0.1:9090/apex om onze server verder te configureren.
Indien dit niet onmiddellijk werkt kunnen we ook het commando sudo /etc/init.d/oracle-xe forcereload uitvoeren.
Toevoegen van een gebruiker aan de dba groep
Om de Oracle server te kunnen laten werken moeten we eerst nog onze gebruiker toevoegen aan
de rol “dba.” zoals hieronder staat aangegeven. Na het toevoegen moeten we onze huidige
gebruiker even uitloggen uit het systeem en vervolgens opnieuw aanmelden.
Daarna kunnen we onze server herstarten met het commando sudo /etc/init.d/oracle-xe forcereload.
Eindwerk Bram Gadeyne
2007-2008
153
Toevoegen van een gebruiker aan de Oracle server
Eindwerk Bram Gadeyne
2007-2008
154
Nadat we zijn ingelogd met de gebruikersnaar SYSTEM en het tijdens de configuratie opgegeven
paswoord, kunnen we een nieuwe gebruiker toevoegen die we COMMAS zullen noemen.
Eindwerk Bram Gadeyne
2007-2008
155
Installatie SQL Developer
Omdat wij in Ubuntu met een op debian gebaseerd systeem zitten moeten we de door Oracle
gedistribueerde .rpm file omzetten naar een .deb file. Dit kunnen we doen met het commando
alien –script bestandsnaam.
Daarna kunnen we de .deb file gewoon openen en installeren door op pakket installeren te
klikken.
Eindwerk Bram Gadeyne
2007-2008
156
Configuratie applicatie
Configuratie database via sql developer
De eerste keer dat we onze sql developer opstarten (te vinden bij de geïnstalleerde toepassingen)
wordt ons gevraagd of we de settings van een vorige installatie willen overnemen. We kiezen voor
“no”.
Nadat we in het systeem zijn ingelogd moeten we een nieuwe connectie toevoegen die we “local”
noemen.
Eindwerk Bram Gadeyne
2007-2008
157
We kunnen onze connectie testen door op de knop test te klikken. Daarna klikken we op de knop
connect.
Nu openen we het bestand export.sql (of export-data.sql om test data mee te installeren).
Eindwerk Bram Gadeyne
2007-2008
158
Vervolgens klikken we op het 2de groene pijltje om het script uit te voeren.
Daarna wordt ons gevraagd via welke connectie we het script willen uitvoeren. We kiezen onze
net aangemaakte “local” connectie.
Controleer of alle tabellen zijn aangemaakt. Indien dat niet zo is kunt u het script nogmaals
proberen uit te voeren.
Installatie EAR
Eindwerk Bram Gadeyne
2007-2008
159
Plaats de ear file in de deploy locatie samen met het configuratiebestand oracle-ds.xml.
Controleer in het configuratie bestand de juistheid van de connectie gegevens.
Voeg in de map \server\default\lib het bestand ojdbc14_g.jar. Op die manier beschikt de server
over een driver om te kunnen verbinden met de Oracle Database.
Configuratie EAR
In ons EAR bestand bevindt zich het bestand ProjectCommas.war. In deze war bevindt zich op de
locatie /WEB-INF/classes het bestand options.properties. In deze file kunt u enkele opties
veranderen die de werking van onze applicatie veranderen. Controleer hier zeker de correctheid
van de 4 directories die aangeven waar respectievelijk de rapporten lokaliseren, de pdf's opslaan
en de 2 mappen waarin klantentevredenheidsbestanden en certificaatbestanden worden
opgeslagen.
Zorg ervoor dat de wijzigingen opgeslagen worden in de EAR file.
Configuratie Mail
Onze applicatie is in staat om mails te verzenden. De connectie hiervoor wordt geconfigureerd in
het bestand components.xml die zich in de map WEB-INF van de war file bevindt. In dit bestand
kunt u de regel <mail:mail-session host="HUSEXV02.dolmen.be"/> aanpassen en een andere host
instellen.
Zorg ervoor dat de wijzigingen opgeslagen worden in de EAR file.
Opstarten applicatie
Opstarten Jboss Server
In de map waar we onze Jboss server hebben uitgepakt gaan we met onze terminal naar de map
bin. In deze map bevindt zich het bestand run.sh. Dit kunnen we uitvoeren door “./run.sh” uit te
voeren.
We zien vervolgens de server opstarten.
Eindwerk Bram Gadeyne
2007-2008
160
Opstarten browser
Na de installatie kunnen we surfen naar de url http://localhost:8080/ProjectCommas. Daarna
wordt onze applicatie opgestart. Voor het inloggen, kunt u standaard aanmelden met de gebruiker
“administrator” en het paswoord “paswoord”.
Eindwerk Bram Gadeyne
2007-2008
161
11.3 Actierapport
Dit is een rapport die kan gegenereerd worden met JasperReports. Het geeft een overzicht van alle
Acties van de medewerker dummy1.
Eindwerk Bram Gadeyne
2007-2008
162
Eindwerk Bram Gadeyne
2007-2008
163
11.4 Functiebeschrijving rapport
In dit rapport wordt een samenvatting van een functiebeschrijving weergegeven. Recursief
worden alle competenties op het rapport ingevuld. Dit is mogelijk via de subrapporten.
Eindwerk Bram Gadeyne
2007-2008
164
Eindwerk Bram Gadeyne
2007-2008
165
Eindwerk Bram Gadeyne
2007-2008
166
Download