IT- D I P L O M U D D A N N E L S E N EKSAMENSPROJEKT AF JAN SCHRØDER HANSEN EFTERÅR 2009

Størrelse: px
Starte visningen fra side:

Download "IT- D I P L O M U D D A N N E L S E N EKSAMENSPROJEKT AF JAN SCHRØDER HANSEN EFTERÅR 2009"

Transkript

1 IT- D I P L O M U D D A N N E L S E N WEB OG SERVERPROGRAMMERING EKSAMENSPROJEKT AF JAN SCHRØDER HANSEN EFTERÅR 2009

2 INDHOLD 1. Indledning Opgavebeskrivelse Afgrænsing Lidt om WICKET Design Designklassediagram Indeling af kode i lag Programmering Sikkerhed Brugervejledning Konklusion Bilag Fejlsituationer Kode Pakke dk.jsh.itdiplom.wsp.bari.wicket Pakke dk.jsh.itdiplom.wsp.bari.bussiness Pakke dk.jsh.itdiplom.wsp.bari.domain Pakke dk.jsh.itdiplom.wsp.bari.util Pakke dk.jsh.itdiplom.wsp.bari.wicket.test SQL til dannelse af databasen Konfigutationsfiler Ant target til generering af databaseskema Eksempler på unit test Indhold på vedlagte CD

3 1. INDLEDNING Dette eksamensprojekt er lavet i forbindelse med faget Web og serverprogrammering på IT- Diplomuddannelsen, Ingeniørhøjskolen i København. Faget har taget udgangspunkt i bogen Webprogrammering med JSP af Jacob Nordfalk, som også er underviser i faget. 2. OPGAVEBESKRIVELSE For at komme igennem så meget af materialet i faget som muligt, har jeg valgt at lave en webløsning til håndtering af ønsker og fejlreporter, til et eller flere softwareprodukter. Der skal være mulighed for at følge status på fejl og ønsker. Er fejlen eller ønsket godkendt, afvist, er det under udvikling, under test etc. Derudover skal der være mulighed for at uploade forskellige filer såsom skærmdumps af fejl, eller prototyper på ny skærmlayouts og andre filer som kan hjælpe til at belyse en sag. Et andet mål med opgaven er at afprøve web-frameworket Wicket 1. Jeg har taget udgangspunkt i bogen Wicket in Action 2 af Martijn Dashorst og Eelco Hillenius. Programmets navn er BaRI, som står for Bugs and Request Interceptor AFGRÆNSING For at afgrænse opgaven har jeg valgt, at se bort fra login, brugerroller og fil uploads. Det fremgår også af mit designklassediagram, se Designklassediagram, hvilke klasser som er implementeret. Strenge og dato/tid formater er skrevet direkte i koden, så hvis programmet skal benyttes på andre sprog end dansk, skal alle strenge og dato/tid formater m.m., flyttes ud i nogle ressource filer. Løsningen er heller ikke dækket ind med hensyn til unit tests. Der er dog lavet en enkelt unit test, for at demonstrere at Wicket er forberedt til unit tests. 1 Wicket, se wicket.apache.org. 2 Wicket in Action, se 3

4 3. LIDT OM WICKET På Wickets hjemmeside kan man læse om de mål, udviklerne har haft med Wicket 3. Jeg vil her komme ind på de punkter, jeg selv som udvikler lægger vægt på. Som udvikler har jeg arbejdet med Struts 1.3, samt med ASP.NET, og en af de problemer som er i disse frameworks, er bl.a. at man blander kode med html. I Struts arbejdes der med java, jsp tags, html tags, javascript i en og samme fil. Det samme gør sig også gældende i ASP.NET, hvor det så bare er C# kode, ASP tags, html tags. Og det giver nogle filer som er svære at overskue, svære at genbruge og vedligeholde. Helt grundlæggende prøver Wicket, at adskille html og kode. Det giver mulighed for, at det faktisk er muligt at få en html/css specialist, til at lave selve html/css koden. Som så kan overtages af en programmør. Det er ikke rigtigt muligt med f.eks struts og ASP.NET, da der er så mange specielle tags, som en html specialist ikke kender til, og som ikke kan håndteres af webdesigners værktøjer. Wicket benytter også nogle gamle java dyder som, en klasse, en java fil. I Wicket kan en Wicket webside, beskrives vha. en html fil og en java fil. Begge ligger i samme katalog og hedder det samme, på nær fil endelsen. Det eneste krav Wicket stiller til html filerne er, at de html elementer der skal være dynamiske, skal have en entydigt Wicket identifikation. En anden ting med Wicket er, at Unit test er tænkt ind i systemet fra starten af. Det er nemt at tage en Wicket side, og teste den vha. JUnit. Se Bilag Eksempler på unit test. 3 Why Wicket, se wicket.apache.org/introduction.html 4

5 4. DESIGN Følgende er en kort beskrivelse af designet af BaRI webapplikationen. Startende med et designklassediagram DESIGNKLASSEDIAGRAM Figur 1 - Designklassediagram De hvide klasser er ikke implementeret endnu. BariUser er delvist implementeret, den persisteres dog ikke i databasen. De grønne klasser er fuldt implementeret, dvs. at de også persisteres. De gule klasser er implementeret som java enums. Dvs. at deres værdi bliver persisteret sammen med BariCase. Det er meningen at BaRI skal kunne håndtere forskellige software projekter/produkter, det er derfor, der er en Product klasse og en UserGroup klasse, så man kan knytte brugere til de enkelte produkter. De enkelte brugere skal også kunne have forskellige roller, som styres af Role klassen. Klassen BariUser og Role kunne evt. håndteres af Webserveren, der som standard kan tilbyde disse funktioner, enten vha. Webserveres konfigurationsfiler. Webserveren kan også konfigureres så den henter brugere og roller fra en database. 5

6 4.2. INDELING AF KODE I LAG Jeg har inddelt min kode i 3 overordnet lag, vha. java pakker, se følgende diagram. Figur 2 Pakkediagram Pakkerne som starter med dk.jsh.itdiplom.wsp.bari, er udviklet i forbindelse med denne opgave. Wicket og Hibernate 4 er de to frameworks som benyttes til henholdsvis Web delen og til database delen. JavaDB er den database som benyttes. De 3 pakker som starter med dk.jsh.itdiplom.wsp.bari indeholder følgende: Pakke dk.jsh.itdiplom.bari.wicket Beskrivelse Kode til generering af de enkelte web-sider. dk.jsh.itdiplom.wsp.bari.busines Forretningslogik, i forbindelse med Hibernate dk.jsh.idtiplom.wsp.bari.domain Data elementer, som dels persisteres, og som benyttes som value objects, mellem de andre lag. De samme klasser som fremgår af Designklassediagrammet. Hibernate benyttes sammen med domain klasserne, som har annotations på de attributter som skal persisteres. Ud fra disse kan Hibernate vha. et ant target lave en database skemafil og håndtere adgang til databasen. Derudover er der en enkel pakke mere som benyttes til Unit test 5, pakken hedder dk.jsh.itdiplom.wsp.bari.wicket.test. 4 Hibernate, se 5 Unit test, se en.wikipedia.org/wiki/unit_testing 6

7 5. PROGRAMMERING Under programmeringen har jeg gjort brug af følgende værktøjer og teknikker: NetBeans 6 Java IDE, Java udviklingsmiljø. JavaDB 7 tidligere Derby, er nu en del af standard java. Apache Tomcat 8 Webserver. SubVersion 9 - Repository til al kode. Bl.a for at have backup af koden på en anden maskine, og for at få historik på mine koderettelser. Frameworks: Hibernate og Wicket, beskrevet tidligere. Alle diagrammer er lavet vha. Dia 10, som har skabeloner til UML diagrammer. De enkelte diagrammer ligger også på den vedlagte CD. Se bilag for indholdet på den vedlagte CD. 6 NetBeans IDE, se netbeans.org 7 JavaDB, se developers.sun.com/javadb 8 Apache Tomcat, se tomcat.apache.org 9 SubVersion, se subversion.tigris.org 10 Dia, se projects.gnome.org/dia 7

8 6. SIKKERHED Wicket er ifølge wickets hjemmeside 11 secure by default. Og jeg har heller ikke kunne fremprovokere diverse Injection flaws 12 angreb. SQL injections forebygger jeg vha. Hibernate s måde at lave prepared statement på, f.eks som i følgende kode: String hql = "select discussionmessage from " + "dk.jsh...wsp.bari.domain.discussionmessage discussionmessage " + "where baricase.id = :id " + "order by discussionmessage.created"; Query query = session.createquery(hql); query.setstring("id", baricase.getid().tostring()); Som det fremgår af koden, bliver ingen variabler direkte indsat i SQL strengen, men via metoden setstring(). Med hensyn til adgangskontrol så har data modellen, se Designklassediagram, en bruger (BariUser), med nogle roller (Role). Dette ligger tæt op af, hvad en Webserver tilbyder. Så jeg vil anbefale at man bruger det indbyggede brugeradgangskontrol, som findes i webserveren, også kaldet containerstyret adgangskontrol, sammen med HTTPS/SSL 13, hvis man vil være helt sikker på, at et evt. password ikke bliver opsnappet. Men derudover mener jeg ikke, at der er noget i denne Webapplikation, som er så følsomt at det kræver HTTPS. Hvis man ikke vil betale for et HTTPS/SSL certifikat, kan man nøjes med at benytte Authmethod: Digest, som ikke overføre password i klartekst, men som en hashværdi. Det beskytter dog ikke mod man-in-the-middle 14 angreb. 11 Wicket introduction, se wicket.apache.org/introduction.html 12 Se OWASP Top 10, se 13 HTTPS/SSL, se en.wikipedia.org/wiki/transport_layer_security 14 Man in the middle, se en.wikipedia.org/wiki/man-in-the-middle_attack 8

9 7. BRUGERVEJLEDNING Første gang BaRI startes vil følgende tomme oversigts side vises. Figur 3 Oversigtsside BaRI er opdelt i to områder. Et Menu område som benyttes til at navigere rundt i BaRI med. Denne er ens for alle BaRI sider. Derunder er der et arbejdsområde, som skiftes ud efter de valg der fortages i Menu området. For at oprette en ny sag, trykkes der på Opret linket i menu boksen og følgende skærmbillede fremkommer. Figur 4 - Opret ny sag side På denne side kan man oprette enten en ny fejl eller et nyt ønske. Det bestemmes af Type feltet. På det næste billede er man klar til at gemme en ny fejl. 9

10 Figur 5 - Oprettelse af en fejl Når der trykkes på Gem knappen, så gemmes sagen og man kommer tilbage til oversigtssiden. Fortryd returnerer også til oversigtssiden, dog uden at gemme. Figur 6 - Retur til oversigtssiden Øverst over listen kan man ændre søgekriterierne for listen. Man kan vælge at se enten alle fejl eller alle ønsker. Man kan også søge efter hvilken status, de enkelte sager har vha. Status feltet. Hvis status Alle vælges, så vises alle sager af den valgte type. Listen opdateres ved at trykke på Søg knappen. 10

11 Til højre under listen ses følgende navigationslinks: Link Beskrivelse << Viser første 10 sager i listen. < Viser forrige 10 sager. 1 Går direkte til side, her 1. > Viser de næste 10 sager. >> Viser de sidste sager i listen. Nu kan den nye fejl vedligeholdes ved at trykke på Vis linket i listen. Og følgende side vises. Figur 7 - Side for vedligeholdelse af en sag Felterne Oprettet af, Oprettet den og Afsluttet den kan ikke rettes. 11

12 Sags status kan have følgende værdier: Værdi Ny Beskrivelse Det er en ny sag. Behandles Sagen behandles, dvs. der bliver taget stilling til, om man skal gå videre med sagen. Godkendt Sagen er godkendt og dermed klar til en udvikler. Afvist Afsluttet Sagen er afvist. Sagen er færdigudviklet og afsluttet. Feltet Afsluttet den får dagsdato. Udviklings status kan have følgende værdier: Værdi Ej begyndt I gang Klar til test Testet I prod. Beskrivelse Venter på en udvikler. Sagen er i gang. Sagen venter på at blive testet. Sagen er testet. Sagen er i produktion Der er mulighed for at rette oplysninger, slette hele sagen, vha. af Gem og Slet knapperne. Eller man kan gå til en diskussions side ved at trykke på Gå til diskussion linket. Som vises på følgende side. 12

