ulrich
2018-02-24 5eee5633fa7504874bbd81840efa5965bedd7c15
Datenbank-Konfiguration ergaenzt, DAOs erzeugt, Initialiser erstellt
4 files added
2 files modified
416 ■■■■■ changed files
src/java/de/uhilger/radiozentrale/daten/Abspieler.java 94 ●●●●● patch | view | raw | blame | history
src/java/de/uhilger/radiozentrale/daten/Sender.java 73 ●●●●● patch | view | raw | blame | history
src/java/de/uhilger/radiozentrale/web/Initialiser.java 218 ●●●●● patch | view | raw | blame | history
web/WEB-INF/create_database.sql 2 ●●● patch | view | raw | blame | history
web/WEB-INF/sql.properties 26 ●●●●● patch | view | raw | blame | history
web/WEB-INF/web.xml 3 ●●●●● patch | view | raw | blame | history
src/java/de/uhilger/radiozentrale/daten/Abspieler.java
New file
@@ -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;
  }
}
src/java/de/uhilger/radiozentrale/daten/Sender.java
New file
@@ -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;
  }
}
src/java/de/uhilger/radiozentrale/web/Initialiser.java
New file
@@ -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);
  }
}
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);
web/WEB-INF/sql.properties
New file
@@ -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>
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