From 5eee5633fa7504874bbd81840efa5965bedd7c15 Mon Sep 17 00:00:00 2001 From: ulrich <undisclosed> Date: Sat, 24 Feb 2018 16:19:43 +0000 Subject: [PATCH] Datenbank-Konfiguration ergaenzt, DAOs erzeugt, Initialiser erstellt --- web/WEB-INF/web.xml | 3 web/WEB-INF/sql.properties | 26 +++ src/java/de/uhilger/radiozentrale/web/Initialiser.java | 218 +++++++++++++++++++++++++++++++ src/java/de/uhilger/radiozentrale/daten/Abspieler.java | 94 +++++++++++++ src/java/de/uhilger/radiozentrale/daten/Sender.java | 73 ++++++++++ web/WEB-INF/create_database.sql | 2 6 files changed, 415 insertions(+), 1 deletions(-) diff --git a/src/java/de/uhilger/radiozentrale/daten/Abspieler.java b/src/java/de/uhilger/radiozentrale/daten/Abspieler.java new file mode 100644 index 0000000..43c4625 --- /dev/null +++ b/src/java/de/uhilger/radiozentrale/daten/Abspieler.java @@ -0,0 +1,94 @@ +/* + * Radiozentrale - Webradio App + * Copyright (C) 2018 Ulrich Hilger, http://uhilger.de + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ + */ + +package de.uhilger.radiozentrale.daten; + +import de.uhilger.baselink.DBColumn; +import de.uhilger.baselink.DBPrimaryKey; +import de.uhilger.baselink.DBTable; + +/** + * + * @author Ulrich Hilger + */ +@DBTable(name="app.abspieler") +@DBPrimaryKey({"abs_id"}) +public class Abspieler { + private int id; + private String name; + private String url; + private String typ; + private String bild; + private String zustand; + + + public void setId(int wert) { + id = wert; + } + + @DBColumn(name = "abs_id") + public int getId() { + return id; + } + + public void setName(String wert) { + name = wert; + } + + @DBColumn(name = "abs_name") + public String getName() { + return name; + } + + public void setUrl(String wert) { + url = wert; + } + + @DBColumn(name = "abs_url") + public String getUrl() { + return url; + } + + public void setTyp(String wert) { + typ = wert; + } + + @DBColumn(name = "abs_typ") + public String getTyp() { + return typ; + } + + public void setBild(String wert) { + bild = wert; + } + + @DBColumn(name = "abs_bild") + public String getBild() { + return bild; + } + + public void setZustand(String wert) { + zustand = wert; + } + + @DBColumn(name = "abs_zustand") + public String getZustand() { + return zustand; + } +} + diff --git a/src/java/de/uhilger/radiozentrale/daten/Sender.java b/src/java/de/uhilger/radiozentrale/daten/Sender.java new file mode 100644 index 0000000..bf600ee --- /dev/null +++ b/src/java/de/uhilger/radiozentrale/daten/Sender.java @@ -0,0 +1,73 @@ +/* + * Radiozentrale - Webradio App + * Copyright (C) 2018 Ulrich Hilger, http://uhilger.de + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ + */ + +package de.uhilger.radiozentrale.daten; + +import de.uhilger.baselink.DBColumn; +import de.uhilger.baselink.DBPrimaryKey; +import de.uhilger.baselink.DBTable; + +/** + * + * @author Ulrich Hilger + */ +@DBTable(name="app.sender") +@DBPrimaryKey({"sender_id"}) +public class Sender { + private int id; + private String name; + private String url; + private String logo; + + + public void setId(int wert) { + id = wert; + } + + @DBColumn(name = "sender_id") + public int getId() { + return id; + } + + public void setName(String wert) { + name = wert; + } + + @DBColumn(name = "sender_name") + public String getName() { + return name; + } + + public void setUrl(String wert) { + url = wert; + } + + @DBColumn(name = "sender_url") + public String getUrl() { + return url; + } + + public void setLogo(String wert) { + logo = wert; + } + + @DBColumn(name = "sender_logo") + public String getLogo() { + return logo; + } +} \ No newline at end of file diff --git a/src/java/de/uhilger/radiozentrale/web/Initialiser.java b/src/java/de/uhilger/radiozentrale/web/Initialiser.java new file mode 100644 index 0000000..7b257db --- /dev/null +++ b/src/java/de/uhilger/radiozentrale/web/Initialiser.java @@ -0,0 +1,218 @@ +/* + * Radiozentrale - Webradio App + * Copyright (C) 2018 Ulrich Hilger, http://uhilger.de + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ + */ + +package de.uhilger.radiozentrale.web; + +import de.uhilger.baselink.GenericRecord; +import de.uhilger.baselink.PersistenceManager; +import de.uhilger.baselink.Record; +import de.uhilger.radiozentrale.daten.Abspieler; +import de.uhilger.radiozentrale.daten.Sender; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.List; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +/** + * Initialisierungsklasse der Anwendung Nutzerverwaltung + * + * Hier wird u.a. geprüft, ob die Datenbank vorhanden ist und diese + * angelegt, falls nicht. Das SQL-Skript zur Anlage der Datenbank findet + * sich in WEB-INF/create_database.sql + * + * @author Ulrich Hilger + */ +public class Initialiser implements ServletContextListener { + + private static final Logger logger = Logger.getLogger(Initialiser.class.getName()); + + /** Name der Datei mit dem SQL-Skript zum Erzeugen der Datenbank */ + private static final String SCRIPT_NAME = "create_database.sql"; + /** Name der Datei mit den SQL-Kommandos dieser Anwendung */ + public static final String SQL_PROPERTIES_NAME = "sql.properties"; + /** Name des Parameters, unter dem der Name der DataSource im Deployment Descritpor zu finden ist */ + public static final String P_DSNAME = "dsname"; + /** Name, unter dem das Properties-Objekt mit den SQL-Befehlen im ServletContext hinterlegt ist */ + public static final String RZ_SQL_PROPERTIES = "radiozentraleSqlProperties"; + /** Name, unter dem das Zugriffsobjekt zur Datenbank im ServletContext hinterlegt ist */ + public static final String RZ_DB = "radiozentraleDb"; + + + /** Name des SQL-Befehls zum Pruefen, ob die Datenbank vorhanden ist */ + public static final String SQL_DB_VORHANDEN = "dbVorhanden"; + + public static final String MP_SENDER = "senderMapper"; + public static final String MP_ABSPIELER = "abspielerMapper"; + + /** + * Diese Webanwendung initialisieren, also z.B. Elemente instantiieren, die + * über den Deployment Descritpor veränderlich gehalten sind. + * + * @param servletContext der zur Laufzeit bestehende ServletContext + */ + private void initApp(ServletContext servletContext) { + try { + initSql(servletContext); + initDb(servletContext); + } catch (Exception ex) { + logger.log(Level.SEVERE, null, ex); + } + } + + /** + * Ein Eigenschaften-Objekt mit den SQL-Statements initialisieren, + * die von dieser Webanwendung verwendet werden + * + * Die SQL-Kommandos werden aus der Datei + * [CatalinaBase]/webapps/[Context]/WEB-INF/sql.properties + * gelesen und als Properties-Objekt unter dem von der Konstante + * SPOT_SQL_PROPERTIES bezeichneten Namen im ServletContext hinterlegt + */ + private void initSql(ServletContext servletContext) { + try { + File basis = new File(this.getClass().getResource("/").toURI()); + File sqlFile = new File(basis.getParentFile(), SQL_PROPERTIES_NAME); + logger.fine("lese SQL-Eigenschaften von " + sqlFile.getAbsolutePath()); + Properties sql = new Properties(); + sql.loadFromXML(new FileInputStream(sqlFile)); + servletContext.setAttribute(RZ_SQL_PROPERTIES, sql); + logger.fine("Abfrage dbVorhanden='" + sql.getProperty(SQL_DB_VORHANDEN) + "'"); + } catch(Exception ex) { + logger.log(Level.SEVERE, ex.getMessage(), ex); + } + } + + /* ----------------- Logik zur Datenbank-Erzeugung ------------ */ + + /* + Die Logik zur Datenbank-Erzeugung benoetigt zwei Parameter: + 1. den Namen der DataSource + 2. einen SQL-Befehl, mit dem geprueft werden kann, ob die + Datenbank vorhanden ist + + Der Name der DataSource ist im Deployment Descriptor unter dem mit + P_DSNAME bezeichneten Namen hinterlegt, der SQL-Befehl ist + im Properties-Objekt mit den SQL-Befehlen dieser Anwendung unter dem + mit SQL_DB_VORHANDEN bezeichneten Namen zu finden. + */ + + /** + * Pruefen, ob die von dieser Webanwendung benoetigte Datenbank + * vorhanden ist. Erzeugen der Datenbank, wenn sie nicht vorgefunden + * wird. + * + * @param servletContext der ServletContext dieser Webanwendung, in dem + * die Parameter zu finden sind, welche die Datenbankverbindung beschreiben + */ + private void initDb(ServletContext servletContext) { + try { + PersistenceManager db = new PersistenceManager(); + db.setDataSourceName(servletContext.getInitParameter(P_DSNAME)); + servletContext.setAttribute(RZ_DB, db); + initMapper(servletContext); + Properties sql = (Properties) servletContext.getAttribute(RZ_SQL_PROPERTIES); + if(!dbVorhanden(db, sql.getProperty(SQL_DB_VORHANDEN))) { + logger.info("Datenbank ist nicht vorhanden"); + int[] ergebnis = db.executeScript(getSqlSkript()); + /* + User admin = new User(); + admin.setId("admin"); + admin.setPw("admin"); + admin.setFirstName("admin"); + admin.setLastName("admin"); + admin.setEmail("none"); + UserMgr um = new UserMgr(); + um.setServletContext(servletContext); + um.createUser(admin); + */ + } + } catch(Exception ex) { + logger.log(Level.INFO, ex.getMessage(), ex); + } + } + + /** + * Mapper erzeugen + * @param servletContext der ServletContext dieser Webanwendung + */ + /* + TODO: das noch auf on demand anlegen: GenericRecord wird erst angelegt + wenn er erstmals benoetigt wird. Ggf. auch einen Mechanismus zum entfernen + laenger nicht benoetigter Mapper hinzufuegen + */ + private void initMapper(ServletContext servletContext) { + servletContext.setAttribute(MP_SENDER, new GenericRecord(Sender.class)); + servletContext.setAttribute(MP_ABSPIELER, new GenericRecord(Abspieler.class)); + } + + @SuppressWarnings("rawtypes") + private boolean dbVorhanden(PersistenceManager pm, String sql) { + boolean istVorhanden = false; + List<List<String>> list = pm.select(sql, Record.WITHOUT_BLOBS); + if(list != null && list.size() > 1) { + istVorhanden = true; + logger.fine("Datenbank ist vorhanden"); + } + return istVorhanden; + } + + private String getSqlSkript() throws Exception { + File basis = new File(this.getClass().getResource("/").toURI()); + File skript = new File(basis.getParentFile(), SCRIPT_NAME); + return fromStream(new FileInputStream(skript)); + } + + private String fromStream(InputStream in) throws IOException + { + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + StringBuilder out = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + out.append(line); + } + return out.toString(); + } + + /* --- ServletContextListener --- */ + + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext servletContext = sce.getServletContext(); + initApp(servletContext); + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + // destroy whatever + ServletContext ctx = sce.getServletContext(); + ctx.removeAttribute(MP_SENDER); + ctx.removeAttribute(MP_ABSPIELER); + ctx.removeAttribute(RZ_SQL_PROPERTIES); + ctx.removeAttribute(RZ_DB); + } + +} diff --git a/web/WEB-INF/create_database.sql b/web/WEB-INF/create_database.sql index 4acca8e..d1dfd5e 100644 --- a/web/WEB-INF/create_database.sql +++ b/web/WEB-INF/create_database.sql @@ -17,7 +17,7 @@ abs_typ varchar(1024), abs_bild varchar(1024), abs_zustand varchar(1024), - primary key (sender_id) + primary key (abs_id) ); create index aname on app.abspieler (abs_name); diff --git a/web/WEB-INF/sql.properties b/web/WEB-INF/sql.properties new file mode 100644 index 0000000..5881357 --- /dev/null +++ b/web/WEB-INF/sql.properties @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> +<properties> + <comment> + SQL-Kommandos der Anwendung radiozentrale + </comment> + <entry key="dbVorhanden"> + select s.schemaname, t.tablename + from SYS.SYSSCHEMAS as s, + SYS.SYSTABLES as t + where s.schemaid = t.schemaid + and s.schemaname = 'APP' + and t.tablename = 'SENDER' + </entry> + <entry key="incrementKey"> + update app.keytable + set key_next = ? + where key_name = ? + and key_next = ? + </entry> + <entry key="getNextKey"> + select key_next from + app.keytable + where key_name = ? + </entry> +</properties> diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml index 10e1198..1f4d8f3 100644 --- a/web/WEB-INF/web.xml +++ b/web/WEB-INF/web.xml @@ -6,6 +6,9 @@ <param-name>dsname</param-name> <param-value>jdbc/RadioDB</param-value> </context-param> + <listener> + <listener-class>de.uhilger.radiozentrale.web.Initialiser</listener-class> + </listener> <session-config> <session-timeout> 30 -- Gitblit v1.9.3