13 Figur 8 - Diskussionsside Denne side giver mulighed for, at slutbrugere og udviklere kan diskutere forskellige ting. F.eks. løsningsforslag til et nyt ønske. Følgende side er et eksempel på en diskussion. 13

14 Figur 9 - Eksempel på en diskussion Til slut - Om BaRI linket giver følgende side: Figur 10 - Om BaRI siden Se også Fejlsituationer, under bilag for eksempler på fejl situationer i BaRI. 14

15 8. KONKLUSION Det har været en god oplevelse at arbejde med Wicket, man kommer meget hurtigt i gang. Og jeg synes at Wicket lever meget fint op til de forventninger, jeg havde til frameworket. Der er en meget klar adskillelse mellem html og java. Det ses bl.a. meget tydeligt på de små og meget overskuelige html-sider i dette projekt. Wicket gør også meget for at gemme webapplikationsproblematikkerne væk fra programmøren. Så denne kan koncentrere sig som selve forretningslogikken. Og det var dejligt at sidde og kode i java igen. Html delen er hurtigt overstået med Wicket. Wicket arbejder også godt sammen med andre frameworks, jeg har benyttet Hibernate til database persistense, uden problemer. Hvis jeg skulle nævne en enkelt bekymring, så skulle det måske være at Wicket bruger en del hukommelse på server siden. Da Wicket bruger de enkelte webserverobjekter som session request meget. Så jeg er ikke sikker på at Wicket egner sig til systemer, som rammes af tusindvis af brugere dagligt. Men ellers vil jeg varmt anbefale Wicket. 15

16 9. BILAG 9.1. FEJLSITUATIONER Følgende er eksempler på fejlsituationer i BaRI. Første eksempel er et forsøg på at gemme en sag, hvor feltet Beskrivelse ikke er udfyldt. Figur 11 - Obligatorisk felt mangler 16

17 Andet eksempel er et forsøg på at rette en sag, som er rettet af en anden person i mellemtiden. BaRI benytter optimistisk låsning vha. Hibernate. Figur 12 - Optimistisk låsning 17

