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