1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package net.sf.jguard.ext.database;
29
30 import java.sql.Connection;
31 import java.sql.DatabaseMetaData;
32 import java.sql.PreparedStatement;
33 import java.sql.ResultSet;
34 import java.sql.SQLException;
35 import java.util.Arrays;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Properties;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43
44
45
46 public class DatabaseUtils {
47 private static final Logger logger = LoggerFactory.getLogger(DatabaseUtils.class.getName());
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 public static void createRequiredDatabaseEntities(Properties props, ConnectionFactory connFactory, List sequencesNames,
64 List tablesNames, List foreignkeysNames) {
65
66
67 createEntities(props, connFactory, sequencesNames, "SEQUENCE_PRESENCE");
68
69
70 createEntities(props, connFactory, tablesNames, "TABLE_PRESENCE");
71
72
73 createForeignKeys(props, connFactory, foreignkeysNames);
74
75 }
76
77 private static String handleSensitiveCase(String original, DatabaseMetaData dbMetaData) throws SQLException {
78 boolean storesLowerCaseIdentifiers = dbMetaData.storesLowerCaseIdentifiers();
79 logger.debug(" database store lower case identifiers =" + storesLowerCaseIdentifiers);
80 boolean storesUpperCaseIdentifiers = dbMetaData.storesUpperCaseIdentifiers();
81 logger.debug(" database store upper case identifiers =" + storesUpperCaseIdentifiers);
82 if (storesLowerCaseIdentifiers) {
83 original = original.toLowerCase();
84 } else if (storesUpperCaseIdentifiers) {
85 original = original.toUpperCase();
86 }
87
88 return original;
89
90 }
91
92 private static void createForeignKeys(Properties props, ConnectionFactory connectionFactory, List foreignkeysNames) {
93 Connection conn = null;
94 try {
95 conn = connectionFactory.getConnection();
96 DatabaseMetaData dbMetaData = conn.getMetaData();
97
98 for (int i = 0; i < foreignkeysNames.size(); i++) {
99 String foreignKeyName = (String) foreignkeysNames.get(i);
100 String query = ((String) props.get(foreignKeyName));
101
102
103 if (query != null) {
104 try {
105
106
107
108
109
110 List words = Arrays.asList(query.split(" "));
111
112
113
114
115
116
117 String fkTableName = (String) words.get(2);
118 String constraintName = (String) words.get(5);
119 String fKeyColumnName = (String) words.get(8);
120 fKeyColumnName = fKeyColumnName.replace('(', ' ');
121 fKeyColumnName = fKeyColumnName.replace(')', ' ').trim();
122 String pKeyTableName = (String) words.get(10);
123 int pKeyIndex = pKeyTableName.indexOf("(");
124
125
126 if (pKeyIndex>0){
127 pKeyTableName = pKeyTableName.substring(0,pKeyIndex);
128 }
129
130 ResultSet rs = dbMetaData.getImportedKeys(null, null, handleSensitiveCase(fkTableName, dbMetaData));
131 boolean foreignKeyFound = false;
132 while (rs.next()) {
133 logger.debug("importedKeys for=" + fkTableName);
134 String pkeyTableName2 = rs.getString("PKTABLE_NAME");
135 logger.debug("PKTABLE_NAME=" + pkeyTableName2);
136 String pkeyColumnName2 = rs.getString("PKCOLUMN_NAME");
137 logger.debug("PKCOLUMN_NAME=" + pkeyColumnName2);
138 String fkeyTableName2 = rs.getString("FKTABLE_NAME");
139 logger.debug("FKTABLE_NAME=" + fkeyTableName2);
140 String fkeyColumnName2 = rs.getString("FKCOLUMN_NAME");
141 logger.debug("FKCOLUMN_NAME=" + fkeyColumnName2);
142 String constraintName2 = rs.getString("FK_NAME");
143 logger.debug("FK_NAME=" + constraintName2);
144 String pkeyName2 = rs.getString("PK_NAME");
145 logger.debug("PK_NAME=" + pkeyName2);
146 if (fkTableName.equalsIgnoreCase(fkeyTableName2) && fKeyColumnName.equalsIgnoreCase(fkeyColumnName2)
147 && pKeyTableName.equalsIgnoreCase(pkeyTableName2)
148 && constraintName.equalsIgnoreCase(constraintName2)) {
149
150 foreignKeyFound = true;
151 break;
152 }
153
154 }
155
156 if (foreignKeyFound) {
157 continue;
158 }
159
160
161 logger.debug("entity=" + foreignKeyName + " query=" + query);
162 PreparedStatement ps2 = conn.prepareStatement(query);
163 ps2.execute();
164 } catch (SQLException sqle) {
165 logger.error("entity=" + foreignKeyName + " cannot be created . " + sqle.getMessage());
166 }
167
168 } else {
169 logger.info(foreignKeyName + " entry is not present in the properties file ");
170 }
171
172 }
173 } catch (SQLException e) {
174 logger.error(" database metadata cannot be grabbed from the SQL connection ");
175 } finally {
176 try {
177 conn.close();
178 } catch (SQLException e) {
179 logger.error(" connexion cannot be closed " + e.getMessage());
180 }
181 }
182
183 }
184
185
186
187
188
189
190
191
192
193 private static void createEntities(Properties props, ConnectionFactory connectionFactory, List entitiesNames,
194 String presenceQueryKey) {
195 Connection conn = null;
196 String presenceQuery = props.getProperty(presenceQueryKey);
197 try {
198 conn = connectionFactory.getConnection();
199 DatabaseMetaData dbMetaData = conn.getMetaData();
200 for (int i = 0; i < entitiesNames.size(); i++) {
201 String entityName = (String) entitiesNames.get(i);
202
203
204
205 if ((String) props.get(entityName) != null) {
206 try {
207
208 String replacedPresenceQuery = presenceQuery.replaceFirst("\\?", handleSensitiveCase(entityName,
209 dbMetaData));
210 PreparedStatement ps1 = conn.prepareStatement(replacedPresenceQuery);
211 logger.debug(replacedPresenceQuery);
212 ResultSet rs1 = ps1.executeQuery();
213 if (rs1.next()) {
214
215 logger.debug(" entity " + entityName + " has been detected : " + rs1.getObject(1));
216 continue;
217 }
218 } catch (SQLException e) {
219 logger.debug(" entity " + entityName + " does not exists and will be created ");
220 }
221 try {
222
223 String query2 = (String) props.get(entityName);
224 logger.debug("entity=" + entityName + " query2=" + query2);
225 PreparedStatement ps2 = conn.prepareStatement(handleSensitiveCase(query2, dbMetaData));
226 ps2.execute();
227 } catch (SQLException sqle) {
228 logger.error("entity=" + entityName + " cannot be created . " + sqle.getMessage());
229 throw new RuntimeException(sqle);
230 }
231
232 } else {
233 logger.info(entityName + " entry is not present in the properties file ");
234 }
235
236 }
237 } catch (SQLException e) {
238 logger.error(e.getMessage());
239 } finally {
240 try {
241 conn.close();
242 } catch (SQLException e) {
243 logger.error(" connexion cannot be closed " + e.getMessage());
244 }
245 }
246 }
247
248
249
250
251
252
253
254
255
256
257
258
259
260 public static boolean isEmpty(Properties props, ConnectionFactory connectionFactory, List selectQueries) {
261 if (props == null) {
262 throw new IllegalArgumentException(" properties is null ");
263 }
264 if (connectionFactory == null) {
265 throw new IllegalArgumentException(" connectionFactory is null ");
266 }
267 boolean empty = true;
268 Connection conn = null;
269 try {
270 conn = connectionFactory.getConnection();
271 PreparedStatement pst = null;
272 ResultSet rs = null;
273 Iterator it = selectQueries.iterator();
274 while (it.hasNext()) {
275 try {
276 String key = (String) it.next();
277 String query = (String) props.getProperty(key);
278 pst = conn.prepareStatement(query);
279 rs = pst.executeQuery();
280 if (rs.next() != false) {
281 logger.info(" there are some principals in database ");
282 empty = false;
283 break;
284 }
285
286 } catch (SQLException e) {
287 logger.debug(e.getMessage());
288 }
289 }
290 } finally {
291 try {
292 conn.close();
293 } catch (SQLException e) {
294 logger.debug(e.getMessage());
295 }
296 }
297 return empty;
298 }
299
300 }