CliMate följer Tre-lager-arkitektur De tre lagren presentation: användarhändelser+grafik+resultat domänlogik: håller systemets funktioner databasaccess: databas + sql-hantering Paketen i CliMate: climate.ui (inkl climate.ui.action och climate.ui.update) är presentation climate.domain är domänlogik climate.database är databasaccess Varför lager: separera olika uppgifter i olika delar Lars Degerstedt statisk uppdelning: vilken fil/klass gör vad Attribution-NonCommercial-ShareAlike2.5 License Viktiga domänklasser i CliMate FileCollection 1 n ObservationFile 1 n Observation Domänobjekt - “domänlogiklagret” Domänlogiken uttrycker data och logiska operationer på data ex: observationer, filer, fil-attribut, inläsningfilter Motsvarande data: METDATA97010100 METDATA97010103.utf-16 METDATA97010106 ... Domänobjekten håller aktuell data FileIdentity: 97010100 Coding: ISO-8859-1 Long: 0.120000E+07 Lat: 0.766000E+07 Domänobjekt är grunden i OO-design de förändras lite/sakta de är nära besläktade med problemdomänen ..förutom data (“tillstånd”) håller dessa klassers objekt systemets funktionalitet. Dessa två tillsammans kan man kalla domänlogik Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License tillstånd/data är viktigare än funktion: metoder kan läggas till gradvis Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License Labb 2: uppgift 1 JButton: grafik och swing-lyssnare JButton javax.swing.JButton: skapar en knapp Visa inlästa filer ex: JButton b = new JButton("I'm a Swing button!"); lyssna på climate.domain javax.swing.AbstractAction visa resultat JLabel JFrame gör subklass ger en ActionListener climate.ui.update.SaveFileListUpdate se t ex ReadFileAction Göra knappar tilldela en lyssnare till en knapp skapa grafik associera lyssnare ex: b.addActionListener(listener) climate.ui.SaveToDatabasePanel Använd javadoc! CliMate använder metadata för text ex: metaData.get Lars Degerstedt Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License Attribution-NonCommercial-ShareAlike2.5 License Exempel: ReadFileAction “Läs” Ex: skapa lyssnaren på läs-knappen Plockar data från domänlagret public void actionPerformed(ActionEvent a) { String filePath = coll.getStringProperty(FileCollection.Property.FILE_PATH); String sign = coll.getStringProperty(FileCollection.Property.SIGNATURE); if (filePath == null || filePath.equals("")) { log.debug("User attempted to read file without file path"); JOptionPane.showMessageDialog(null, metaData.get(Messages.SPECIFY_FILE_MESSAGE)); Data.get(Messages.SIGNATUR_TOO_SHORT_MESSAGE)); ... Testar om alla data } else { är ifylld annars popup t ry { coll.readFromFile(); } catch (FileNotFoundException e) { Om allt är ok läs in ... från fil/katalog } } Anrop till domän! Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License CliMate main CliMate Window ReadFromFile Panel readFileButton: JButton rf: ReadFile Action new new new new addAction Listener(rf) Dvs framtida knapp-händelser till rf Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License UI-objekt - “presentationslagret” Exempel: Användarhändelse “läs in” Två typer av objekt: readFileBut: JButton grafik: grafiskt innehåll och layout lyssnare: lyssnar efter händelser och agerar på dem ReadFile Action FileCollection Observation Filter ObservationFile actionPerformed Två typer av lyssnare: readFromFile readFromFile användarhändelser “action”: t ex Swing-lyssnare på komponenter filterRow systemhändelser “update”: t ex Observable/Observer på domänlogik update ... CliMate climate.ui innehåller grafik-klasser climate.ui.action Swing-lyssnare climate.ui.update Observer-lyssnare Lars Degerstedt Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License Attribution-NonCommercial-ShareAlike2.5 License JList: Swing-komponent för listor Används för att lista strängar eller andra swingkomponenter Exempel: UI-update “ny fil inläst” till flik Spara FileCollection SaveFileList Update DefaultList Model vertikalt eller horisontellt update JList använder en JListModel som håller innehållet i listan addElement Skapad av SaveToDatabase Panel uppdaterar man modellen uppdateras grafiken CliMate använder en subklass DefaultListModel Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License Laboration 2 - uppgift 2 Databas-access via JDBC (skiss) Spara observationer och fildata i MySQLdatabas Java klient- Editera i alla tre lagren för användarfallet “spara” Skapa klass java.sql.Connection Databas SQL anrop Java.sql.Statement Klasser som påverkas: Creates SaveToDatabaseAction/Worker SQL Resultat ObservationFile Java.sql.ResultSet DatabaseService Sparandet ska ske så att flikens JProgressBar uppdateras kontinuerligt. Lars Degerstedt Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License Attribution-NonCommercial-ShareAlike2.5 License Litet exempel på JDBC-koppling Class.forName(com.mysql.jdbc.Driver).newInstance(); String url = jdbc:mysql://maj4.ida.liu.se:bird_database; Connection c = DriverManager.getConnection(url, "my_login", "my_password"); Statement stmt = con.createStatement(); stmt.executeUpdate(INSERT INTO species VALUES+ ('skata', 'Till Skottland')); ResultSet rs = stmt.executeQuery(SELECT * FROM species WHERE + name = \skata\"); rs.next(); String text = rs.getString(migration_field); System.out.println(Skatans flyttvanor:+text); Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License JDBC i Climate Klassen Database skapar ett java.sql.Connectionobjekt val av host/databas/användare/lösen sätts i settings.properties Observera att endast ett Connection-objekt skapas per körning DatabaseService bygger SQL-statements och skickar via detta Connection-objekt Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License Lagret för databas-access Modell-vy-kontroll (MVC) ...namnet på denna kommunikationsmodell mellan domänlogik och presentation. Avbilda objekt på relationer Domänlogik FileCollection Enkel lösning: transaktionsskript (Fowler) Modell hantera SQL i Java - “metaprogrammering” prenumerera/notifiera Separera ut SQL-källkod från löpande Java-källkod Förändra tillstånd Presentation SaveFileList Update Hantera process-koppling användarhändelser Vy värddator + sökväg föränderlig konfigureringsdata Hantera tillfälliga avbrott och omstart Kontroll ReadFileAction ReadFromFilePanel SaveToDatabasePanel Lars Degerstedt Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License Attribution-NonCommercial-ShareAlike2.5 License SwingWorker - bakgrundsprocess Sekvensdiagram för “Spara”: från presentation till databas Undvik att krävande operationer fryser grafiken introducera trådar (eng thread) som kör separat process climate.ui.SwingWorker skapar en tråd SaveToDatabaseWorker ärver av SwingWorker saveBut: JButton SaveToDb Action action Performed SaveToDb Worker new start FileCollection Database Service ... saveProgress... updateObs ...updateObs execute Update ... updateObs ... SaveToDatabaseAction ska starta SaveToDatabaseWorker Swing körs i sin egen tråd (“the Swing thread”) SwingUtilities: invokeAndWait och invokeLater Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License Swing-tråden Connection saveTo Database måste implementera construct()-metoden trådar startas med med metoden start() ... -”-”- ... SwingWorker-tråden Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License “Spara”: från databas till presentation Spara i omgångar och ProgressBar Observer/Observable: ui-lagret lyssnar även inåt mot domain – då använder vi java.util.Observer FileCollection FileCollection SaveProgress Update JProgressBar FileCollection Se paketet climate.ui.update FileCollection markerar hur långt man kommit update display(true) getStringProp setSaveProgressMax: sätter hur lång nuvarande fil är update setSaveProgress: sätter hur många obs som sparats setMaximum getStringProp setValue I MetaData finns en metod getDatabaseBatchSize update anger antal observationer som ska sparas åt gången. ... Vid varje progressionsmarkering anropas alla Observer-objekt för FileCollection getStringProp ... SwingWorker-tråden setValue ... Swing-tråden SaveProgressUpdate lyssnar efter progressions-händelser Lars Degerstedt Lars Degerstedt License Progressions-grafiken nollställs för Attribution-NonCommercial-ShareAlike2.5 varje sparad fil Attribution-NonCommercial-ShareAlike2.5 License DatabaseService: Data Mapper i CliMate UpdateStatement: CliMates updateobject-klass Kopplar domänobjekt och databasrepresentation Objektorienterad modell till relationsmodell - “O/R bridge” Tre publika metoder i DatabaseService Skapa en speciell klass/metoder som bygger upp en databas-uppdatering (insert, delete, replace etc) saveObservations: sparar ner ett segment ur en observationsfil UpdateStatement: objekt som utifrån ett eller flera ValueSet registerInFileCollection: registrerar vilken observationssamling som just sparats (labb 2) tilldelar query = “REPLACE INTO ” + table + “ VALUES “ selectObservations: gör en selektion baserat på givna sökkriterier (labb 3) Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License addValueSet: lägger till värden efter VALUES execute: skickar värdet på query till databasen Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License Summering Tre-lager-arkitektur: olika uppgifter i olika lager Labb 2, del 1: arbeta med swing-grafik och uppdatering via Observable/Observer Domänlogik och presentation arbetar ihop via MVC lyssnare åt två håll: på användaren och på systemet I CliMate: action och update Labb 2, del 2: JDBC/SQL enbart i databaslagret Separat tråd för tung beräkning DataMapper och Update Object Lars Degerstedt Attribution-NonCommercial-ShareAlike2.5 License