ulrich
2017-02-12 b4b5eb1c0f1c4f40caab62ad2363b21a8c1e2919
commit | author | age
51c9e3 1 /*
U 2  *  Nutzerverwaltung - User and role management in your browser
3  *  Copyright (C) 2011-2016 Ulrich Hilger, http://uhilger.de
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see http://www.gnu.org/licenses/
17  */
18
19 package de.uhilger.um.web;
7fb4d9 20
70a614 21 import de.uhilger.baselink.GenericRecord;
314fea 22 import de.uhilger.baselink.PersistenceManager;
U 23 import de.uhilger.baselink.Record;
1fc020 24 import de.uhilger.um.api.UserMgr;
57c58d 25 import de.uhilger.um.daten.User;
70a614 26 import de.uhilger.um.daten.UserData;
U 27 import de.uhilger.um.daten.UserRole;
314fea 28 import java.io.BufferedReader;
U 29 import java.io.File;
30 import java.io.FileInputStream;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.InputStreamReader;
34 import java.util.List;
35 import java.util.Properties;
36 import java.util.logging.Level;
37 import java.util.logging.Logger;
38 import javax.servlet.ServletContext;
7fb4d9 39 import javax.servlet.ServletContextEvent;
U 40 import javax.servlet.ServletContextListener;
41
42 /**
b7910b 43  * Initialisierungsklasse der Anwendung Nutzerverwaltung
7fb4d9 44  * 
U 45  * Hier wird u.a. geprüft, ob die Datenbank vorhanden ist und diese 
b7910b 46  * angelegt, falls nicht. Das SQL-Skript zur Anlage der Datenbank findet 
627850 47  * sich in WEB-INF/create_database.sql
7fb4d9 48  * 
U 49  * @author Ulrich Hilger
50  */
b7910b 51 public class Initialiser implements ServletContextListener {
314fea 52   
b7910b 53   private static final Logger logger = Logger.getLogger(Initialiser.class.getName());
7fb4d9 54
314fea 55   /** Name der Datei mit dem SQL-Skript zum Erzeugen der Datenbank */
U 56   private static final String SCRIPT_NAME = "create_database.sql";  
57   /** Name der Datei mit den SQL-Kommandos dieser Anwendung */
58   public static final String SQL_PROPERTIES_NAME = "sql.properties";
59   /** Name des Parameters, unter dem der Name der DataSource im Deployment Descritpor zu finden ist */
60   public static final String P_DSNAME = "dsname";
35c04d 61     
314fea 62   /** Name des SQL-Befehls zum Pruefen, ob die Datenbank vorhanden ist */
U 63   public static final String SQL_DB_VORHANDEN = "dbVorhanden";  
64   
1fc020 65   /**
U 66    * Diese Webanwendung initialisieren, also z.B. Elemente instantiieren, die
67    * über den Deployment Descritpor veränderlich gehalten sind.
68    * 
69    * @param servletContext  der zur Laufzeit bestehende ServletContext
70    */
6240cd 71   private void initApp(ServletContext servletContext) {
U 72     try {
1fc020 73       initSql(servletContext);
U 74       initDb(servletContext);
6240cd 75     } catch (Exception ex) {
U 76       logger.log(Level.SEVERE, null, ex);
77     }
78   }
314fea 79   
U 80  /**
81    * Ein Eigenschaften-Objekt mit den SQL-Statements initialisieren, 
82    * die von dieser Webanwendung verwendet werden
83    * 
84    * Die SQL-Kommandos werden aus der Datei 
85    * [CatalinaBase]/webapps/[Context]/WEB-INF/sql.properties 
86    * gelesen und als Properties-Objekt unter dem von der Konstante 
87    * SPOT_SQL_PROPERTIES bezeichneten Namen im ServletContext hinterlegt
88    */
89   private void initSql(ServletContext servletContext) {
90     try {
91       File basis = new File(this.getClass().getResource("/").toURI());
92       File sqlFile = new File(basis.getParentFile(), SQL_PROPERTIES_NAME);
93       logger.fine("lese SQL-Eigenschaften von " + sqlFile.getAbsolutePath());
35c04d 94       Properties sql = new Properties();
314fea 95       sql.loadFromXML(new FileInputStream(sqlFile));
1fc020 96       servletContext.setAttribute(UserMgr.UM_SQL_PROPERTIES, sql);
314fea 97       logger.fine("Abfrage dbVorhanden='" + sql.getProperty(SQL_DB_VORHANDEN) + "'");
U 98     } catch(Exception ex) {
99       logger.log(Level.SEVERE, ex.getMessage(), ex);
100     }
101   }
102   
103   /* ----------------- Logik zur Datenbank-Erzeugung ------------ */
104   
105   /*
106     Die Logik zur Datenbank-Erzeugung benoetigt zwei Parameter: 
107       1. den Namen der DataSource
108       2. einen SQL-Befehl, mit dem geprueft werden kann, ob die 
109           Datenbank vorhanden ist
110   
111     Der Name der DataSource ist im Deployment Descriptor unter dem mit 
112     P_DSNAME bezeichneten Namen hinterlegt, der SQL-Befehl ist 
113     im Properties-Objekt mit den SQL-Befehlen dieser Anwendung unter dem 
114     mit SQL_DB_VORHANDEN bezeichneten Namen zu finden.
115   */
116   
117   /**
118    * Pruefen, ob die von dieser Webanwendung benoetigte Datenbank 
119    * vorhanden ist. Erzeugen der Datenbank, wenn sie nicht vorgefunden 
120    * wird.
121    * 
122    * @param servletContext der ServletContext dieser Webanwendung, in dem 
123    * die Parameter zu finden sind, welche die Datenbankverbindung beschreiben
124    */
125   private void initDb(ServletContext servletContext) {
126     try {
35c04d 127       PersistenceManager db = new PersistenceManager();
314fea 128       db.setDataSourceName(servletContext.getInitParameter(P_DSNAME));
35c04d 129       servletContext.setAttribute(UserMgr.UM_DB, db);
70a614 130       initMapper(servletContext);
1fc020 131       Properties sql = (Properties) servletContext.getAttribute(UserMgr.UM_SQL_PROPERTIES);
314fea 132       if(!dbVorhanden(db, sql.getProperty(SQL_DB_VORHANDEN))) {
U 133         logger.info("Datenbank ist nicht vorhanden");
134         int[] ergebnis = db.executeScript(getSqlSkript());
57c58d 135         User admin = new User();
U 136         admin.setId("admin");
137         admin.setPw("admin");
61cf48 138         admin.setFirstName("admin");
U 139         admin.setLastName("admin");
140         admin.setEmail("none");
57c58d 141         UserMgr um = new UserMgr();
U 142         um.setServletContext(servletContext);
143         um.createUser(admin);
314fea 144       }
U 145     } catch(Exception ex) {
146       logger.log(Level.INFO, ex.getMessage(), ex);
147     }
148   }
149   
70a614 150   /**
U 151    * Mapper erzeugen
152    * @param servletContext der ServletContext dieser Webanwendung
153    */
154   /*
155   TODO: das noch auf on demand anlegen: GenericRecord wird erst angelegt
156    wenn er erstmals benoetigt wird. Ggf. auch einen Mechanismus zum entfernen 
157    laenger nicht benoetigter Mapper hinzufuegen
158   */
159   private void initMapper(ServletContext servletContext) {
160     servletContext.setAttribute(UserMgr.MP_USER, new GenericRecord(User.class));
161     servletContext.setAttribute(UserMgr.MP_USER_DATA, new GenericRecord(UserData.class));
162     servletContext.setAttribute(UserMgr.MP_USER_ROLE, new GenericRecord(UserRole.class));
163   }
164   
314fea 165   @SuppressWarnings("rawtypes")
U 166   private boolean dbVorhanden(PersistenceManager pm, String sql) {
167     boolean istVorhanden = false;
168     List<List<String>> list = pm.select(sql, Record.WITHOUT_BLOBS);
61cf48 169     if(list != null && list.size() > 1) {
314fea 170       istVorhanden = true;
U 171       logger.fine("Datenbank ist vorhanden");
172     }
173     return istVorhanden;
174   }
175     
176   private String getSqlSkript() throws Exception {
177     File basis = new File(this.getClass().getResource("/").toURI());
178     File skript = new File(basis.getParentFile(), SCRIPT_NAME);
179     return fromStream(new FileInputStream(skript));
180   }
181   
182   private String fromStream(InputStream in) throws IOException
183   {
184     BufferedReader reader = new BufferedReader(new InputStreamReader(in));
185     StringBuilder out = new StringBuilder();
186     String line;
187     while ((line = reader.readLine()) != null) {
188       out.append(line);
189     }
190     return out.toString();
191   }
192
193   /* --- ServletContextListener --- */
194   
7fb4d9 195   @Override
U 196   public void contextInitialized(ServletContextEvent sce) {
314fea 197     ServletContext servletContext = sce.getServletContext();
6240cd 198     initApp(servletContext);
7fb4d9 199   }
U 200
201   @Override
202   public void contextDestroyed(ServletContextEvent sce) {
203     // destroy whatever 
204   }
205   
206 }