ulrich
2017-02-11 1345f04c927a319d1f541d420250e94bb949fbdd
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   
1345f0 65   public static final String MP_USER = "userMapper";
U 66   public static final String MP_USER_DATA = "userDataMapper";
67   public static final String MP_USER_ROLE = "userRoleMapper";
68   
1fc020 69   /**
U 70    * Diese Webanwendung initialisieren, also z.B. Elemente instantiieren, die
71    * über den Deployment Descritpor veränderlich gehalten sind.
72    * 
73    * @param servletContext  der zur Laufzeit bestehende ServletContext
74    */
6240cd 75   private void initApp(ServletContext servletContext) {
U 76     try {
1fc020 77       initSql(servletContext);
U 78       initDb(servletContext);
6240cd 79     } catch (Exception ex) {
U 80       logger.log(Level.SEVERE, null, ex);
81     }
82   }
314fea 83   
U 84  /**
85    * Ein Eigenschaften-Objekt mit den SQL-Statements initialisieren, 
86    * die von dieser Webanwendung verwendet werden
87    * 
88    * Die SQL-Kommandos werden aus der Datei 
89    * [CatalinaBase]/webapps/[Context]/WEB-INF/sql.properties 
90    * gelesen und als Properties-Objekt unter dem von der Konstante 
91    * SPOT_SQL_PROPERTIES bezeichneten Namen im ServletContext hinterlegt
92    */
93   private void initSql(ServletContext servletContext) {
94     try {
95       File basis = new File(this.getClass().getResource("/").toURI());
96       File sqlFile = new File(basis.getParentFile(), SQL_PROPERTIES_NAME);
97       logger.fine("lese SQL-Eigenschaften von " + sqlFile.getAbsolutePath());
35c04d 98       Properties sql = new Properties();
314fea 99       sql.loadFromXML(new FileInputStream(sqlFile));
1fc020 100       servletContext.setAttribute(UserMgr.UM_SQL_PROPERTIES, sql);
314fea 101       logger.fine("Abfrage dbVorhanden='" + sql.getProperty(SQL_DB_VORHANDEN) + "'");
U 102     } catch(Exception ex) {
103       logger.log(Level.SEVERE, ex.getMessage(), ex);
104     }
105   }
106   
107   /* ----------------- Logik zur Datenbank-Erzeugung ------------ */
108   
109   /*
110     Die Logik zur Datenbank-Erzeugung benoetigt zwei Parameter: 
111       1. den Namen der DataSource
112       2. einen SQL-Befehl, mit dem geprueft werden kann, ob die 
113           Datenbank vorhanden ist
114   
115     Der Name der DataSource ist im Deployment Descriptor unter dem mit 
116     P_DSNAME bezeichneten Namen hinterlegt, der SQL-Befehl ist 
117     im Properties-Objekt mit den SQL-Befehlen dieser Anwendung unter dem 
118     mit SQL_DB_VORHANDEN bezeichneten Namen zu finden.
119   */
120   
121   /**
122    * Pruefen, ob die von dieser Webanwendung benoetigte Datenbank 
123    * vorhanden ist. Erzeugen der Datenbank, wenn sie nicht vorgefunden 
124    * wird.
125    * 
126    * @param servletContext der ServletContext dieser Webanwendung, in dem 
127    * die Parameter zu finden sind, welche die Datenbankverbindung beschreiben
128    */
129   private void initDb(ServletContext servletContext) {
130     try {
35c04d 131       PersistenceManager db = new PersistenceManager();
314fea 132       db.setDataSourceName(servletContext.getInitParameter(P_DSNAME));
35c04d 133       servletContext.setAttribute(UserMgr.UM_DB, db);
70a614 134       initMapper(servletContext);
1fc020 135       Properties sql = (Properties) servletContext.getAttribute(UserMgr.UM_SQL_PROPERTIES);
314fea 136       if(!dbVorhanden(db, sql.getProperty(SQL_DB_VORHANDEN))) {
U 137         logger.info("Datenbank ist nicht vorhanden");
138         int[] ergebnis = db.executeScript(getSqlSkript());
57c58d 139         User admin = new User();
U 140         admin.setId("admin");
141         admin.setPw("admin");
61cf48 142         admin.setFirstName("admin");
U 143         admin.setLastName("admin");
144         admin.setEmail("none");
57c58d 145         UserMgr um = new UserMgr();
U 146         um.setServletContext(servletContext);
147         um.createUser(admin);
314fea 148       }
U 149     } catch(Exception ex) {
150       logger.log(Level.INFO, ex.getMessage(), ex);
151     }
152   }
153   
70a614 154   /**
U 155    * Mapper erzeugen
156    * @param servletContext der ServletContext dieser Webanwendung
157    */
158   /*
159   TODO: das noch auf on demand anlegen: GenericRecord wird erst angelegt
160    wenn er erstmals benoetigt wird. Ggf. auch einen Mechanismus zum entfernen 
161    laenger nicht benoetigter Mapper hinzufuegen
162   */
163   private void initMapper(ServletContext servletContext) {
164     servletContext.setAttribute(UserMgr.MP_USER, new GenericRecord(User.class));
165     servletContext.setAttribute(UserMgr.MP_USER_DATA, new GenericRecord(UserData.class));
166     servletContext.setAttribute(UserMgr.MP_USER_ROLE, new GenericRecord(UserRole.class));
167   }
168   
314fea 169   @SuppressWarnings("rawtypes")
U 170   private boolean dbVorhanden(PersistenceManager pm, String sql) {
171     boolean istVorhanden = false;
172     List<List<String>> list = pm.select(sql, Record.WITHOUT_BLOBS);
61cf48 173     if(list != null && list.size() > 1) {
314fea 174       istVorhanden = true;
U 175       logger.fine("Datenbank ist vorhanden");
176     }
177     return istVorhanden;
178   }
179     
180   private String getSqlSkript() throws Exception {
181     File basis = new File(this.getClass().getResource("/").toURI());
182     File skript = new File(basis.getParentFile(), SCRIPT_NAME);
183     return fromStream(new FileInputStream(skript));
184   }
185   
186   private String fromStream(InputStream in) throws IOException
187   {
188     BufferedReader reader = new BufferedReader(new InputStreamReader(in));
189     StringBuilder out = new StringBuilder();
190     String line;
191     while ((line = reader.readLine()) != null) {
192       out.append(line);
193     }
194     return out.toString();
195   }
196
197   /* --- ServletContextListener --- */
198   
7fb4d9 199   @Override
U 200   public void contextInitialized(ServletContextEvent sce) {
314fea 201     ServletContext servletContext = sce.getServletContext();
6240cd 202     initApp(servletContext);
7fb4d9 203   }
U 204
205   @Override
206   public void contextDestroyed(ServletContextEvent sce) {
207     // destroy whatever 
208   }
209   
210 }