ulrich
2016-12-27 7f8a035fd7d290be1c7ba01956097cab466c9200
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,145 @@
 * @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";
  public static final boolean WITHOUT_BLOBS = false;
  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;
  }
  /**
   * Ein benanntes SQL-Kommando ermitteln
   * @param id Name des gewuenschten SQL-Kommandos
   * @return das SQL-Kommando mit der in id angegebenen Bezeichnung
   */
  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