ulrich
2016-12-27 6240cdca43495122d436de8488395bf7fd5eae12
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   
6240cd 41   public static final String P_DIGESTER = "digester";
U 42   
314fea 43   /** Name des SQL-Befehls zum Pruefen, ob die Datenbank vorhanden ist */
U 44   public static final String SQL_DB_VORHANDEN = "dbVorhanden";  
45   
627850 46   /** Boolean-Konstante zur Kennzeichnung von Datenbankergebnissen mit/ohne Blobs */
725d10 47   public static final boolean WITHOUT_BLOBS = false;
U 48
627850 49   /** Anwendungsweite Referenz zur Datenbank */
314fea 50   private static PersistenceManager db;
627850 51   
U 52   /** Anwendungsweite Referenz zu den SQL-Befehlen */
314fea 53   private static Properties sql;
6240cd 54   
U 55   private static Digester digester;
56   
57   private void initApp(ServletContext servletContext) {
58     try {
59       String digesterClassName = servletContext.getInitParameter(P_DIGESTER);
60       digester = (Digester) Class.forName(digesterClassName).newInstance();
61     } catch (Exception ex) {
62       logger.log(Level.SEVERE, null, ex);
63     }
64   }
314fea 65   
U 66  /**
67    * Ein Eigenschaften-Objekt mit den SQL-Statements initialisieren, 
68    * die von dieser Webanwendung verwendet werden
69    * 
70    * Die SQL-Kommandos werden aus der Datei 
71    * [CatalinaBase]/webapps/[Context]/WEB-INF/sql.properties 
72    * gelesen und als Properties-Objekt unter dem von der Konstante 
73    * SPOT_SQL_PROPERTIES bezeichneten Namen im ServletContext hinterlegt
74    */
75   private void initSql(ServletContext servletContext) {
76     try {
77       File basis = new File(this.getClass().getResource("/").toURI());
78       File sqlFile = new File(basis.getParentFile(), SQL_PROPERTIES_NAME);
79       logger.fine("lese SQL-Eigenschaften von " + sqlFile.getAbsolutePath());
80       sql = new Properties();
81       sql.loadFromXML(new FileInputStream(sqlFile));
82       servletContext.setAttribute(UM_SQL_PROPERTIES, sql);
83       logger.fine("Abfrage dbVorhanden='" + sql.getProperty(SQL_DB_VORHANDEN) + "'");
84     } catch(Exception ex) {
85       logger.log(Level.SEVERE, ex.getMessage(), ex);
86     }
87   }
88
89   /* ----------------- statische Getter --------------------- */
90   
91   /**
92    * Das Zugriffsobjekt fuer die Datenbank dieser Webanwendung 
93    * ermitteln
94    * 
95    * @return das Zugriffsobjekt zur Datenbank dieser Webanwendung
96    */
97   public static PersistenceManager getDatabase() {
98     if(db == null) {
99       db = new PersistenceManager();
100     }
101     return db;
102   }
103   
77e6a4 104   /**
U 105    * Ein benanntes SQL-Kommando ermitteln 
106    * @param id Name des gewuenschten SQL-Kommandos
107    * @return das SQL-Kommando mit der in id angegebenen Bezeichnung 
108    */
314fea 109   public static String getSqlStatement(String id) {
U 110     return sql.getProperty(id);
6240cd 111   }
U 112   
113   public static Digester getDigester() {
114     return digester;
314fea 115   }
U 116   
117   /* ----------------- Logik zur Datenbank-Erzeugung ------------ */
118   
119   /*
120     Die Logik zur Datenbank-Erzeugung benoetigt zwei Parameter: 
121       1. den Namen der DataSource
122       2. einen SQL-Befehl, mit dem geprueft werden kann, ob die 
123           Datenbank vorhanden ist
124   
125     Der Name der DataSource ist im Deployment Descriptor unter dem mit 
126     P_DSNAME bezeichneten Namen hinterlegt, der SQL-Befehl ist 
127     im Properties-Objekt mit den SQL-Befehlen dieser Anwendung unter dem 
128     mit SQL_DB_VORHANDEN bezeichneten Namen zu finden.
129   */
130   
131   /**
132    * Pruefen, ob die von dieser Webanwendung benoetigte Datenbank 
133    * vorhanden ist. Erzeugen der Datenbank, wenn sie nicht vorgefunden 
134    * wird.
135    * 
136    * @param servletContext der ServletContext dieser Webanwendung, in dem 
137    * die Parameter zu finden sind, welche die Datenbankverbindung beschreiben
138    */
139   private void initDb(ServletContext servletContext) {
140     try {
141       db = new PersistenceManager();
142       db.setDataSourceName(servletContext.getInitParameter(P_DSNAME));
143       Properties sql = (Properties) servletContext.getAttribute(UM_SQL_PROPERTIES);
144       if(!dbVorhanden(db, sql.getProperty(SQL_DB_VORHANDEN))) {
145         logger.info("Datenbank ist nicht vorhanden");
146         int[] ergebnis = db.executeScript(getSqlSkript());
147       }
148     } catch(Exception ex) {
149       logger.log(Level.INFO, ex.getMessage(), ex);
150     }
151   }
152   
153   @SuppressWarnings("rawtypes")
154   private boolean dbVorhanden(PersistenceManager pm, String sql) {
155     boolean istVorhanden = false;
156     List<List<String>> list = pm.select(sql, Record.WITHOUT_BLOBS);
157     if(list.size() > 1) {
158       istVorhanden = true;
159       logger.fine("Datenbank ist vorhanden");
160     }
161     return istVorhanden;
162   }
163     
164   private String getSqlSkript() throws Exception {
165     File basis = new File(this.getClass().getResource("/").toURI());
166     File skript = new File(basis.getParentFile(), SCRIPT_NAME);
167     return fromStream(new FileInputStream(skript));
168   }
169   
170   private String fromStream(InputStream in) throws IOException
171   {
172     BufferedReader reader = new BufferedReader(new InputStreamReader(in));
173     StringBuilder out = new StringBuilder();
174     String line;
175     while ((line = reader.readLine()) != null) {
176       out.append(line);
177     }
178     return out.toString();
179   }
180
181   /* --- ServletContextListener --- */
182   
7fb4d9 183   @Override
U 184   public void contextInitialized(ServletContextEvent sce) {
314fea 185     ServletContext servletContext = sce.getServletContext();
U 186     initSql(servletContext);
187     initDb(servletContext);
6240cd 188     initApp(servletContext);
7fb4d9 189   }
U 190
191   @Override
192   public void contextDestroyed(ServletContextEvent sce) {
193     // destroy whatever 
194   }
195   
196 }