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
+   * &uuml;ber den Deployment Descritpor ver&auml;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