ulrich
2016-12-27 627850aeb788606f3c4a5ee5f59784b7a0ee5fc3
commit | author | age
7fb4d9 1 package de.uhilger.um;
U 2
314fea 3 import de.uhilger.baselink.PersistenceManager;
U 4 import de.uhilger.baselink.Record;
5 import java.io.BufferedReader;
6 import java.io.File;
7 import java.io.FileInputStream;
8 import java.io.IOException;
9 import java.io.InputStream;
10 import java.io.InputStreamReader;
11 import java.util.List;
12 import java.util.Properties;
13 import java.util.logging.Level;
14 import java.util.logging.Logger;
15 import javax.servlet.ServletContext;
7fb4d9 16 import javax.servlet.ServletContextEvent;
U 17 import javax.servlet.ServletContextListener;
18
19 /**
20  * Hauptklasse der Anwendung Nutzerverwaltung
21  * 
22  * Hier wird u.a. geprüft, ob die Datenbank vorhanden ist und diese 
627850 23  * angelegt, falls nicht. Das SQL zur Anlage der Datenbank findet 
U 24  * sich in WEB-INF/create_database.sql
7fb4d9 25  * 
U 26  * @author Ulrich Hilger
27  */
28 public class App implements ServletContextListener {
314fea 29   
U 30   private static final Logger logger = Logger.getLogger(App.class.getName());
7fb4d9 31
314fea 32   /** Name der Datei mit dem SQL-Skript zum Erzeugen der Datenbank */
U 33   private static final String SCRIPT_NAME = "create_database.sql";  
34   /** Name der Datei mit den SQL-Kommandos dieser Anwendung */
35   public static final String SQL_PROPERTIES_NAME = "sql.properties";
36   /** Name, unter dem das Properties-Objekt mit den SQL-Befehlen im ServletContext hinterlegt ist */
37   public static final String UM_SQL_PROPERTIES = "umSqlProperties";
38   /** Name des Parameters, unter dem der Name der DataSource im Deployment Descritpor zu finden ist */
39   public static final String P_DSNAME = "dsname";
40   
41   /** Name des SQL-Befehls zum Pruefen, ob die Datenbank vorhanden ist */
42   public static final String SQL_DB_VORHANDEN = "dbVorhanden";  
43   
627850 44   /** Boolean-Konstante zur Kennzeichnung von Datenbankergebnissen mit/ohne Blobs */
725d10 45   public static final boolean WITHOUT_BLOBS = false;
U 46
627850 47   /** Anwendungsweite Referenz zur Datenbank */
314fea 48   private static PersistenceManager db;
627850 49   
U 50   /** Anwendungsweite Referenz zu den SQL-Befehlen */
314fea 51   private static Properties sql;
U 52   
53  /**
54    * Ein Eigenschaften-Objekt mit den SQL-Statements initialisieren, 
55    * die von dieser Webanwendung verwendet werden
56    * 
57    * Die SQL-Kommandos werden aus der Datei 
58    * [CatalinaBase]/webapps/[Context]/WEB-INF/sql.properties 
59    * gelesen und als Properties-Objekt unter dem von der Konstante 
60    * SPOT_SQL_PROPERTIES bezeichneten Namen im ServletContext hinterlegt
61    */
62   private void initSql(ServletContext servletContext) {
63     try {
64       File basis = new File(this.getClass().getResource("/").toURI());
65       File sqlFile = new File(basis.getParentFile(), SQL_PROPERTIES_NAME);
66       logger.fine("lese SQL-Eigenschaften von " + sqlFile.getAbsolutePath());
67       sql = new Properties();
68       sql.loadFromXML(new FileInputStream(sqlFile));
69       servletContext.setAttribute(UM_SQL_PROPERTIES, sql);
70       logger.fine("Abfrage dbVorhanden='" + sql.getProperty(SQL_DB_VORHANDEN) + "'");
71     } catch(Exception ex) {
72       logger.log(Level.SEVERE, ex.getMessage(), ex);
73     }
74   }
75
76   /* ----------------- statische Getter --------------------- */
77   
78   /**
79    * Das Zugriffsobjekt fuer die Datenbank dieser Webanwendung 
80    * ermitteln
81    * 
82    * @return das Zugriffsobjekt zur Datenbank dieser Webanwendung
83    */
84   public static PersistenceManager getDatabase() {
85     if(db == null) {
86       db = new PersistenceManager();
87     }
88     return db;
89   }
90   
77e6a4 91   /**
U 92    * Ein benanntes SQL-Kommando ermitteln 
93    * @param id Name des gewuenschten SQL-Kommandos
94    * @return das SQL-Kommando mit der in id angegebenen Bezeichnung 
95    */
314fea 96   public static String getSqlStatement(String id) {
U 97     return sql.getProperty(id);
98   }
99   
100   /* ----------------- Logik zur Datenbank-Erzeugung ------------ */
101   
102   /*
103     Die Logik zur Datenbank-Erzeugung benoetigt zwei Parameter: 
104       1. den Namen der DataSource
105       2. einen SQL-Befehl, mit dem geprueft werden kann, ob die 
106           Datenbank vorhanden ist
107   
108     Der Name der DataSource ist im Deployment Descriptor unter dem mit 
109     P_DSNAME bezeichneten Namen hinterlegt, der SQL-Befehl ist 
110     im Properties-Objekt mit den SQL-Befehlen dieser Anwendung unter dem 
111     mit SQL_DB_VORHANDEN bezeichneten Namen zu finden.
112   */
113   
114   /**
115    * Pruefen, ob die von dieser Webanwendung benoetigte Datenbank 
116    * vorhanden ist. Erzeugen der Datenbank, wenn sie nicht vorgefunden 
117    * wird.
118    * 
119    * @param servletContext der ServletContext dieser Webanwendung, in dem 
120    * die Parameter zu finden sind, welche die Datenbankverbindung beschreiben
121    */
122   private void initDb(ServletContext servletContext) {
123     try {
124       db = new PersistenceManager();
125       db.setDataSourceName(servletContext.getInitParameter(P_DSNAME));
126       Properties sql = (Properties) servletContext.getAttribute(UM_SQL_PROPERTIES);
127       if(!dbVorhanden(db, sql.getProperty(SQL_DB_VORHANDEN))) {
128         logger.info("Datenbank ist nicht vorhanden");
129         int[] ergebnis = db.executeScript(getSqlSkript());
130       }
131     } catch(Exception ex) {
132       logger.log(Level.INFO, ex.getMessage(), ex);
133     }
134   }
135   
136   @SuppressWarnings("rawtypes")
137   private boolean dbVorhanden(PersistenceManager pm, String sql) {
138     boolean istVorhanden = false;
139     List<List<String>> list = pm.select(sql, Record.WITHOUT_BLOBS);
140     if(list.size() > 1) {
141       istVorhanden = true;
142       logger.fine("Datenbank ist vorhanden");
143     }
144     return istVorhanden;
145   }
146     
147   private String getSqlSkript() throws Exception {
148     File basis = new File(this.getClass().getResource("/").toURI());
149     File skript = new File(basis.getParentFile(), SCRIPT_NAME);
150     return fromStream(new FileInputStream(skript));
151   }
152   
153   private String fromStream(InputStream in) throws IOException
154   {
155     BufferedReader reader = new BufferedReader(new InputStreamReader(in));
156     StringBuilder out = new StringBuilder();
157     String line;
158     while ((line = reader.readLine()) != null) {
159       out.append(line);
160     }
161     return out.toString();
162   }
163
164   /* --- ServletContextListener --- */
165   
7fb4d9 166   @Override
U 167   public void contextInitialized(ServletContextEvent sce) {
314fea 168     ServletContext servletContext = sce.getServletContext();
U 169     initSql(servletContext);
170     initDb(servletContext);
7fb4d9 171   }
U 172
173   @Override
174   public void contextDestroyed(ServletContextEvent sce) {
175     // destroy whatever 
176   }
177   
178 }