KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jguard > ext > database > DatabaseUtils


1 /*
2  jGuard is a security framework based on top of jaas (java authentication and authorization security).
3  it is written for web applications, to resolve simply, access control problems.
4  version $Name$
5  http://sourceforge.net/projects/jguard/
6
7  Copyright (C) 2004 Charles GAY
8
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23
24  jGuard project home page:
25  http://sourceforge.net/projects/jguard/
26
27  */

28 package net.sf.jguard.ext.database;
29
30 import java.sql.Connection JavaDoc;
31 import java.sql.DatabaseMetaData JavaDoc;
32 import java.sql.PreparedStatement JavaDoc;
33 import java.sql.ResultSet JavaDoc;
34 import java.sql.SQLException JavaDoc;
35 import java.util.Arrays JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.List JavaDoc;
38 import java.util.Properties JavaDoc;
39 import java.util.logging.Logger JavaDoc;
40
41 /**
42  * utility class to create tables, sequences and foreign keys.
43  *
44  * @author <a HREF="mailto:diabolo512@users.sourceforge.net">Charles Gay</a>
45  *
46  */

47 public class DatabaseUtils {
48     private static final Logger JavaDoc logger = Logger.getLogger(DatabaseUtils.class.getName());
49
50     /**
51      * create the missing table, sequences and foreign_keys.
52      *
53      * @param props
54      * file containing sql queries
55      * @param connFactory connection factory
56      * jdbc connection
57      * @param tablesNames
58      * tables to create
59      * @param sequencesNames
60      * sequences to create
61      * @param foreignkeysNames
62      * foreign keys to create
63      */

64     public static void createRequiredDatabaseEntities(Properties JavaDoc props, ConnectionFactory connFactory, List JavaDoc sequencesNames,
65             List JavaDoc tablesNames, List JavaDoc foreignkeysNames) {
66
67         // we create sequences
68
createEntities(props, connFactory, sequencesNames, "SEQUENCE_PRESENCE");
69
70         // we create tables
71
createEntities(props, connFactory, tablesNames, "TABLE_PRESENCE");
72
73         // we create foreign keys
74
createForeignKeys(props, connFactory, foreignkeysNames);
75
76     }
77
78     private static String JavaDoc handleSensitiveCase(String JavaDoc original, DatabaseMetaData JavaDoc dbMetaData) throws SQLException JavaDoc {
79         boolean storesLowerCaseIdentifiers = dbMetaData.storesLowerCaseIdentifiers();
80         logger.finest(" database store lower case identifiers =" + storesLowerCaseIdentifiers);
81         boolean storesUpperCaseIdentifiers = dbMetaData.storesUpperCaseIdentifiers();
82         logger.finest(" database store upper case identifiers =" + storesUpperCaseIdentifiers);
83         if (storesLowerCaseIdentifiers) {
84             original = original.toLowerCase();
85         } else if (storesUpperCaseIdentifiers) {
86             original = original.toUpperCase();
87         }
88
89         return original;
90
91     }
92
93     private static void createForeignKeys(Properties JavaDoc props, ConnectionFactory connectionFactory, List JavaDoc foreignkeysNames) {
94         Connection JavaDoc conn = null;
95         try {
96             conn = connectionFactory.getConnection();
97             DatabaseMetaData JavaDoc dbMetaData = conn.getMetaData();
98
99             for (int i = 0; i < foreignkeysNames.size(); i++) {
100                 String JavaDoc foreignKeyName = (String JavaDoc) foreignkeysNames.get(i);
101                 String JavaDoc query = ((String JavaDoc) props.get(foreignKeyName));
102                 // is there any entity to create?
103
// => we check its presence into properties file
104
if (query != null) {
105                     try {
106                         // words have got this structure:
107
// alter table ${FK_TABLE_NAME} add constraint ${CONSTRAINT_NAME} foreign key (${FOREIGN_KEY_COLUMN_NAME})
108
// references ${PRIMARY_KEY_TABLE_NAME}
109
// 0 1 2 3 4 5 6 7 8 9 10
110
// 2,5,8,10 are the only grabbed words
111
List JavaDoc words = Arrays.asList(query.split(" "));
112                         /*
113                         if (words.size() != 11) {
114                             logger.severe(" the query for creating " + foreignKeyName + " must contains 11 words ");
115                             continue;
116                         }
117                         */

118                         String JavaDoc fkTableName = (String JavaDoc) words.get(2);
119                         String JavaDoc constraintName = (String JavaDoc) words.get(5);
120                         String JavaDoc fKeyColumnName = (String JavaDoc) words.get(8);// remove ()
121
fKeyColumnName = fKeyColumnName.replace('(', ' ');
122                         fKeyColumnName = fKeyColumnName.replace(')', ' ').trim();
123                         String JavaDoc pKeyTableName = (String JavaDoc) words.get(10);
124                         int pKeyIndex = pKeyTableName.indexOf("(");
125                         //SQL server include the column when we grab the primary key table name
126
//we remove it
127
if (pKeyIndex>0){
128                             pKeyTableName = pKeyTableName.substring(0,pKeyIndex);
129                         }
130                         
131                         ResultSet JavaDoc rs = dbMetaData.getImportedKeys(null, null, handleSensitiveCase(fkTableName, dbMetaData));
132                         boolean foreignKeyFound = false;
133                         while (rs.next()) {
134                             logger.finest("importedKeys for=" + fkTableName);
135                             String JavaDoc pkeyTableName2 = rs.getString("PKTABLE_NAME");
136                             logger.finest("PKTABLE_NAME=" + pkeyTableName2);
137                             String JavaDoc pkeyColumnName2 = rs.getString("PKCOLUMN_NAME");
138                             logger.finest("PKCOLUMN_NAME=" + pkeyColumnName2);
139                             String JavaDoc fkeyTableName2 = rs.getString("FKTABLE_NAME");
140                             logger.finest("FKTABLE_NAME=" + fkeyTableName2);
141                             String JavaDoc fkeyColumnName2 = rs.getString("FKCOLUMN_NAME");
142                             logger.finest("FKCOLUMN_NAME=" + fkeyColumnName2);
143                             String JavaDoc constraintName2 = rs.getString("FK_NAME");
144                             logger.finest("FK_NAME=" + constraintName2);
145                             String JavaDoc pkeyName2 = rs.getString("PK_NAME");
146                             logger.finest("PK_NAME=" + pkeyName2);
147                             if (fkTableName.equalsIgnoreCase(fkeyTableName2) && fKeyColumnName.equalsIgnoreCase(fkeyColumnName2)
148                                     && pKeyTableName.equalsIgnoreCase(pkeyTableName2)
149                                     && constraintName.equalsIgnoreCase(constraintName2)) {
150                                 // foreign key is already present
151
foreignKeyFound = true;
152                                 break;
153                             }
154
155                         }
156
157                         if (foreignKeyFound) {
158                             continue;
159                         }
160                         // we create the entity
161

162                         logger.finest("entity=" + foreignKeyName + " query=" + query);
163                         PreparedStatement JavaDoc ps2 = conn.prepareStatement(query);
164                         ps2.execute();
165                     } catch (SQLException JavaDoc sqle) {
166                         logger.severe("entity=" + foreignKeyName + " cannot be created . " + sqle.getMessage());
167                     }
168
169                 } else {
170                     logger.info(foreignKeyName + " entry is not present in the properties file ");
171                 }
172
173             }
174         } catch (SQLException JavaDoc e) {
175             logger.severe(" database metadata cannot be grabbed from the SQL connection ");
176         } finally {
177             try {
178                 conn.close();
179             } catch (SQLException JavaDoc e) {
180                 logger.severe(" connexion cannot be closed " + e.getMessage());
181             }
182         }
183
184     }
185
186     /**
187      * create sequences.
188      * @param props
189      * @param connectionFactory connection Factory
190      * @param entitiesNames
191      * tables name which permit to build sequence name
192      * @param presenceQueryKey
193      */

194     private static void createEntities(Properties JavaDoc props, ConnectionFactory connectionFactory, List JavaDoc entitiesNames,
195             String JavaDoc presenceQueryKey) {
196         Connection JavaDoc conn = null;
197         String JavaDoc presenceQuery = props.getProperty(presenceQueryKey);
198         try {
199             conn = connectionFactory.getConnection();
200             DatabaseMetaData JavaDoc dbMetaData = conn.getMetaData();
201             for (int i = 0; i < entitiesNames.size(); i++) {
202                 String JavaDoc entityName = (String JavaDoc) entitiesNames.get(i);
203
204                 // is there any entity to create?
205
// => we check its presence into properties file
206
if ((String JavaDoc) props.get(entityName) != null) {
207                     try {
208                         // does the entity is already present in the database?
209
String JavaDoc replacedPresenceQuery = presenceQuery.replaceFirst("\\?", handleSensitiveCase(entityName,
210                                 dbMetaData));
211                         PreparedStatement JavaDoc ps1 = conn.prepareStatement(replacedPresenceQuery);
212                         logger.finest(replacedPresenceQuery);
213                         ResultSet JavaDoc rs1 = ps1.executeQuery();
214                         if (rs1.next()) {
215                             // entity is already present
216
logger.finest(" entity " + entityName + " has been detected : " + rs1.getObject(1));
217                             continue;
218                         }
219                     } catch (SQLException JavaDoc e) {
220                         logger.finest(" entity " + entityName + " does not exists and will be created ");
221                     }
222                     try {
223                         // we create the entity
224
String JavaDoc query2 = (String JavaDoc) props.get(entityName);
225                         logger.finest("entity=" + entityName + " query2=" + query2);
226                         PreparedStatement JavaDoc ps2 = conn.prepareStatement(handleSensitiveCase(query2, dbMetaData));
227                         ps2.execute();
228                     } catch (SQLException JavaDoc sqle) {
229                         logger.severe("entity=" + entityName + " cannot be created . " + sqle.getMessage());
230                         throw new RuntimeException JavaDoc(sqle);
231                     }
232
233                 } else {
234                     logger.info(entityName + " entry is not present in the properties file ");
235                 }
236
237             }
238         } catch (SQLException JavaDoc e) {
239             logger.severe(e.getMessage());
240         } finally {
241             try {
242                 conn.close();
243             } catch (SQLException JavaDoc e) {
244                 logger.severe(" connexion cannot be closed " + e.getMessage());
245             }
246         }
247     }
248
249     /**
250      * detect if the database has got some datas. return <i>true</i> if <strong>all</strong> jGuard tables involved in
251      * authorization are empty
252      *
253      * @param props
254      * properties files containing SQL queries
255      * @param connectionFactory
256      * connection factory used to check if the database is empty
257      * @param selectQueries
258      * queries to execute
259      * @return true if the database schema is empty
260      */

261     public static boolean isEmpty(Properties JavaDoc props, ConnectionFactory connectionFactory, List JavaDoc selectQueries) {
262         if (props == null) {
263             throw new IllegalArgumentException JavaDoc(" properties is null ");
264         }
265         if (connectionFactory == null) {
266             throw new IllegalArgumentException JavaDoc(" connectionFactory is null ");
267         }
268         boolean empty = true;
269         Connection JavaDoc conn = null;
270         try {
271             conn = connectionFactory.getConnection();
272             PreparedStatement JavaDoc pst = null;
273             ResultSet JavaDoc rs = null;
274             Iterator JavaDoc it = selectQueries.iterator();
275             while (it.hasNext()) {
276                 try {
277                     String JavaDoc key = (String JavaDoc) it.next();
278                     String JavaDoc query = (String JavaDoc) props.getProperty(key);
279                     pst = conn.prepareStatement(query);
280                     rs = pst.executeQuery();
281                     if (rs.next() != false) {
282                         logger.info(" there are some principals in database ");
283                         empty = false;
284                         break;
285                     }
286
287                 } catch (SQLException JavaDoc e) {
288                     logger.finest(e.getMessage());
289                 }
290             }
291         } finally {
292             try {
293                 conn.close();
294             } catch (SQLException JavaDoc e) {
295             }
296         }
297         return empty;
298     }
299
300 }
301
Popular Tags