18 9.2. KODE Koden er delt op de enkelte javapakker PAKKE DK.JSH.ITDIPLOM.WSP.BARI.WICKET Application.java package dk.jsh.itdiplom.wsp.bari.wicket; import org.apache.wicket.protocol.http.webapplication; Wicket Jan S. Hansen public class Application extends WebApplication { Constructor. public Application() { Returns home page for the public Class gethomepage() { return Overview.class; BasePage.html Denne htmlside er en fælles side for alle sider, en slags abstract html side, som de andre sider arver fra. Det er her menuen og fejltekstområdet defineres. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>bari</title> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <link wicket:id='stylesheet'/> </head> <body> <div id="container"> <div id="header"> <h1>bari</h1> </div> <div id="contents"> <fieldset> <legend>menu</legend> <a href="#" wicket:id="createnew">opret</a> <a href="#" wicket:id="overview">oversigt</a> <a style="float:right" href="#" wicket:id="about"> Om BaRI</a> </fieldset> </div> <div id="error"> <span wicket:id="error">error message goes here</span> </div> <div id="main"> <wicket:child /> </div> </div> </body> </html> 18

19 BasePage.java Det samme som beskrevet for BasePage.html gør sig gældende for denne fil. package dk.jsh.itdiplom.wsp.bari.wicket; import dk.jsh.itdiplom.wsp.bari.domain.bariuser; import dk.jsh.itdiplom.wsp.bari.domain.constants.type; import java.text.simpledateformat; import org.apache.wicket.page; import org.apache.wicket.markup.html.webpage; import org.apache.wicket.markup.html.basic.label; import org.apache.wicket.markup.html.link.link; import org.apache.wicket.markup.html.resources.stylesheetreference; import org.apache.wicket.model.propertymodel; Abstract wicket base page. Handles common error message handling, stylecheet and menu Jan S. Hansen public abstract class BasePage extends WebPage { final static SimpleDateFormat standarddatetimeformat = new SimpleDateFormat("dd/MM-yyyy HH:mm"); private String errormessage = ""; private BariUser bariuser; Constructor public BasePage() { PropertyModel errormessagemodel = new PropertyModel(this, "errormessage"); add(new Label("error", errormessagemodel)); add(new StyleSheetReference("stylesheet", BasePage.class, "style.css")); add(new Link("createnew") public void onclick() { Page page = new CreateNew(bariUser); setresponsepage(page); ); add(new Link("overview") public void onclick() { Page page = new Overview(bariUser, Type.ERROR, "Alle"); setresponsepage(page); ); add(new Link("about") public void onclick() { Page page = new About(); setresponsepage(page); ); Get BaRI user. public BariUser getbariuser() { return bariuser; Set BaRI user. public void setbariuser(bariuser bariuser) { this.bariuser = bariuser; 19

20 Returns an error message public String geterrormessage() { return errormessage; Set error message. public void seterrormessage(string errormessage) { this.errormessage = errormessage; About.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title></title> </head> <body> <wicket:extend> <fieldset> <legend>om BaRI</legend> <p>bari står for <b>b</b>ugs <b>a</b>nd <b>r</b>equest <b>i</b>nterceptor</p> <p>programmet er udviklet i forbindelse med faget Web og Server programmering, som er et fag under IT-Diplomuddannelsen.</p> <p>programmet er udviklet af Jan Schrøder Hansen, efteråret 2009.</p> <p> <a href="mailto:jan.sch.hansen@gmail.com"> jan.sch.hansen@gmail.com</a></p> </fieldset> <fieldset> <legend>måling af kodekvalitet - What the fuck per minute</legend> <img wicket:id="wtfm"/> </fieldset> </wicket:extend> </body> </html> About.java package dk.jsh.itdiplom.wsp.bari.wicket; import org.apache.wicket.markup.html.image.image; About Jan S. Hansen public class About extends BasePage { public About() { add(new Image("wtfm", "wtfm.jpg")); CreateNew.html <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " <html xmlns:wicket=" <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title></title> 20

21 <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <wicket:extend> <fieldset> <legend>opret</legend> <form action="#" wicket:id="form"> <table align="center" border="0"> <tbody> <td style="width:120px">overskrift:</td> <td> <input wicket:id="title" type="text" name="" value="" size="50" /> </td> <td>type:</td> <td><select wicket:id="type" name=""> <option>nyt ønske</option> <option>fejl</option> </select></td> <td>oprettet af:</td> <td> <input wicket:id="user" type="text" name="" value="" size="50" /> </td> <td>beskrivelse:</td> <td> </td> <td colspan="2"> <textarea wicket:id="description" name="" rows="5" cols="80"> </textarea> </td> <td colspan="2"> <div style="float:right"> <input wicket:id="cancel" type="button" value="fortryd" /> <input wicket:id="save" type="submit" value="gem" /> </div> </td> </tbody> </table> </form> </fieldset> </wicket:extend> </body> </html> CreateNew.java package dk.jsh.itdiplom.wsp.bari.wicket; import dk.jsh.itdiplom.wsp.bari.bussiness.baricasebusiness; import dk.jsh.itdiplom.wsp.bari.domain.baricase; import dk.jsh.itdiplom.wsp.bari.domain.bariuser; import dk.jsh.itdiplom.wsp.bari.domain.constants.casestatus; import dk.jsh.itdiplom.wsp.bari.domain.constants.devstatus; import dk.jsh.itdiplom.wsp.bari.domain.constants.type; import java.util.arraylist; import java.util.date; import java.util.list; import org.apache.wicket.attributemodifier; import org.apache.wicket.markup.html.form.button; import org.apache.wicket.markup.html.form.dropdownchoice; import org.apache.wicket.markup.html.form.form; import org.apache.wicket.markup.html.form.textarea; import org.apache.wicket.markup.html.form.textfield; import org.apache.wicket.markup.html.link.link; import org.apache.wicket.model.model; 21

22 Create new BariCase Jan S. Hansen public final class CreateNew extends BasePage { private TextField<String> title; private DropDownChoice<String> type; private TextField<String> user; private TextArea<String> description; bariuser A BaRI user. public CreateNew(BariUser bariuser) { //Add a form as an inner class. Form form = new Form("form") { //Handles required fields protected void onerror() { List<String> emptyfields = new ArrayList<String>(); if (!title.checkrequired()) { emptyfields.add("overskrift"); title.add(new AttributeModifier("style", true, new Model("border-color:red;"))); else { title.add(new AttributeModifier("style", true, new Model("border-color:default;"))); if (!type.checkrequired()) { emptyfields.add("type"); type.add(new AttributeModifier("style", true, new Model("border-color:red;"))); else { type.add(new AttributeModifier("style", true, new Model("border-color:default;"))); if (!user.checkrequired()) { emptyfields.add("oprettet af"); user.add(new AttributeModifier("style", true, new Model("border-color:red;"))); else { user.add(new AttributeModifier("style", true, new Model("border-color:default;"))); if (!description.checkrequired()) { emptyfields.add("beskrivelse"); description.add(new AttributeModifier("style", true, new Model("border-color:red;"))); else { description.add(new AttributeModifier("style", true, new Model("border-color:defalut;"))); StringBuilder errormessage = new StringBuilder(); if (emptyfields.size() == 1) { errormessage.append("feltet "); errormessage.append("'").append(emptyfields.get(0)).append("'"); else { errormessage.append("felterne "); int fieldcounter = 1; for (String field : emptyfields) { errormessage.append("'").append(field).append("'"); if (fieldcounter < emptyfields.size() -1) { errormessage.append(", "); if (fieldcounter == emptyfields.size() -1) { errormessage.append(" og "); 22

23 fieldcounter++; errormessage.append(" skal udfyldes."); seterrormessage(errormessage.tostring()); ; add(form); //Add fields to the form. title = new TextField("title", new Model("")); title.setrequired(true); form.add(title); type = new DropDownChoice("type", new Model(Type.ERROR.getDescription()), Type.getDescriptions()); type.setrequired(true); form.add(type); user = new TextField("user", new Model("")); user.setrequired(true); form.add(user); description = new TextArea("description", new Model("")); description.setrequired(true); form.add(description); //Add buttons to the form. form.add(new Link("cancel") public void onclick() { setresponsepage(overview.class); ); form.add(new Button("save") public void onsubmit() { BariCase baricase = new BariCase( title.getmodelobject(), Type.getType(type.getModelObject()), user.getmodelobject(), new Date(), null, CaseStatus.NEW, DevStatus.NOTSTARTED, description.getmodelobject(), null); BariCaseBusiness.saveNew(bariCase); setresponsepage(overview.class); ); Discussion.html <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " <html xmlns:wicket=" <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>discussion</title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <wicket:extend> <fieldset> <legend>diskussion</legend> <table align="center" border="0"> <tbody> <td colspan="2"> <b><span wicket:id="type">fejl</span>: <span wicket:id="title">overskrift</span></b> </td> <td colspan="2"> 23

24 <textarea wicket:id="log" name="" rows="20" cols="90" readonly="readonly"> </textarea> </td> </tbody> </table> <form action="#" wicket:id="form"> <table align="center" border="0"> <tbody> <td colspan="2"> <b>nyt indlæg:</b> </td> <td style="width:120px">bruger:</td> <td> <input wicket:id="user" type="text" name="" value="" size="50" /> </td> <td colspan="2">indlæg:</td> <td colspan="2"> <textarea wicket:id="message" name="" rows="5" cols="80"> </textarea> </td> <td colspan="2" > <a href="#" wicket:id="goback">tilbage</a> <div style="float:right"> <input wicket:id="save" type="submit" value="gem nyt indlæg" /> </div> </td> </tbody> </table> </form> </fieldset> </wicket:extend> </body> </html> Discussion.java package dk.jsh.itdiplom.wsp.bari.wicket; import dk.jsh.itdiplom.wsp.bari.bussiness.discussionmessagebusiness; import dk.jsh.itdiplom.wsp.bari.domain.baricase; import dk.jsh.itdiplom.wsp.bari.domain.discussionmessage; import java.util.arraylist; import java.util.date; import java.util.list; import org.apache.wicket.attributemodifier; import org.apache.wicket.page; import org.apache.wicket.markup.html.basic.label; import org.apache.wicket.markup.html.form.button; import org.apache.wicket.markup.html.form.form; import org.apache.wicket.markup.html.form.textarea; import org.apache.wicket.markup.html.form.textfield; import org.apache.wicket.markup.html.link.link; import org.apache.wicket.model.model; Discussion Jan S. Hansen public final class Discussion extends BasePage { 24

25 private TextField<String> user; private TextArea<String> message; baricase A BaRI user. public Discussion(final BariCase baricase) { add(new Label("type", new Model(bariCase.getType().getDescription()))); add(new Label("title", new Model(bariCase.getTitle()))); //Get all discussion messages and build a discussion log. List<DiscussionMessage> discussionmessages = DiscussionMessageBusiness.getAllDiscussionMessages(bariCase); if (discussionmessages.size() > 0) { StringBuilder log = new StringBuilder(); for (DiscussionMessage discussionmessage : discussionmessages) { log.append(standarddatetimeformat.format( discussionmessage.getcreated())); log.append(" af "); log.append(discussionmessage.getbariuser()); log.append(":\n"); log.append(discussionmessage.getmessage()); log.append("\n\n"); add(new TextArea("log", new Model(log.toString()))); else { add(new TextArea("log", new Model("Der er ingen indlã g."))); //Create and add a form Form form = new Form("form") { //Handles required fields protected void onerror() { List<String> emptyfields = new ArrayList<String>(); if (!user.checkrequired()) { emptyfields.add("bruger"); user.add(new AttributeModifier("style", true, new Model("border-color:red;"))); else { user.add(new AttributeModifier("style", true, new Model("border-color:default;"))); if (!message.checkrequired()) { emptyfields.add("indlã g"); message.add(new AttributeModifier("style", true, new Model("border-color:red;"))); else { message.add(new AttributeModifier("style", true, new Model("border-color:default;"))); StringBuilder errormessage = new StringBuilder(); if (emptyfields.size() == 1) { errormessage.append("feltet "); errormessage.append("'").append(emptyfields.get(0)).append("'"); else { errormessage.append("felterne "); int fieldcounter = 1; for (String field : emptyfields) { errormessage.append("'").append(field).append("'"); if (fieldcounter < emptyfields.size() -1) { errormessage.append(", "); if (fieldcounter == emptyfields.size() -1) { errormessage.append(" og "); fieldcounter++; 25

26 errormessage.append(" skal udfyldes."); seterrormessage(errormessage.tostring()); ; add(form); //Add fields to the form. user = new TextField("user", new Model("")); user.setrequired(true); form.add(user); message = new TextArea("message", new Model("")); message.setrequired(true); form.add(message); //Add links and buttons to the form. form.add(new Link("goBack") public void onclick() { Page page = new Update(bariCase); setresponsepage(page); ); form.add(new Button("save") public void onsubmit() { DiscussionMessage discussionmessage = new DiscussionMessage( baricase, new Date(), user.getmodelobject(), message.getmodelobject()); DiscussionMessageBusiness.saveNew(discussionMessage); Page page = new Discussion(bariCase); setresponsepage(page); ); Overview.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title></title> </head> <body> <wicket:extend> <fieldset> <legend>oversigt</legend> <form action="#" wicket:id="form"> Type: <select wicket:id="type" name=""> <option>nyt à nske</option> <option>fejl</option> </select> Status: <select wicket:id="status" name=""> <option>alle</option> <option>ny</option> <option>under behandling</option> <option>godkendt</option> <option>afvist</option> </select> <input style="float:right" wicket:id="search" type="submit" value="søg" /> </form> <table class="pageablelistview" border="0" cellspacing="0" width="100%"> <th>overskrift</th> <th>oprettet</th> <th>afsluttet</th> <th>status</th> <th>udvikling</th> <th> </th> 26

27 <tr wicket:id="pageable"> <td><span wicket:id="title">[title]</span></td> <td><span wicket:id="created">[created]</span></td> <td><span wicket:id="finished">[finished]</span></td> <td><span wicket:id="casestatus">[casestatus]</span></td> <td><span wicket:id="devstatus">[devstatus]</span></td> <td><a href="#" wicket:id="action">vis</a></td> </table> <div style="float:right"> <span wicket:id="navigator">[dataview navigator]</span> </div> </fieldset> </wicket:extend> </body> </html> Overview.java package dk.jsh.itdiplom.wsp.bari.wicket; import dk.jsh.itdiplom.wsp.bari.bussiness.baricasebusiness; import dk.jsh.itdiplom.wsp.bari.domain.baricase; import dk.jsh.itdiplom.wsp.bari.domain.bariuser; import dk.jsh.itdiplom.wsp.bari.domain.constants.casestatus; import dk.jsh.itdiplom.wsp.bari.domain.constants.type; import java.util.linkedlist; import java.util.list; import org.apache.wicket.attributemodifier; import org.apache.wicket.page; import org.apache.wicket.markup.html.basic.label; import org.apache.wicket.markup.html.form.button; import org.apache.wicket.markup.html.form.dropdownchoice; import org.apache.wicket.markup.html.form.form; import org.apache.wicket.markup.html.link.link; import org.apache.wicket.markup.html.list.listitem; import org.apache.wicket.markup.html.list.pageablelistview; import org.apache.wicket.markup.html.navigation.paging.pagingnavigator; import org.apache.wicket.model.abstractreadonlymodel; import org.apache.wicket.model.model; Overview page for all Jan S. Hansen public final class Overview extends BasePage { private DropDownChoice<String> dropdownchoicetype; private DropDownChoice<String> statusdownchoicetype; //TODO: Should be deleted after autentication is implemented. public Overview() { this(new BariUser("login", "password", "fullname", " "), Type.ERROR, "Alle"); bariuser A BaRI type Type used as default on overview status Status uses as default on overview page. public Overview(final BariUser bariuser, Type type, String status) { setbariuser(bariuser); //Add search form. Form form = new Form("form"); add(form); dropdownchoicetype = new DropDownChoice("type", new Model(type.getDescription()), Type.getDescriptions()); form.add(dropdownchoicetype); LinkedList<String> statuslist = new LinkedList<String>(CaseStatus.getDescriptions()); 27

28 statuslist.addfirst("alle"); statusdownchoicetype = new DropDownChoice("status", new Model(status), statuslist); form.add(statusdownchoicetype); form.add(new Button("search") public void onsubmit() { Page page = new Overview(bariUser, Type.getType(dropDownChoiceType.getModelObject()), statusdownchoicetype.getmodelobject()); setresponsepage(page); ); //Add table with search results. CaseStatus cs = null; if (!"Alle".equals(statusDownChoiceType.getModelObject())) { cs = CaseStatus.getCaseStatus(statusDownChoiceType.getModelObject()); List<BariCase> baricases = BariCaseBusiness.getAllBariCases(type, cs); PageableListView pageablelistview = new PageableListView("pageable", baricases, 10) protected void populateitem(final ListItem item) { final BariCase baricase = (BariCase) item.getmodelobject(); item.add(new Label("title", baricase.gettitle())); item.add(new Label("created", standarddatetimeformat.format(baricase.getcreated()))); item.add(new Label("finished", baricase.getfinished() == null? "" :standarddatetimeformat.format(baricase.getfinished()))); item.add(new Label("casestatus", baricase.getcasestatus().getdescription())); item.add(new Label("devstatus", baricase.getdevstatus().getdescription())); item.add(new Link("action") public void onclick() { Page page = new Update(bariCase); setresponsepage(page); ); item.add(new AttributeModifier("class", true, new AbstractReadOnlyModel<String>() public String getobject() { return (item.getindex() % 2 == 1)? "even" : "odd"; )); ; add(pageablelistview); add(new PagingNavigator("navigator", pageablelistview)); Update.html <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " <html xmlns:wicket=" <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>update</title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <wicket:extend> <fieldset> <legend>vis/opdater</legend> <form action="#" wicket:id="form"> <table align="center" border="0"> 28

29 <tbody> <td style="width:120px">overskrift:</td> <td><input wicket:id="title" type="text" name="" value="" size="50" /></td> <td>type:</td> <td><select wicket:id="type" name=""> <option>nyt ønske</option> <option>fejl</option> </select></td> <td>oprettet af:</td> <td><input wicket:id="user" type="text" name="" value="" size="50" disabled="true"/></td> <td>oprettet den:</td> <td><input wicket:id="created" type="text" name="" value="" size="16" disabled="true" /></td> <td>afsluttet den:</td> <td><input wicket:id="finished" type="text" name="" value="" size="16" disabled="true"/></td> <td>sag status:</td> <td><select wicket:id="casestatus" name=""> <option>ny</option> <option>under behandling</option> <option>godkendt</option> <option>afvist</option> </select></td> <td>udviklings status:</td> <td><select wicket:id="devstatus" name=""> <option>ikke startet</option> <option>igang</option> <option>klar til test</option> <option>i produktion</option> </select></td> <td>beskrivelse:</td> <td> </td> <td colspan="2"><textarea wicket:id="description" name="" rows="5" cols="80"> </textarea></td> <td>konklusion:</td> <td> </td> <td colspan="2"><textarea wicket:id="conclusion" name="" rows="5" cols="80"> </textarea></td> <td colspan="2"> <a href="#" wicket:id="showdiscussion">gå til diskussion</a> <div style="float:right"> <input wicket:id="cancel" type="button" value="fortryd" /> <input wicket:id="delete" type="button" value="slet" /> <input wicket:id="save" type="submit" value="gem" /> </div> </td> </tbody> </table> 29

30 </form> </fieldset> </wicket:extend> </body> </html> Update.java package dk.jsh.itdiplom.wsp.bari.wicket; import dk.jsh.itdiplom.wsp.bari.bussiness.baricasebusiness; import dk.jsh.itdiplom.wsp.bari.domain.baricase; import dk.jsh.itdiplom.wsp.bari.domain.constants.casestatus; import dk.jsh.itdiplom.wsp.bari.domain.constants.devstatus; import dk.jsh.itdiplom.wsp.bari.domain.constants.type; import java.util.arraylist; import java.util.list; import org.apache.wicket.attributemodifier; import org.apache.wicket.page; import org.apache.wicket.markup.html.form.button; import org.apache.wicket.markup.html.form.dropdownchoice; import org.apache.wicket.markup.html.form.form; import org.apache.wicket.markup.html.form.textarea; import org.apache.wicket.markup.html.form.textfield; import org.apache.wicket.markup.html.link.link; import org.apache.wicket.model.model; import org.hibernate.staleobjectstateexception; BariCase update Jan S. Hansen public final class Update extends BasePage { private TextField<String> title; private DropDownChoice<String> type; private DropDownChoice<String> casestatus; private DropDownChoice<String> devstatus; private TextArea<String> description; private TextArea<String> conclusion; baricase A BaRI user. public Update(final BariCase baricase) { //Add a form. Form form = new Form("form") { //Handle required fields protected void onerror() { List<String> emptyfields = new ArrayList<String>(); if (!title.checkrequired()) { emptyfields.add("overskrift"); title.add(new AttributeModifier("style", true, new Model("border-color:red;"))); else { title.add(new AttributeModifier("style", true, new Model("border-color:default;"))); if (!type.checkrequired()) { emptyfields.add("type"); type.add(new AttributeModifier("style", true, new Model("border-color:red;"))); else { type.add(new AttributeModifier("style", true, new Model("border-color:default;"))); if (!description.checkrequired()) { emptyfields.add("beskrivelse"); 30

31 description.add(new AttributeModifier("style", true, new Model("border-color:red;"))); else { description.add(new AttributeModifier("style", true, new Model("border-color:defalut;"))); StringBuilder errormessage = new StringBuilder(); if (emptyfields.size() == 1) { errormessage.append("feltet "); errormessage.append("'").append(emptyfields.get(0)).append("'"); else { errormessage.append("felterne "); int fieldcounter = 1; for (String field : emptyfields) { errormessage.append("'").append(field).append("'"); if (fieldcounter < emptyfields.size() -1) { errormessage.append(", "); if (fieldcounter == emptyfields.size() -1) { errormessage.append(" og "); fieldcounter++; errormessage.append(" skal udfyldes."); seterrormessage(errormessage.tostring()); ; add(form); //Add form fields. title = new TextField("title", new Model(bariCase.getTitle())); title.setrequired(true); form.add(title); type = new DropDownChoice("type", new Model(bariCase.getType().getDescription()), Type.getDescriptions()); type.setrequired(true); form.add(type); form.add(new TextField("user", new Model(bariCase.getBariUser()))); form.add(new TextField("created", new Model(standardDateTimeFormat.format(bariCase.getCreated())))); form.add(new TextField("finished", new Model(bariCase.getFinished() == null? "" :standarddatetimeformat.format(baricase.getfinished())))); casestatus = new DropDownChoice("caseStatus", new Model(bariCase.getCaseStatus().getDescription()), CaseStatus.getDescriptions()); casestatus.setrequired(true); form.add(casestatus); devstatus = new DropDownChoice("devStatus", new Model(bariCase.getDevStatus().getDescription()), DevStatus.getDescriptions()); devstatus.setrequired(true); form.add(devstatus); description = new TextArea("description", new Model(bariCase.getDescription())) ; description.setrequired(true); form.add(description); conclusion = new TextArea("conclusion", new Model(bariCase.getConclusion())); form.add(conclusion); //Add form links and buttons form.add(new Link("showDiscussion") public void onclick() { Page page = new Discussion(bariCase); setresponsepage(page); ); form.add(new Link("cancel") { 31

32 public void onclick() { setresponsepage(overview.class); Button savebutton = new Button("save") public void onsubmit() { baricase.settitle(title.getmodelobject()); baricase.settype(type.gettype(type.getmodelobject())); baricase.setcasestatus( CaseStatus.getCaseStatus(caseStatus.getModelObject())); baricase.setdevstatus( DevStatus.getDevStatus(devStatus.getModelObject())); baricase.setdescription(description.getmodelobject()); baricase.setconclusion(conclusion.getmodelobject()); try { BariCaseBusiness.update(bariCase); setresponsepage(overview.class); catch (StaleObjectStateException sose) { seterrormessage("sagen kan ikke gemmes, " + "da den er rettet af en anden!"); ; form.add(savebutton); Link deletelink = new Link("delete") public void onclick() { BariCaseBusiness.delete(bariCase); setresponsepage(overview.class); ; deletelink.add(new JS_EventConfirmation("onclick", "Er du sikker pã " + " at du vil slette?")); form.add(deletelink); //Disable fields and save button, if case is finished. if (baricase.getfinished()!= null) { title.setenabled(false); type.setenabled(false); casestatus.setenabled(false); devstatus.setenabled(false); description.setenabled(false); conclusion.setenabled(false); savebutton.setenabled(false); Inner class that adds a javascript confirm dialog to a attribute. private class JS_EventConfirmation extends AttributeModifier { public JS_EventConfirmation(String event, String msg) { super(event, true, new protected String newvalue(final String currentvalue, final String replacementvalue) { String result = "if (confirm('" + replacementvalue + "')) "; if (currentvalue!= null) { result += currentvalue + ";"; return result; 32

33 style.css body { margin:0; padding:0; font-family:times; div { margin:0; padding:0; / Remove space between elements #container { margin-left:auto; margin-right:auto; / Center block level content width:800px; #header { text-align: center; / Center inline Content - Don't work in IE' width:100%; #content { width:100%; padding-left:10px; padding-right:10px; #error { text-align: center; color: red; #main { width:100%; / Table layout table.pageablelistview { margin-bottom: 10px; border-bottom: 1px solid; table.pageablelistview caption { text-align: left; table.pageablelistview tr { padding-top: 2px; padding-bottom: 2px; table.pageablelistview trtable.pageablelistview caption { text-align: left;.even { background-color: #ececec; table.pageablelistview tr.odd { background-color: #fff; table.pageablelistview tr td { padding-left: 8px; padding-right: 30px; table.pageablelistview tr th { color: black; padding-top: 3px; padding-bottom: 3px; padding-left: 8px; padding-right: 30px; background-color: #ececec; border-bottom: 1px solid; border-top: 1px solid; text-align: left; white-space: nowrap; vertical-align: middle; table.pageablelistview tr th { background-position: right; background-repeat:no-repeat; table.pageablelistview tr th a { 33

34 font-weight: normal; PAKKE DK.JSH.ITDIPLOM.WSP.BARI.BUSSINESS BariCaseBusiness.java package dk.jsh.itdiplom.wsp.bari.bussiness; import dk.jsh.itdiplom.wsp.bari.domain.baricase; import dk.jsh.itdiplom.wsp.bari.domain.constants.casestatus; import dk.jsh.itdiplom.wsp.bari.domain.constants.type; import dk.jsh.itdiplom.wsp.bari.util.hibernateutil; import java.util.arraylist; import java.util.date; import java.util.list; import org.hibernate.query; import org.hibernate.session; import org.hibernate.transaction; Business metods for Jan S. Hansen public class BariCaseBusiness { Create new baricase BariCase public static void savenew(baricase baricase) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction tx = session.begintransaction(); session.save(baricase); tx.commit(); session.close(); Get all BariCase type type of BariCases to casestatus type of casestatus to a List of BariCase objects. public static List<BariCase> getallbaricases(type type, CaseStatus casestatus) { List<BariCase> baricases = new ArrayList<BariCase>(); Session session = HibernateUtil.getSessionFactory().openSession(); String hql = "select baricase from " + "dk.jsh.itdiplom.wsp.bari.domain.baricase baricase " + "where baricase.type = :type "; if (casestatus!= null) { hql += "and baricase.casestatus = :casestatus "; hql += "order by baricase.created desc"; Query query = session.createquery(hql); query.setstring("type", type.tostring()); if (casestatus!= null) { query.setstring("casestatus", casestatus.tostring()); baricases = query.list(); session.close(); return baricases; Update a baricase BariCase public static void update(baricase baricase) { Session session = HibernateUtil.getSessionFactory().openSession(); 34

35 try { Transaction tx = session.begintransaction(); if (baricase.getcasestatus().equals(casestatus.done)) { baricase.setfinished(new Date()); session.update(baricase); tx.commit(); finally { session.close(); Delete a baricase and all discussion baricase BariCase public static void delete(baricase baricase) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction tx = session.begintransaction(); String sql = "delete from DiscussionMessage where " + "baricase_id = :id"; Query query = session.createsqlquery(sql); query.setstring("id", baricase.getid().tostring()); query.executeupdate(); session.delete(baricase); tx.commit(); session.close(); DiscussionMessageBusiness.java package dk.jsh.itdiplom.wsp.bari.bussiness; import dk.jsh.itdiplom.wsp.bari.domain.baricase; import dk.jsh.itdiplom.wsp.bari.domain.discussionmessage; import dk.jsh.itdiplom.wsp.bari.util.hibernateutil; import java.util.arraylist; import java.util.list; import org.hibernate.query; import org.hibernate.session; import org.hibernate.transaction; Business metods for Jan S. Hansen public class DiscussionMessageBusiness { Create new discussionmessage DiscussionMessage public static void savenew(discussionmessage discussionmessage) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction tx = session.begintransaction(); session.save(discussionmessage); tx.commit(); session.close(); Get all DiscussionMessages for a specific baricase a List of DiscussionMessage objects. public static List<DiscussionMessage> getalldiscussionmessages( BariCase baricase) { List<DiscussionMessage> discussionmessages = new ArrayList<DiscussionMessage>(); 35

36 Session session = HibernateUtil.getSessionFactory().openSession(); String hql = "select discussionmessage from " + "dk.jsh.itdiplom.wsp.bari.domain.discussionmessage discussionmessage + "where baricase.id = :id " + "order by discussionmessage.created"; Query query = session.createquery(hql); query.setstring("id", baricase.getid().tostring()); discussionmessages = query.list(); session.close(); return discussionmessages; PAKKE DK.JSH.ITDIPLOM.WSP.BARI.DOMAIN BariCase.java package dk.jsh.itdiplom.wsp.bari.domain; import dk.jsh.itdiplom.wsp.bari.domain.constants.casestatus; import dk.jsh.itdiplom.wsp.bari.domain.constants.devstatus; import dk.jsh.itdiplom.wsp.bari.domain.constants.type; import java.io.serializable; import java.util.date; import javax.persistence.; BariCase entity Jan S. public class BariCase implements Serializable { private static final long serialversionuid = GenerationType.IDENTITY) protected Long protected Integer version; protected String protected Type type; protected String protected Date protected Date protected CaseStatus protected DevStatus devstatus; protected String description; protected String conclusion; public BariCase() { public BariCase(String title, Type type, String bariuser, Date created, Date finished, CaseStatus casestatus, DevStatus devstatus, String description, String conclusion) { this.title = title; this.type = type; this.bariuser = bariuser; this.created = created; this.finished = finished; this.casestatus = casestatus; this.devstatus = devstatus; this.description = description; this.conclusion = conclusion; public Long getid() { 36

37 return id; public void setid(long id) { this.id = id; public Integer getversion() { return version; public String gettitle() { return title; public void settitle(string title) { this.title = title; public Type gettype() { return type; public void settype(type type) { this.type = type; public String getbariuser() { return bariuser; public void setbariuser(string bariuser) { this.bariuser = bariuser; public Date getcreated() { return created; public void setcreated(date created) { this.created = created; public Date getfinished() { return finished; public void setfinished(date finished) { this.finished = finished; public CaseStatus getcasestatus() { return casestatus; public void setcasestatus(casestatus casestatus) { this.casestatus = casestatus; public DevStatus getdevstatus() { return devstatus; public void setdevstatus(devstatus devstatus) { this.devstatus = devstatus; public String getdescription() { return description; public void setdescription(string description) { this.description = description; public String getconclusion() { 37

38 return conclusion; public void setconclusion(string conclusion) { this.conclusion = conclusion; BariUser.java package dk.jsh.itdiplom.wsp.bari.domain; import java.io.serializable; BariUser entity Jan S. Hansen public class BariUser implements Serializable { private static final long serialversionuid = 1L; private String login; private String password; private String fullname; private String ; public BariUser() { public BariUser(String login, String password, String fullname, String ) { this.login = login; this.password = password; this.fullname = fullname; this. = ; public String get () { return ; public void set (string ) { this. = ; public String getfullname() { return fullname; public void setfullname(string fullname) { this.fullname = fullname; public String getlogin() { return login; public void setlogin(string login) { this.login = login; public String getpassword() { return password; public void setpassword(string password) { this.password = password; 38

39 DiscussionMessage.java package dk.jsh.itdiplom.wsp.bari.domain; import java.io.serializable; import java.util.date; import javax.persistence.; Discussion message entity Jan S. public class DiscussionMessage implements Serializable { private static final long serialversionuid = GenerationType.IDENTITY) protected Long protected Integer protected BariCase protected Date created; protected String bariuser; protected String message; public DiscussionMessage() { public DiscussionMessage(BariCase baricase, Date created, String bariuser, String message) { this.baricase = baricase; this.created = created; this.bariuser = bariuser; this.message = message; public String getbariuser() { return bariuser; public void setbariuser(string bariuser) { this.bariuser = bariuser; public Long getid() { return id; public void setid(long id) { this.id = id; public Integer getversion() { return version; public void setversion(integer version) { this.version = version; public BariCase getbaricase() { return baricase; public void setbaricase(baricase baricase) { this.baricase = baricase; public Date getcreated() { return created; 39

40 public void setcreated(date created) { this.created = created; public String getmessage() { return message; public void setmessage(string message) { this.message = message; Constants.java package dk.jsh.itdiplom.wsp.bari.domain; import java.util.arraylist; import java.util.list; Constants and Jan S. Hansen public class Constants { private Constants() { BaRI case type: REQUEST, ERROR. public enum Type { REQUEST("Nyt à nske"), ERROR("Fejl"); private String description; Type(String description) { this.description = description; public String getdescription() { return description; public static List<String> getdescriptions() { List<String> descriptions = new ArrayList<String>(); descriptions.add(error.description); descriptions.add(request.description); return descriptions; public static Type gettype(string description) { if (REQUEST.description.equals(description)) return REQUEST; return ERROR; Case status: NEW, CONSIDER, APPROVED, REJECTED and DONE. public enum CaseStatus { NEW("Ny"), CONSIDER("Behandles"), APPROVED("Godkendt"), REJECTED("Afvist"), DONE("Afsluttet"); private String description; CaseStatus(String description) { this.description = description; 40

41 public String getdescription() { return description; public static List<String> getdescriptions() { List<String> descriptions = new ArrayList<String>(); descriptions.add(new.description); descriptions.add(consider.description); descriptions.add(approved.description); descriptions.add(rejected.description); descriptions.add(done.description); return descriptions; public static CaseStatus getcasestatus(string description) { if (NEW.description.equals(description)) return NEW; if (CONSIDER.description.equals(description)) return CONSIDER; if (APPROVED.description.equals(description)) return APPROVED; if (DONE.description.equals(description)) return DONE; return REJECTED; Developer status: NOTSTARTED, STARTED, READYTOTEST, TESTED and INPRODUCTION. public enum DevStatus { NOTSTARTED("Ej begyndt"), STARTED("I gang"), READYTOTEST("Klar til test"), TESTED("Testet"), INPRODUCTION("I prod."); private String description; DevStatus(String description) { this.description = description; public String getdescription() { return description; public static List<String> getdescriptions() { List<String> descriptions = new ArrayList<String>(); descriptions.add(notstarted.description); descriptions.add(started.description); descriptions.add(readytotest.description); descriptions.add(tested.description); descriptions.add(inproduction.description); return descriptions; public static DevStatus getdevstatus(string description) { if (NOTSTARTED.description.equals(description)) return NOTSTARTED; if (STARTED.description.equals(description)) return STARTED; if (READYTOTEST.description.equals(description)) return READYTOTEST; if (TESTED.description.equals(description)) return TESTED; return INPRODUCTION; PAKKE DK.JSH.ITDIPLOM.WSP.BARI.UTIL HibernateUtil.java package dk.jsh.itdiplom.wsp.bari.util; import org.hibernate.; import org.hibernate.cfg.; 41

42 Hibernate session Jan S. Hansen public class HibernateUtil { private static SessionFactory sessionfactory; static { try { sessionfactory = new AnnotationConfiguration().configure().buildSessionFactory(); catch (Throwable ex) { throw new ExceptionInInitializerError(ex); Get a Hibernate session a SessionFactory public static SessionFactory getsessionfactory() { return sessionfactory; Close SessionFactory. public static void shutdown() { getsessionfactory().close(); PAKKE DK.JSH.ITDIPLOM.WSP.BARI.WICKET.TEST CreateNewTest.java package dk.jsh.itdiplom.wsp.bari.wicket.test; import dk.jsh.itdiplom.wsp.bari.domain.bariuser; import dk.jsh.itdiplom.wsp.bari.domain.constants; import dk.jsh.itdiplom.wsp.bari.wicket.createnew; import org.apache.wicket.util.tester.wickettester; import org.junit.test; import static org.junit.assert.; JUnit test for CreateNew Jan S. Hansen public class CreateNewTest { Test that required fields must be filled public void TestRequiredFields() { WicketTester wt = new WicketTester(); BariUser bariuser = new BariUser("login", "password", "Bruger navn", " "); CreateNew createnew = new CreateNew(bariUser); wt.startpage(createnew); wt.assertlabel("error", ""); //No errors yet wt.setparameterfornextrequest("form:title", ""); wt.setparameterfornextrequest("form:user", ""); wt.setparameterfornextrequest("form:description", ""); wt.setparameterfornextrequest("form:type", Constants.Type.ERROR); wt.submitform("form"); String error = wt.gettagbywicketid("error").getvalue(); asserttrue("title/overskrift should be part of the error message", error.contains("overskrift")); asserttrue("user/oprettet af should be part of the error message", error.contains("oprettet af")); asserttrue("descripten/beskrivelse should be part of the error message", 42

43 error.contains("beskrivelse")); 9.3. SQL TIL DANNELSE AF DATABASEN bari_dll.sql alter table DiscussionMessage drop constraint FKBC64A29FF02FEB14; drop table BariCase; drop table DiscussionMessage; create table BariCase ( id bigint not null generated always as identity, bariuser varchar(255), casestatus varchar(255), conclusion varchar(255), created timestamp, description varchar(255), devstatus varchar(255), finished timestamp, title varchar(255), type varchar(255), version integer, primary key (id) ); create table DiscussionMessage ( id bigint not null generated always as identity, bariuser varchar(255), created timestamp, message varchar(255), version integer, baricase_id bigint, primary key (id) ); alter table DiscussionMessage add constraint FKBC64A29FF02FEB14 foreign key (baricase_id) references BariCase; 9.4. KONFIGUTATIONSFILER Hibernate.cfg.xml <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" " <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.derbydialect</property> <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.clientdriver</property> <property name="hibernate.connection.url">jdbc:derby://localhost:1527/bari</property> <property name="hibernate.connection.username">bari</property> <property name="hibernate.connection.password">bari</property> <!-- Show and print nice SQL on stdout --> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <!-- List of annotated classes --> <mapping class="dk.jsh.itdiplom.wsp.bari.domain.baricase" /> <mapping class="dk.jsh.itdiplom.wsp.bari.domain.discussionmessage" /> </session-factory> 43

44 </hibernate-configuration> web.xml <?xml version="1.0" encoding="utf-8"?> <web-app version="2.5" xmlns=" xmlns:xsi=" xsi:schemalocation=" <filter> <filter-name>wicketapplication</filter-name> <filter-class>org.apache.wicket.protocol.http.wicketfilter</filter-class> <init-param> <param-name>applicationclassname</param-name> <param-value>dk.jsh.itdiplom.wsp.bari.wicket.application</param-value> </init-param> </filter> <filter-mapping> <filter-name>wicketapplication</filter-name> <url-pattern>/</url-pattern> </filter-mapping> <session-config><session-timeout> 30 </session-timeout></session-config> <welcome-file-list> <welcome-file/> </welcome-file-list> </web-app> 9.5. ANT TARGET TIL GENERERING AF DATABASESKEMA Følgende er indsat i NetBeans build.xml (Projekt fil). Som er et Ant target der udfra hibernatekonfigfilen og de domaineklasser denne peger på, kan genere et databaseskema. <taskdef name="hibernatetool" classname="org.hibernate.tool.ant.hibernatetooltask" classpathref="project.classpath"/> <target name="schemaexport"> <hibernatetool destdir="."> <classpath path="build/web/web-inf/classes" /> <annotationconfiguration configurationfile="src/java/hibernate.cfg.xml" /> <hbm2ddl drop="true" create="true" export="true" outputfilename="bari_ddl.sql" delimiter=";" format="true" /> </hibernatetool> </target> 44

45 9.6. EKSEMPLER PÅ UNIT TEST 9.7. INDHOLD PÅ VEDLAGTE CD Indholdet på den vedlagte CD er inddelt i følgende 3 kataloger: Løsning Indeholder java kode, htmlfiler m.m samt NetBeans projektfil. Program Indeholder en bari.war samt JavaDB skemafil til oprettelse af databasen. Rapport Indeholder denne rapport i Word 2007 format og diagrammer i Dia-format. 45

Databaseadgang fra Java

Databaseadgang fra Java Databaseadgang fra Java Grundlæggende Programmering med Projekt Peter Sestoft Fredag 2007-11-23 Relationsdatabasesystemer Der er mange databaseservere Microsoft Access del af Microsoft Office MySQL god,

Læs mere

IT-DIPLOMUDDANNELSEN AFGANGSPROJEKT AF JAN SCHRØDER HANSEN EFTERÅR/VINTER 2011

IT-DIPLOMUDDANNELSEN AFGANGSPROJEKT AF JAN SCHRØDER HANSEN EFTERÅR/VINTER 2011 IT-DIPLOMUDDANNELSEN AFGANGSPROJEKT AF JAN SCHRØDER HANSEN EFTERÅR/VINTER 2011 INDHOLD 1. Indledning... 3 2. Opgavebeskrivelse... 3 3. Krav... 5 3.1. Funktionelle krav... 5 3.2. Ikke funktionelle krav...

Læs mere

Web 2.0. World Wide Web (www)

Web 2.0. World Wide Web (www) Web 2.0 World Wide Web (www) I marts 1989 skrev Tim Berners-Lee et information udveksling program kaldt ENQUIRE. Da han arbejde i CERN, var han ikke tilfreds med kommunikationen, derfor videreudviklede

Læs mere

Projekt-studieweb. Om kommunikationsteorierne. Morten, Jacob, Kristian og Cihat

Projekt-studieweb. Om kommunikationsteorierne. Morten, Jacob, Kristian og Cihat Projekt-studieweb Om kommunikationsteorierne Morten, Jacob, Kristian og Cihat Gestaltlovene Loven om nærhed Loven om lukkethed Loven om lighed Loven om forbundethed Loven om fortsættelse Loven om figur

Læs mere

Design Diaries.

Design Diaries. Design Diaries http://blog.lykkeeilert.dk/ Patricia Gambula Larsen Patrick Lykke Eilert Ninette Andersen cph-pl130@cphbusiness.dk cph-pe58@cphbusiness.dk cph-na96@cphbusiness.dk INDHOLD Use case model

Læs mere

The Design Diaries Project 3 2. Semester. Blog om designprincipper

The Design Diaries Project 3 2. Semester. Blog om designprincipper The Design Diaries Project 3 2. Semester Blog om designprincipper By Lif Neergaard www.lifmediadesign.dk cph-ln175@cphbusiness.dk Mathias Larsen www.nefjam.dk cph-ml414@cphbusiness.dk Ida Christensen www.idamedia.dk

Læs mere

I profil-feltet kan imastra-kunder vælge om upload skal ske ligesom filerne var indsendt til mailboksen eller

I profil-feltet kan imastra-kunder vælge om upload skal ske ligesom filerne var indsendt til mailboksen eller Upload fil Upload fil skal ses som et alternativ til at indsende tællefiler vedhæftet til mails Upload fil kan være en hurtigere og mere håndholdt måde at få data ind i Mastra på. Man starter med via Gennemse

Læs mere

Aptana editor til MAC og Windows

Aptana editor til MAC og Windows 1 Aptana editor til MAC og Windows http://aptana.com/products/studio3/download For at downloade Mac versionen skal du klikke på : Customize Your Download og der efter klikke på MAC OS X. Indtast navn og

Læs mere

Indholdsfortegnelse Databaser og PHP... 3 Opgave... 4 Opgave... 5 Opgave... 6 Sidste opgave er en lille gæstebog... 7 Kilder og nyttige links:...

Indholdsfortegnelse Databaser og PHP... 3 Opgave... 4 Opgave... 5 Opgave... 6 Sidste opgave er en lille gæstebog... 7 Kilder og nyttige links:... Indholdsfortegnelse Databaser og PHP... 3 Opgave... 4 Opgave... 5 Opgave... 6 Sidste opgave er en lille gæstebog... 7 Kilder og nyttige links:... 9 Nogle HTML tags... 9 Databaser og PHP Når vi snakker

Læs mere

Oversigt HTML5 nye tags til sideopbygning

Oversigt HTML5 nye tags til sideopbygning HTML5 er udviklet af WHATWG Oversigt HTML5 nye tags til sideopbygning (Web Hypertext Application Technology Working Group) En

Læs mere

Nu skal vi især se på <font> og <center> samt centrering af hele siden på skærmen.

Nu skal vi især se på <font> og <center> samt centrering af hele siden på skærmen. Validering 4 Nu skal vi især se på og samt centrering af hele siden på skærmen. Det er i HTML ikke forbudt at bruge koden , men lad nu være alligevel, du får blot en masse valideringsproblemer.

Læs mere

Ordbøgerne.dk. Navne: Andreas Foldager og Rasmus Bjerring Pedersen Fag: IT B Lærer: Karl Bjarnason Afleveringsdato: 17-11-06.

Ordbøgerne.dk. Navne: Andreas Foldager og Rasmus Bjerring Pedersen Fag: IT B Lærer: Karl Bjarnason Afleveringsdato: 17-11-06. Ordbøgerne.dk Navne: Andreas Foldager og Rasmus Bjerring Pedersen Fag: IT B Lærer: Karl Bjarnason Afleveringsdato: 17-11-06 Side 1 af 35 Indholdsfortegnelse Indledning:...3 Design...4 Visuelt design:...4

Læs mere

Tredjepart webservices

Tredjepart webservices Tredjepart webservices 4. juni 2015 USS Dok. Klik her for at angive tekst. 1/12 Indholdsfortegnelse Introduktion... 3 Miljøer... 3 Adgang... 3 API kald... 4 GET: /authorizations... 4 Input 4 Output 4 Output

Læs mere

5. Billeder og logo til websitet er optimeret til web via Photoshop, så de fylder mindst muligt for at mindske indlæsningstiden for websitet.

5. Billeder og logo til websitet er optimeret til web via Photoshop, så de fylder mindst muligt for at mindske indlæsningstiden for websitet. GRAFISK WORKFLOW Grafisk workflow Beskrivelse Opgaven Design af website til Tipsbladet Fokus, som er noget, jeg selv har fundet på. Det er tænkt som et alternativ til Tipsbladet.dk, hvor der på Tipsbladet

Læs mere

PROJEKT 3. The Design Diaries. LINK TIL BLOG: Af Mikkel Borg Svendsen & Sebastian Frank MUL B

PROJEKT 3. The Design Diaries. LINK TIL BLOG:  Af Mikkel Borg Svendsen & Sebastian Frank MUL B PROJEKT 3 The Design Diaries LINK TIL BLOG: http://mbsgraphic.dk/blog/ Af Mikkel Borg Svendsen & Sebastian Frank MUL B 1 INDHOLDS- FORTEGNELSE HVEM ER BLOGGERNE? 3 USE CASE 4 ATTRIBUT TABEL 5 PHP CODE

Læs mere

Byg et website med Dreamweaver

Byg et website med Dreamweaver Byg et website med Dreamweaver I denne øvelse skal vi opbygge et website for Hotel Holiday i Dreamweaver. Det færdige site kan ses her: http://www.itu.dk/people/khhp/hotel_holidays/velkommen.html Øvelsen

Læs mere

IBM Network Station Manager. esuite 1.5 / NSM Integration. IBM Network Computer Division. tdc - 02/08/99 lotusnsm.prz Page 1

IBM Network Station Manager. esuite 1.5 / NSM Integration. IBM Network Computer Division. tdc - 02/08/99 lotusnsm.prz Page 1 IBM Network Station Manager esuite 1.5 / NSM Integration IBM Network Computer Division tdc - 02/08/99 lotusnsm.prz Page 1 New esuite Settings in NSM The Lotus esuite Workplace administration option is

Læs mere

TEKNISK DOKUMENTATION FAKTURA LAYOUT ABAQUE VERSION 2.0

TEKNISK DOKUMENTATION FAKTURA LAYOUT ABAQUE VERSION 2.0 TEKNISK DOKUMENTATION FAKTURA LAYOUT ABAQUE VERSION 2.0 INTRODUKTION... 3 SKABELON OPBYGNINGEN... 3 BYG DIN EGEN SKABELON... 3 INDSÆT FELTER... 3 INDSÆT VARELINJER... 3 FILNAVN... 4 LISTE OVER FELTER...

Læs mere

ØVELSE 11: TABLES & FORMS (Individuel)

ØVELSE 11: TABLES & FORMS (Individuel) ØVELSE 11: TABLES & FORMS (Individuel) 1. Målsætning I denne øvelse kommer du til at arbejde med to forskellige områder: Forms (formularer) og tables (tabeller) (kapitel 8+9 i LWD.) Du kommer blandt andet

Læs mere

GUIDE TIL OPRETTELSE AF SIDER OG INDHOLD I UMBRACO ONLINE BETJENING

GUIDE TIL OPRETTELSE AF SIDER OG INDHOLD I UMBRACO ONLINE BETJENING GUIDE TIL OPRETTELSE AF SIDER OG INDHOLD I UMBRACO ONLINE BETJENING DANSKE BEDEMÆND august 2014 v1.4 1 P a g e INDHOLDSFORTEGNELSE Adgang... 3 Overordnet om Umbraco... 4 Højreklik muligheder i oversigten...

Læs mere

Google App Engine. Google App Engine som platform. Claus Myglegaard Vagner og Jacob von Eyben

Google App Engine. Google App Engine som platform. Claus Myglegaard Vagner og Jacob von Eyben GoogleAppEngine GoogleAppEnginesomplatform ClausMyglegaardVagnerogJacobvonEyben Abstract CloudcomputingerenteknologidervinderfremidengenerelleITinfrastruktur. SocialemediersåsomLinkedIn,TwitterogFacebookharøgetbehovetfor

Læs mere

Nyhedsbrev april: spørgeskemaundersøgelse

Nyhedsbrev april: spørgeskemaundersøgelse #ChronoContact_Survey { margin-bottom: 10px; margin-left: 0px;.form_element { float: left; font-family: Arial,Helvetica,sans-serif; font-size: 12px; margin-bottom: 8px; margin-left: 0; margin-top: 8px;

Læs mere

Tech College Aalborg. ASP.NET Hjemmeside. Projekt Smart Zenior Home - Guide til ASP.NET hjemmeside med Visual Studio

Tech College Aalborg. ASP.NET Hjemmeside. Projekt Smart Zenior Home - Guide til ASP.NET hjemmeside med Visual Studio Tech College Aalborg ASP.NET Hjemmeside Projekt Smart Zenior Home - Guide til ASP.NET hjemmeside med Visual Studio Isabella Sihm Ziersen Indhold ASP.Net hjemmeside... 2 Visual Studio... 2 Brug af templates

Læs mere

Password-beskyttelse af visse filer

Password-beskyttelse af visse filer W EB DESIGN 101 K ODEORDSBESKYTTELSE A F VISSE FI LER Password-beskyttelse af visse filer P å et websted kan det være interessant kun at give en del af brugerskaren adgang til visse filer. Der er en mængde

Læs mere

Guide til oprettelse/redigering af events på bornholm.info

Guide til oprettelse/redigering af events på bornholm.info Guide til oprettelse/redigering af events på bornholm.info Trin Login Beskrivelse 1. Login på hjemmesiden: URL: http://bornholm.info/wp-admin/ Brugernavn: se mailen Adgangskode: se mailen Opret event 1.

Læs mere

Form og dens underlige box model

Form og dens underlige box model Denne guide er oprindeligt udgivet på Eksperten.dk Form og dens underlige box model Denne artikel handler om hvilke problemer man som webudvikler kan komme ud for, og hvordan man løser dem. Jeg kommer

Læs mere

PHP Quick Teknisk Ordbog

PHP Quick Teknisk Ordbog PHP Quick Teknisk Ordbog Af Daniel Pedersen PHP Quick Teknisk Ordbog 1 Indhold De mest brugte tekniske udtryk benyttet inden for web udvikling. Du vil kunne slå de enkelte ord op og læse om hvad de betyder,

Læs mere

JSP, Tomcat. Tutorial lavet af Jákup W. Hansen TSU semester 10.october 2007

JSP, Tomcat. Tutorial lavet af Jákup W. Hansen TSU semester 10.october 2007 JSP, Tomcat Tutorial lavet af Jákup W. Hansen TSU 2006 3.semester 10.october 2007 Hvad er JSP(Java Server Pages): Det er en teknik som er bygget ovenover Servlets teknikken, men fidusen er at det skal

Læs mere

Værktøjer fra værktøjskassen. Søren Breddam, Stevns Kommune

Værktøjer fra værktøjskassen. Søren Breddam, Stevns Kommune Værktøjer fra værktøjskassen Søren Breddam, Stevns Kommune sb@stevns.dk 1stevns kommune Mapbasic i Stevns Kommune Data Kørsel af planlagte opgaver, så data altid er opdaterede. Logfil til overvågning Dagligt

Læs mere

Efterlyst! Introduktion HTML & CSS. I dette projekt skal du lære, hvordan du laver din egen plakat. Arbejdsliste. Test dit Projekt.

Efterlyst! Introduktion HTML & CSS. I dette projekt skal du lære, hvordan du laver din egen plakat. Arbejdsliste. Test dit Projekt. HTML & CSS 1 Efterlyst! All Code Clubs must be registered. Registered clubs appear on the map at codeclubworld.org - if your club is not on the map then visit jumpto.cc/ccwreg to register your club. Introduktion

Læs mere

Web- og serverprogrammering

Web- og serverprogrammering Web- og serverprogrammering Introduktion til web- og serverprogrammering - dag 1 Overblik over WSP, eller: de 3+x sprog i webprogrammering (HTML, CSS, JavaScript, plus x serverside-sprog) Installation

Læs mere

Grafisk workflow. website til duckhead music

Grafisk workflow. website til duckhead music Grafisk workflow website til duckhead music Portfolio h1 Side 18 website til duckhead music Selvom jeg er hos et webbureau, så sidder jeg udelukkende med design, og er derfor ikke kommet til at kode endnu.

Læs mere

Mit grafiske workflow inkluderer:

Mit grafiske workflow inkluderer: GRAFISK WORKFLOW Opgave: Opgaven var at producere en bog og et website med temaet stilhistorie. Jeg har valgt at beskrive mit grafiske workflow i produktionen af websitet. Kravene var, at der skulle være

Læs mere

Kom i gang med SAS STPbaserede

Kom i gang med SAS STPbaserede make connections share ideas be inspired Kom i gang med SAS STPbaserede webapplikationer Lars L. Andersson Chefkonsulent Webapplikationer Interaktion med serverbaserede data via skærmbilleder leveret gennem

Læs mere

Assignment #5 Toolbox Contract

Assignment #5 Toolbox Contract Assignment #5 Toolbox Contract Created by: René Kragh Trine Randløv E mail address cph rk70@cphbusiness.dk 23 11 2014 1 Introduktion Dette dokument indeholder en vertikal kontrakt for et system som skal

Læs mere

Dokumentering af umbraco artikeleksport:

Dokumentering af umbraco artikeleksport: Dokumentering af umbraco artikeleksport: Lav en artikel side 2-3. Installationsguide side 3-5. Opsættelse af databasen og web.config side 5-8. Umbraco: templates side 8. Umbraco: borger.dk tab side 8.

Læs mere

Prepared Statements. Denne artikel beskriver hvorfor prepared statements er gode. Den forudsætter lidt kendskab til Java og JDBC.

Prepared Statements. Denne artikel beskriver hvorfor prepared statements er gode. Den forudsætter lidt kendskab til Java og JDBC. Denne guide er oprindeligt udgivet på Eksperten.dk Prepared Statements Denne artikel beskriver hvorfor prepared statements er gode. Den forudsætter lidt kendskab til Java og JDBC. Skrevet den 18. Feb 2010

Læs mere

Lad os lave en hjemmeside. Kikker du på http://www.olehasselbalch.dk, vil du højst sandsynligt se dette.

Lad os lave en hjemmeside. Kikker du på http://www.olehasselbalch.dk, vil du højst sandsynligt se dette. Lad os lave en hjemmeside. Kikker du på http://www.olehasselbalch.dk, vil du højst sandsynligt se dette. Spørgsmålet er nu, hvordan laver man sådan en side? Du skal have et såkaldt webhotel, hvilket jeg

Læs mere

DM01 DM01. 3. Obl. Afl. Jacob Christiansen, 130282, jacob.ch@mail.tdcadsl.dk. D12, Elias 18/3-2003. Side 1 af 11

DM01 DM01. 3. Obl. Afl. Jacob Christiansen, 130282, jacob.ch@mail.tdcadsl.dk. D12, Elias 18/3-2003. Side 1 af 11 DM01 DM01 3. Obl. Afl. Jacob Christiansen, 130282, jacob.ch@mail.tdcadsl.dk D12, Elias 18/3-2003 Side 1 af 11 DM01 Indholdsfortegnelse: BILAG:...2 1 FORMÅL:...3 2 KLASSER:...4 2.1 DILEMMA:...4 2.1.1 METODER:...4

Læs mere

Grafisk Redegørelse Opgaven Programvalg Kvalitetsvurdering Målgruppe Arbejdsproces Kvalitet Komposition og layout Brugervenlighed

Grafisk Redegørelse Opgaven Programvalg Kvalitetsvurdering Målgruppe Arbejdsproces Kvalitet Komposition og layout Brugervenlighed Redegørelse Grafisk Opgaven At redesigne en hjemmeside for AGF fanclub, som har et mere moderne look og et nyhedsarkiv som er let oversskueligt. Hjemmesiden er en opgave jeg selv har stillet mig og kunne

Læs mere

Administration - Wordpress 2014-07-02. Administration - Wordpress

Administration - Wordpress 2014-07-02. Administration - Wordpress Administration - Wordpress 1 Indholdsfortegnelse Wordpress CMS-system... 4 Wordpress administration... 4 Video-manualer til Wordpress... 4 Wordpress Support... 4 Manual Traeinfo.dk og Traeguiden.dk...

Læs mere

Ratingsystem i PHP og MySQL

Ratingsystem i PHP og MySQL Denne guide er oprindeligt udgivet på Eksperten.dk Ratingsystem i PHP og MySQL Lær at lave et system til at vise rating/bedømmelse på artikler og nyheder. Skrevet den 03. Feb 2009 af virtual1ty I kategorien

Læs mere

PHP Crash course. Databaser

PHP Crash course. Databaser PHP Crash course Databaser PHP Intro PHP er et server scripting sprog der kan bruges til at lave aktivt indhold på hjemme sider. Der er to betingelser som skal opfyldes for at serveren fortolker PHP koden.

Læs mere

I mit script tager jeg højde for det problem ved, at gemme et unikt tal mellem 0-9 på 6 cifre og derved vil de så blive vist som 2 online.

I mit script tager jeg højde for det problem ved, at gemme et unikt tal mellem 0-9 på 6 cifre og derved vil de så blive vist som 2 online. Denne guide er oprindeligt udgivet på Eksperten.dk Hvem er online? Online script, som tager højde for at der kan være flere personer, som har den samme IP-adresse. Scriptet viser hvor lang tid brugeren

Læs mere

PHP Snippets. De små korte. Skrevet af Daniel Pedersen

PHP Snippets. De små korte. Skrevet af Daniel Pedersen PHP Snippets De små korte Skrevet af Daniel Pedersen Indhold PHP Snippets De små korte er en samling af små og praktiske kode eksempler med kort forklaring, som med formål at kunne benyttes til opsalgsværk

Læs mere

CentOS 7. Lavet af Ali Sarac og Andreas Jensen

CentOS 7. Lavet af Ali Sarac og Andreas Jensen CentOS 7 Lavet af Ali Sarac og Andreas Jensen 3.8.2017 Indholdsfortegnelse Konklusion... 3 Installer CentOS 7 i VMware... 3 Installation af Apache, PHP5 og vores HTML side... 7 2.4 spørgsmål... 12 Kildekoder...

Læs mere

Det Naturvidenskabelige Fakultet. Introduktion til Blackboard (Øvelser) Naturvidenskabeligt Projekt 2006 Prøv at forske

Det Naturvidenskabelige Fakultet. Introduktion til Blackboard (Øvelser) Naturvidenskabeligt Projekt 2006 Prøv at forske Det Naturvidenskabelige Fakultet Introduktion til Blackboard (Øvelser) Naturvidenskabeligt Projekt 2006 Prøv at forske Indholdsfortegnelse Introduktion til Blackboard Content System...3 Øvelse 01 individuel:

Læs mere

AAU, Programmering i Java Intern skriftlig prøve 18. maj 2007

AAU, Programmering i Java Intern skriftlig prøve 18. maj 2007 AAU, Programmering i Java Intern skriftlig prøve 18. maj 2007 Opgavebesvarelsen skal afleveres som enten en printerudskrift eller som et passende dokument sendt via email til fjj@noea.dk. Besvarelsen skal

Læs mere

Portal Registration. Check Junk Mail for activation . 1 Click the hyperlink to take you back to the portal to confirm your registration

Portal Registration. Check Junk Mail for activation  . 1 Click the hyperlink to take you back to the portal to confirm your registration Portal Registration Step 1 Provide the necessary information to create your user. Note: First Name, Last Name and Email have to match exactly to your profile in the Membership system. Step 2 Click on the

Læs mere

PHP 3 UGERS FORLØB PHP, MYSQL & SQL

PHP 3 UGERS FORLØB PHP, MYSQL & SQL PHP 3 UGERS FORLØB PHP, MYSQL & SQL Uge 1 & 2 Det basale: Det primære mål efter uge 1 og 2, er at få forståelse for hvordan AMP miljøet fungerer i praksis, og hvordan man bruger PHP kodesproget til at

Læs mere

Denne artikel er til dem der ønsker at vide mere om hvad CSS er og hvad CSS kan bruges til hvad angår WWW.

Denne artikel er til dem der ønsker at vide mere om hvad CSS er og hvad CSS kan bruges til hvad angår WWW. Denne guide er oprindeligt udgivet på Eksperten.dk CSS - en gennemgang Denne artikel er til dem der ønsker at vide mere om hvad CSS er og hvad CSS kan bruges til hvad angår WWW. Der er lidt CSS historie

Læs mere

Projekt i Programmering C Menu til hjemmeside.

Projekt i Programmering C Menu til hjemmeside. Projekt i Programmering C Menu til hjemmeside. 10-12-2004 Holstebro HTX Bent Arnoldsen Synopsis. Projektet her er en menu til hjemmesider, som er lavet så den er let at tilrette, når man tilføjer eller

Læs mere

Web Admin 5.5. Brugsvejledning for Domain admin. Copyright 2003 Gullestrup.net

Web Admin 5.5. Brugsvejledning for Domain admin. Copyright 2003 Gullestrup.net Web Admin 5.5 Copyright 2003 Gullestrup.net Log ind på systemet Start med at gå ind på http://mailadmin.gullestrup.net i din browser. Indtast din Email Adresse samt Password, som du tidligere har modtaget

Læs mere

Dynamisk PHP design OPDATERET

Dynamisk PHP design OPDATERET Denne guide er oprindeligt udgivet på Eksperten.dk Dynamisk PHP design OPDATERET I har måske undret jer over "http://bla.dk/?side=kontakt", her beskriver jeg hvordan, og hvorfor Skrevet den 03. Feb 2009

Læs mere

Reeksamen, DSDS, forår 2008

Reeksamen, DSDS, forår 2008 Reeksamen, DSDS, forår 2008 Introduktion til Scripting, Databaser og Systemarkitektur Jonas Holbech IT Universitetet i København 22. august 2008 Alle hjælpemidler er tilladte, dog ikke computer og kommunikationsmidler.

Læs mere

Dynamiske Billeder, Image Map & XY coordinater. ASP.NET og Access Databasen.

Dynamiske Billeder, Image Map & XY coordinater. ASP.NET og Access Databasen. Dynamiske Billeder, Image Map & XY coordinater. ASP.NET og Access Databasen. Tutorial lavet af Jákup W. Hansen TSU 2006 22. april 2008 Hvorfor denne tutorial: Denne tutorial er ikke direkte pensum på datamatikkerskolen,

Læs mere

Procesbeskrivelse - Webprogrammering

Procesbeskrivelse - Webprogrammering Procesbeskrivelse - Webprogrammering Indholdsfortegnelse Forudsætninger... 1 Konceptet... 2 Hjemmesiden... 2 Server-side... 3 Filstrukturen... 3 Databasehåndtering og serverforbindelse... 4 Client-side...

Læs mere

FORSTÅELSE FOR GRAFISK PRODUKTION OG WORKFLOW

FORSTÅELSE FOR GRAFISK PRODUKTION OG WORKFLOW Opgaven I AArhus er en fiktiv hjemmeside. Formålet med hjemmesiden, er at Folk som befinder sig i Aarhus kan henvende sig til I AArhus og berette deres synspunkt på Aarhus. Siden henvender sig til unge,

Læs mere

Region Syddanmark Guide til oprettelse og udsendelse af nyhedsbreve i Peytz Mail

Region Syddanmark Guide til oprettelse og udsendelse af nyhedsbreve i Peytz Mail Region Syddanmark Guide til oprettelse og udsendelse af nyhedsbreve i Peytz Mail 10. august 2018 1 Nyhedsbreve i Peytz Mail Sådan opretter du et nyt nyhedsbrev 1. Log på Peytz Mail med dit brugernavn og

Læs mere

Umbraco installationsvejledning

Umbraco installationsvejledning på et ScanNet ASP Webhotel Indledning Beskrivelse Denne vejledning vil indeholde installation af CMS systemet Umbraco på et ASP Webhotel. Det dansk grundlagt Content Management System (CMS) Umbraco er

Læs mere

Lad os lave en hjemmeside. Kikker du på http://www.olehasselbalch.dk, vil du højst sandsynligt se dette.

Lad os lave en hjemmeside. Kikker du på http://www.olehasselbalch.dk, vil du højst sandsynligt se dette. Lad os lave en hjemmeside. Kikker du på http://www.olehasselbalch.dk, vil du højst sandsynligt se dette. Spørgsmålet er nu, hvordan laver man sådan en side? Du skal have et såkaldt webhotel, hvilket jeg

Læs mere

Sådan kan du sende data fra din egen hjemmeside til JitBesked via en HTML-JDF.

Sådan kan du sende data fra din egen hjemmeside til JitBesked via en HTML-JDF. Sådan kan du sende data fra din egen hjemmeside til JitBesked via en HTML-JDF. Vejledningen her beskriver hvordan man opbygger en form i HTML og sender indholdet af felterne til JitBesked. Det kræver du

Læs mere

Indledning. MIO er optimeret til Internet Explorer. Læs endvidere under Ofte stillede spørgsmål.

Indledning. MIO er optimeret til Internet Explorer. Læs endvidere under Ofte stillede spørgsmål. Indhold Indledning... 3 Søgefunktioner... 4 Søgning fra forsiden... 5 Søgning under menupunktet Instrument... 6 Sådan får man vist instrumenterne i en bestemt afdeling... 7 Sådan ændrer man status på et

Læs mere

Byggebasen Javascript

Byggebasen Javascript EG Data Inform Byggebasen Javascript Implementering af ansvarsperioder og produktdata på eget site Jens Karsø 2013 Indhold Byggebasen javascript-plugin til DB12-site... 2 DB12-site kommunikationsmodel...

Læs mere

FORCE Inspect Online Manual v. 1.02. FORCE Inspect Online Manual. 1 af 18

FORCE Inspect Online Manual v. 1.02. FORCE Inspect Online Manual. 1 af 18 FORCE Inspect Online Manual 1 af 18 Indholdsfortegnelse Indholdsfortegnelse... 2 FORCE Inspect Online Manual... 3 Generelt... 3 Login... 3 Main... 4 Intro sektion... 4 Links sektion... 4 News sektion...

Læs mere

Eksempel på en database: studenter, kurser, eksamener

Eksempel på en database: studenter, kurser, eksamener Udvidet Programmering 1999 Forelæsning 20, fredag 12. november 1999 Relationsdatabaser: relationer, tupler, attributter Forespørgselssproget SQL Databasesystemet PostgreSQL Tilgang til relationsdatabaser

Læs mere

Web- og serverprogrammering

Web- og serverprogrammering Web- og serverprogrammering Arkitekturer i webprogrammer - dag 6 Model-View-Controller-arkitukturen Flerlags-arkitekturer Læsning: WJSP 10 Dette materiale er under Åben Dokumentlicens, se http://www.sslug.dk/linuxbog/licens.html

Læs mere

3) Først og fremmest kan du vælge hvilket tema din side skal have.

3) Først og fremmest kan du vælge hvilket tema din side skal have. Wordpress er et open source software du kan bruge til at oprette blogs og hjemmesider i. Du har mulighed for at vælge forskellig temaer og designe din side som du har lyst. Blogs og hjemmesider kan blandt

Læs mere

Hvordan vælger jeg dokumentprofilen?

Hvordan vælger jeg dokumentprofilen? Hvordan vælger jeg dokumentprofilen? Valget af OIOUBL profil i en konkret dokumentudveksling vil bl.a. afhænge af, hvilke OIOUBL profiler den anden part i udvekslingen understøtter. Et konkret eksempel

Læs mere

Web Admin 5.5. Brugsvejledning for User admin. Copyright 2003 Gullestrup.net

Web Admin 5.5. Brugsvejledning for User admin. Copyright 2003 Gullestrup.net Web Admin 5.5 Copyright 2003 Gullestrup.net Log ind på systemet Start med at gå ind på http://mailadmin.gullestrup.net i din browser. Indtast din Email Adresse samt Password, som hører til din konto, tryk

Læs mere

Beginning CSS and Web Development kap. 1 11

Beginning CSS and Web Development kap. 1 11 Beginning CSS and Web Development kap. 1 11 Plan Xhtml opbygning CSS Divs, class, id Baggrunde, farver og billeder Tekst Links Lister Tabeller Stand up programmering Xhtml vs. html i XHTML skal alle elementer

Læs mere

JEM1 LAB14. Journal. Jonas Lange, Martin Funding Fisker og Torben Porsgaard 11/4/2009

JEM1 LAB14. Journal. Jonas Lange, Martin Funding Fisker og Torben Porsgaard 11/4/2009 JEM1 LAB14 Journal Jonas Lange, Martin Funding Fisker og Torben Porsgaard 11/4/2009 Denne journal er fremstillet i forbindelse med udarbejdelsen af en J2ME applikation der holder og persisterer links og

Læs mere

REDESIGN AF GRAFISK FORUMS HJEMMESIDE. Grafisk Workflow

REDESIGN AF GRAFISK FORUMS HJEMMESIDE. Grafisk Workflow Grafisk Workflow REDESIGN AF GRAFISK FORUMS HJEMMESIDE Før Efter REDEGØRELSE OPGAVEN Da jeg ikke har noget med web at gøre på min elevplads, opfandt jeg en fiktiv opgave - nemlig at redesigne Grafisk Forums

Læs mere

Dannelse af PDF dokumenter

Dannelse af PDF dokumenter Dannelse af PDF dokumenter Indhold Dannelse af PDF-dokumenter i Phd Planner... 2 Valg af vedhæftninger i PDF dokumentet... 2 Valg af skabelon for PDF dokumentet... 3 Når PDF filen er dannet... 5 Gem PDF

Læs mere

Grafisk workflow. Maria Clausen Svendeportfolio Grafisk workflow

Grafisk workflow. Maria Clausen Svendeportfolio Grafisk workflow Grafisk workflow Maria Clausen Svendeportfolio Grafisk workflow OPGAVEN Kunden har stiftet et nyt firma som hedder Wood id, som sælger lamper, møbler og tilbehør lavet i kvalitets træ. Kunden ville gerne

Læs mere

A Profile for Safety Critical Java

A Profile for Safety Critical Java A Profile for Safety Critical Java Martin Schoeberl Hans Søndergaard Bent Thomsen Anders P. Ravn Præsenteret af: Henrik Kragh-Hansen November 8, 2007 Forfatterne Martin Schoeberl Udvikler af JOP processoren

Læs mere

Løsning af skyline-problemet

Løsning af skyline-problemet Løsning af skyline-problemet Keld Helsgaun RUC, oktober 1999 Efter at have overvejet problemet en stund er min første indskydelse, at jeg kan opnå en løsning ved at tilføje en bygning til den aktuelle

Læs mere

Online kursus: Content Mangement System - Wordpress

Online kursus: Content Mangement System - Wordpress Online kursus 365 dage DKK 1.999 Nr. 90213 P ekskl. moms Wordpress er et open-source content management system, som anvendes af mere end 23% af verdens 10 millioner mest besøgte hjemmesider. Det er et

Læs mere

Practical Intermodal Communication. How-To WebBooking Customer Cap-Flex. Version

Practical Intermodal Communication. How-To WebBooking Customer Cap-Flex. Version Practical Intermodal Communication How-To WebBooking Customer Cap-Flex Version 1.04 PICit A/S Javavej 1 DK-8000 Aarhus (45) 87 30 80 20 www.picit.dk 1/36 Indhold Capacity Booking Flow 2 Cancel af Fast

Læs mere

Grafisk Workflow. Mediegrafiker - Svendeprøve. Mediegrafikeruddannelsen af Ramin Azizi

Grafisk Workflow. Mediegrafiker - Svendeprøve. Mediegrafikeruddannelsen af Ramin Azizi Grafisk Workflow Mediegrafiker - Svendeprøve Mediegrafikeruddannelsen 2012-2016 - af Ramin Azizi www.azizidesign.dk Dokumentation Opgavebeskrivelse: Jeg har i denne opgave valgt at redesigne s hjemmeside,

Læs mere

I denne arktikle går jeg gennem Slet, Ret og Opret data i en MySQL database. der er også en lille del i den hvor den postere datanen ud i en løkke

I denne arktikle går jeg gennem Slet, Ret og Opret data i en MySQL database. der er også en lille del i den hvor den postere datanen ud i en løkke Denne guide er oprindeligt udgivet på Eksperten.dk MySQL for nybegynder I denne arktikle går jeg gennem Slet, Ret og Opret data i en MySQL database. der er også en lille del i den hvor den postere datanen

Læs mere

Brugervejledning til udfyldelse og udstedelse af Europass Mobilitetsbevis i Europass Mobilitetsdatabasen

Brugervejledning til udfyldelse og udstedelse af Europass Mobilitetsbevis i Europass Mobilitetsdatabasen Brugervejledning til udfyldelse og udstedelse af Europass Mobilitetsbevis i Europass Mobilitetsdatabasen Europass Mobilitetsbevis skal udfyldes og udstedes i mobilitetsdatabasen: http://mobilitet.europass.dk/.

Læs mere

Program Dokumentation PC Software Skrevet af. Gruppen. Version 1.0

Program Dokumentation PC Software Skrevet af. Gruppen. Version 1.0 Program Dokumentation PC Software Skrevet af Gruppen. Version 1.0 Indholds fortegnelse 1. INDLEDNING...3 1.1. FORMÅL...3 1.2. REFERENCER...3 1.3. VERSIONSHISTORIE...3 1.4. DEFINITIONER...3 1.5. DOKUMENTATIONENS

Læs mere

Database for udviklere. Jan Lund Madsen PBS10107

Database for udviklere. Jan Lund Madsen PBS10107 Database for udviklere Jan Lund Madsen PBS10107 Indhold LINQ... 3 LINQ to SQL og Arkitektur... 3 O/R designere... 5 LINQ Den store introduktion med.net 3.5 er uden tvivl LINQ(udtales link): Language-INtegrated

Læs mere

En Kort Introduktion til Oracle

En Kort Introduktion til Oracle En Kort Introduktion til Oracle Henrik Bulskov 12. februar 2001 bulskov@ruc.dk 1 Start SQL*Plus... 1 1.1 TELNET... 1 1.2 WINDOWS SQL PLUS... 2 2 Kør et SQL-script... 3 3 Hjælp i SQL*Plus... 3 4 Editering

Læs mere

GRAFISK WORKFLOW GRAFISK WORKFLOW DIGITAL KOMMUNIKATION OLEMOGELBY.COM

GRAFISK WORKFLOW GRAFISK WORKFLOW DIGITAL KOMMUNIKATION OLEMOGELBY.COM GRAFISK WORKFLOW DIGITAL KOMMUNIKATION OLEMOGELBY.COM OPGAVEN Redesign af Ole Møgelbys hjemmeside, der efter stor succes med sine værker, gerne vil have frisket udtrykket lidt op. Billedsiderne skal udvides

Læs mere

Brugervejledning til databrowseren

Brugervejledning til databrowseren Brugervejledning til databrowseren Indholdsfortegnelse Indledning...2 Hvordan tilgås browseren og api et...2 Databrowseren...2 Søgning...2 Visning...4 Features i listevisningen...4 Detaljeret visning...5

Læs mere

Nolde Museet. I gang med Dreamweaver. Opgave. Opgavebeskrivelse. Layout. Mål og CSS

Nolde Museet. I gang med Dreamweaver. Opgave. Opgavebeskrivelse. Layout. Mål og CSS Opgavebeskrivelse Lav en webside om i Sønderjylland. Opgaven fører dig igennem de basale ting, hvad angår opbygningen af en side med CSS. Der er ikke tale om et komplet site, men du kan bruge opgaven som

Læs mere

Introduktion til ActionScript, fortsat

Introduktion til ActionScript, fortsat Introduktion til ActionScript, fortsat Kaspar Rosengreen Nielsen kaspar@interactivespaces.net i n t e r a c t i v e s p a c e s. n e t Kaspar Nielsen, kaspar@interactivespaces.net 1 Dagens program Opsamling

Læs mere

Netværk & elektronik

Netværk & elektronik Netværk & elektronik Oversigt Ethernet og IP teori Montering af Siteplayer modul Siteplayer teori Siteplayer forbindelse HTML Router (port forwarding!) Projekter Lkaa Mercantec 2009 1 Ethernet På Mars

Læs mere

Tagwall med Php & MySQL

Tagwall med Php & MySQL Denne guide er oprindeligt udgivet på Eksperten.dk Tagwall med Php & MySQL Her laver vi en tagwall i Php & MySQL... jeg forklarer dog ikke så meget, men jeg håber du kan få det til at blive til en tagwall

Læs mere

Zapier-integration mellem MailChimp og webcrm hos Azalea IT

Zapier-integration mellem MailChimp og webcrm hos Azalea IT Case: Zapier-integration mellem MailChimp og webcrm hos Azalea IT Zapier er en integrationsplatform, hvor man kan forbinde over 1500 apps uden at skrive en eneste bid kode. Du kan se, hvilke apps du kan

Læs mere

KUNDE-WEBPORTAL KOM GODT I GANG

KUNDE-WEBPORTAL KOM GODT I GANG Specialtrykkeriet Arco KUNDE-WEBPORTAL KOM GODT I GANG Vi håber du får fornøjelse af vores nye værktøj. WebApproval skal gøre det nemmere og mere sikkert for dig at godkende din tryksager. Har du spørgsmål,

Læs mere

Grafisk Workflow STILHISTORIE. Website lavet i forbindelse med et projekt om stilhistorie. Klik her for at se websitet:

Grafisk Workflow STILHISTORIE. Website lavet i forbindelse med et projekt om stilhistorie. Klik her for at se websitet: STILHISTORIE Website lavet i forbindelse med et projekt om stilhistorie. Klik her for at se websitet: http://www.mediegrafiker-ats.dk/12gf32med8b/stil/maria/ Opgaven I forbindelse med et tema omhandlende

Læs mere

User Manual for LTC IGNOU

User Manual for LTC IGNOU User Manual for LTC IGNOU 1 LTC (Leave Travel Concession) Navigation: Portal Launch HCM Application Self Service LTC Self Service 1. LTC Advance/Intimation Navigation: Launch HCM Application Self Service

Læs mere

Adobe Acrobat Connect brugergrænsefladen

Adobe Acrobat Connect brugergrænsefladen Adobe Acrobat Connect brugergrænsefladen Adobe Connect er et webbaseret videokonferenceværktøj, der giver mulighed for online, synkron kommunikation, deling af filer, skærm og whiteboard, gennemførelse

Læs mere

GRAFISK WORKFLOW H1 MARIA SCHELDE

GRAFISK WORKFLOW H1 MARIA SCHELDE GRAFISK WORKFLOW H1 MARIA SCHELDE DOKUMENTATION Opgaven Arkitekt Mette Schelde skulle have designet og programmeret et website, hvorpå hun kunne præsentere hendes produkter. Designkrav Sitet skal være

Læs mere

Active Builder - Brugermanual

Active Builder - Brugermanual Active Builder - Brugermanual Version: Release 2.0 Sprog: Dansk Copyright 2014 - Talk Active ApS INDHOLDSFORTEGNELSE INDHOLDSFORTEGNELSE... 2 1. HURTIGT OVERBLIK... 4 1.1 Vælg URL:... 4 1.2 Vælg en skabelon:...

Læs mere

Opdatering af ISOWARE til version 6.1.0

Opdatering af ISOWARE til version 6.1.0 Opdatering af ISOWARE til version 6.1.0 September 2015 Indhold Kontaktoplysninger... 1 VIGTIGT... 2 Opdatering af trejdepartssoftware... 2 Opdatering til version 6.1.0.... 2 1. Backup af databasen... 3

Læs mere