ulrich
2016-11-27 314feae8ddc3dc4bf286ab5c7d6e0c1df5fc3518
dbInit hinzugefuegt
3 files modified
2 files added
249 ■■■■■ changed files
src/java/de/uhilger/um/App.java 143 ●●●●● patch | view | raw | blame | history
web/META-INF/context.xml 14 ●●●●● patch | view | raw | blame | history
web/WEB-INF/create_database.sql 41 ●●●●● patch | view | raw | blame | history
web/WEB-INF/sql.properties 47 ●●●●● patch | view | raw | blame | history
web/WEB-INF/web.xml 4 ●●●● patch | view | raw | blame | history
src/java/de/uhilger/um/App.java
@@ -1,5 +1,18 @@
package de.uhilger.um;
import de.uhilger.baselink.PersistenceManager;
import de.uhilger.baselink.Record;
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;
@@ -12,10 +25,138 @@
 * @author Ulrich Hilger
 */
public class App implements ServletContextListener {
  private static final Logger logger = Logger.getLogger(App.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, unter dem das Properties-Objekt mit den SQL-Befehlen im ServletContext hinterlegt ist */
  public static final String UM_SQL_PROPERTIES = "umSqlProperties";
  /** Name des Parameters, unter dem der Name der DataSource im Deployment Descritpor zu finden ist */
  public static final String P_DSNAME = "dsname";
  /** Name des SQL-Befehls zum Pruefen, ob die Datenbank vorhanden ist */
  public static final String SQL_DB_VORHANDEN = "dbVorhanden";
  private static PersistenceManager db;
  private static Properties sql;
 /**
   * 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());
      sql = new Properties();
      sql.loadFromXML(new FileInputStream(sqlFile));
      servletContext.setAttribute(UM_SQL_PROPERTIES, sql);
      logger.fine("Abfrage dbVorhanden='" + sql.getProperty(SQL_DB_VORHANDEN) + "'");
    } catch(Exception ex) {
      logger.log(Level.SEVERE, ex.getMessage(), ex);
    }
  }
  /* ----------------- statische Getter --------------------- */
  /**
   * Das Zugriffsobjekt fuer die Datenbank dieser Webanwendung
   * ermitteln
   *
   * @return das Zugriffsobjekt zur Datenbank dieser Webanwendung
   */
  public static PersistenceManager getDatabase() {
    if(db == null) {
      db = new PersistenceManager();
    }
    return db;
  }
  public static String getSqlStatement(String id) {
    return sql.getProperty(id);
  }
  /* ----------------- 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 {
      db = new PersistenceManager();
      db.setDataSourceName(servletContext.getInitParameter(P_DSNAME));
      Properties sql = (Properties) servletContext.getAttribute(UM_SQL_PROPERTIES);
      if(!dbVorhanden(db, sql.getProperty(SQL_DB_VORHANDEN))) {
        logger.info("Datenbank ist nicht vorhanden");
        int[] ergebnis = db.executeScript(getSqlSkript());
      }
    } catch(Exception ex) {
      logger.log(Level.INFO, ex.getMessage(), ex);
    }
  }
  @SuppressWarnings("rawtypes")
  private boolean dbVorhanden(PersistenceManager pm, String sql) {
    boolean istVorhanden = false;
    List<List<String>> list = pm.select(sql, Record.WITHOUT_BLOBS);
    if(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) {
    // do some initialisation here
    ServletContext servletContext = sce.getServletContext();
    initSql(servletContext);
    initDb(servletContext);
  }
  @Override
web/META-INF/context.xml
@@ -1,2 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/um"/>
<Context antiJARLocking="true" path="/um">
  <Resource name="jdbc/UserDB"
      auth="Container"
      type="javax.sql.DataSource"
      username="dbadmin"
      password="changeit"
      driverClassName="org.apache.derby.jdbc.ClientDriver"
      url="jdbc:derby://127.0.0.1:1527/udb;create=true"
      maxActive="60"
      maxIdle="30"
      maxWait="5000"
  />
</Context>
web/WEB-INF/create_database.sql
New file
@@ -0,0 +1,41 @@
CREATE TABLE APP.USERS
(
   USER_NAME     VARCHAR(250)   NOT NULL,
   USER_PASS     VARCHAR(250)   NOT NULL,
   USER_FIRST    VARCHAR(250),
   USER_LAST     VARCHAR(250),
   USER_EMAIL    VARCHAR(250),
   USER_CREATED  VARCHAR(14),
   PRIMARY KEY (USER_NAME)
);
CREATE TABLE APP.USER_ROLES
(
   USER_NAME  VARCHAR(250)   NOT NULL,
   ROLE_NAME  VARCHAR(250)   NOT NULL,
   PRIMARY KEY (USER_NAME, ROLE_NAME)
);
create table APP.keytable (
  key_name            varchar(80) not null primary key,
    key_next            int
);
create index key_name_next ON APP.keytable (key_name,key_next);
insert into APP.keytable (key_name, key_next) values ('gr_id',1);
insert into APP.keytable (key_name, key_next) values ('mt_id',1);
create table APP.methoden (
  mt_id       int,
  mt_klasse   varchar(32000),
  mt_name     varchar(32000),
  primary key (mt_id)
);
create index mtkm on APP.methoden (mt_klasse,mt_name);
create table APP.methoden_rechte (
  role_name   varchar(250),
  mt_id       int,
  primary key (role_name,mt_id)
);
web/WEB-INF/sql.properties
New file
@@ -0,0 +1,47 @@
<?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 Nutzerverwaltung
  </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 = 'USER'
  </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>
  <entry key="getTrackpoints">
    select * from
    app.orte
    where or_zeit larger ?
    and or_zeit smaller ?
    and or_pers_id = ?
  </entry>
  <entry key="getFirstTrackpoint">
    select * from
    app.orte
    where or_zeit larger ?
    and or_zeit smaller ?
    and or_pers_id = ?
    fetch first row only
  </entry>
  <entry key="getDateList">
    select substr(or_zeit,1,8) as tag, count(*) as anz from app.orte as orte
    where or_pers_id = ?
    and substr(or_zeit,1,8) like ?
    group by substr(or_zeit,1,8)
  </entry>
</properties>
web/WEB-INF/web.xml
@@ -1,6 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>Nutzerverwaltung</display-name>
    <context-param>
        <param-name>dsname</param-name>
        <param-value>jdbc/UserDB</param-value>
    </context-param>
    <session-config>
        <session-timeout>
            30