KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > jdbc > JDBCPropertyDatabase


1 package com.sslexplorer.jdbc;
2
3 import java.io.ByteArrayOutputStream JavaDoc;
4 import java.io.File JavaDoc;
5 import java.io.ObjectOutputStream JavaDoc;
6 import java.io.Serializable JavaDoc;
7 import java.sql.ResultSet JavaDoc;
8 import java.sql.SQLException JavaDoc;
9 import java.sql.Timestamp JavaDoc;
10 import java.util.ArrayList JavaDoc;
11 import java.util.Calendar JavaDoc;
12 import java.util.HashSet JavaDoc;
13 import java.util.List JavaDoc;
14 import java.util.Set JavaDoc;
15
16 import org.apache.commons.cache.Cache;
17 import org.apache.commons.cache.CacheStat;
18 import org.apache.commons.cache.MemoryStash;
19 import org.apache.commons.cache.SimpleCache;
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 import com.sslexplorer.boot.ContextHolder;
24 import com.sslexplorer.boot.PropertyClass;
25 import com.sslexplorer.boot.PropertyClassManager;
26 import com.sslexplorer.boot.PropertyDefinition;
27 import com.sslexplorer.core.CoreServlet;
28 import com.sslexplorer.properties.DefaultPropertyProfile;
29 import com.sslexplorer.properties.Property;
30 import com.sslexplorer.properties.PropertyDatabase;
31 import com.sslexplorer.properties.PropertyProfile;
32 import com.sslexplorer.properties.attributes.AbstractAttributeKey;
33 import com.sslexplorer.properties.attributes.AttributeDefinition;
34 import com.sslexplorer.properties.attributes.DefaultAttributeDefinition;
35 import com.sslexplorer.properties.impl.profile.ProfileProperties;
36 import com.sslexplorer.properties.impl.profile.ProfilePropertyKey;
37
38 /**
39  * Implementation of a {@link com.sslexplorer.properties.PropertyDatabase} that
40  * stores profiles, categories and properties in a JDBC compliant database.
41  * <p>
42  * To improve performance, the values of the properties themselves are cached in
43  * memory.
44  * <p>
45  * The behaviour of this cache is effected by two Java system properties,
46  * <code>sslexplorer.jdbcPropertyDatabase.cacheTTL</code> and
47  * <code>sslexplorer.jdbcPropertyDatabase.cacheMaxObjs</code>
48  *
49  * @author Brett Smith <a HREF="mailto: brett@3sp.com">&lt;brett@3sp.com&gt;</a>
50  */

51
52 public class JDBCPropertyDatabase implements PropertyDatabase {
53
54     static Log log = LogFactory.getLog(JDBCPropertyDatabase.class);
55
56     final static Long JavaDoc CACHE_TTL = new Long JavaDoc(System.getProperty("sslexplorer.jdbcPropertyDatabase.cacheTTL", "180000"));
57     final static Integer JavaDoc CACHE_MAXOBJS = new Integer JavaDoc(System.getProperty("sslexplorer.jdbcPropertyDatabase.cacheMaxObjs", "2000"));
58     final static Long JavaDoc CACHE_COST = new Long JavaDoc(1);
59
60     // Private instance variables
61
private Cache propertyCache;
62     private JDBCDatabaseEngine db;
63
64     /*
65      * (non-Javadoc)
66      *
67      * @see com.sslexplorer.core.Database#open(com.sslexplorer.core.CoreServlet)
68      */

69     public void open(CoreServlet controllingServlet) throws Exception JavaDoc {
70         String JavaDoc dbName = System.getProperty("sslexplorer.propertyDatabase.jdbc.dbName", "explorer_configuration");
71         controllingServlet.addDatabase(dbName, ContextHolder.getContext().getDBDirectory());
72         String JavaDoc jdbcUser = System.getProperty("sslexplorer.jdbc.username", "sa");
73         String JavaDoc jdbcPassword = System.getProperty("sslexplorer.jdbc.password", "");
74         String JavaDoc vendorDB = System.getProperty("sslexplorer.jdbc.vendorClass", "com.sslexplorer.jdbc.hsqldb.HSQLDBDatabaseEngine");
75
76         if (log.isInfoEnabled()) {
77             log.info("Property database is being opened...");
78             log.info("JDBC vendor class implementation is " + vendorDB);
79         }
80
81         db = (JDBCDatabaseEngine) Class.forName(vendorDB).newInstance();
82         db.init("propertyDatabase", dbName, jdbcUser, jdbcPassword, null);
83
84         File JavaDoc upgradeDir = new File JavaDoc("install/upgrade");
85         DBUpgrader upgrader = new DBUpgrader(ContextHolder.getContext().getVersion(), db, ContextHolder.getContext()
86                         .getDBDirectory(), upgradeDir);
87         upgrader.upgrade();
88
89         int maxObjs = CACHE_MAXOBJS.intValue();
90         propertyCache = new SimpleCache(new MemoryStash(maxObjs));
91         loadAttributeDefinitions();
92     }
93
94     /*
95      * (non-Javadoc)
96      *
97      * @see com.sslexplorer.boot.Database#close()
98      */

99     public void close() throws Exception JavaDoc {
100         if(propertyCache != null)
101             propertyCache.clear();
102     }
103
104     public String JavaDoc retrieveGenericProperty(String JavaDoc key1, String JavaDoc key2, String JavaDoc key3, String JavaDoc key4, String JavaDoc key5) throws Exception JavaDoc {
105         String JavaDoc cacheKey = key1 + "_" + key2 + "_" + key3 + "_" + key4 + "_" + key5;
106         String JavaDoc val = (String JavaDoc) propertyCache.retrieve(cacheKey);
107         if (val == null) {
108
109             JDBCPreparedStatement ps = db.getStatement("select.property");
110             ps.setString(1, key1);
111             ps.setString(2, key2);
112             ps.setString(3, key3);
113             ps.setString(4, key4);
114             ps.setString(5, key5);
115             ResultSet JavaDoc rs = ps.executeQuery();
116             try {
117                 val = rs.next() ? rs.getString("value") : null;
118             } finally {
119                 rs.close();
120                 ps.releasePreparedStatement();
121             }
122         }
123         if (val != null)
124             storeToCache(cacheKey, val);
125         return val;
126     }
127
128     /*
129      * (non-Javadoc)
130      *
131      * @see com.sslexplorer.boot.PropertyDatabase#storeProperty(int,
132      * java.lang.String, java.lang.String, java.lang.String)
133      */

134     public void storeGenericProperty(String JavaDoc key1, String JavaDoc key2, String JavaDoc key3, String JavaDoc key4, String JavaDoc key5, String JavaDoc value) throws Exception JavaDoc {
135         propertyCache.clear();
136         JDBCPreparedStatement ps = db.getStatement("select.property");
137         ps.setString(1, key1);
138         ps.setString(2, key2);
139         ps.setString(3, key3);
140         ps.setString(4, key4);
141         ps.setString(5, key5);
142
143         ResultSet JavaDoc rs = ps.executeQuery();
144
145         JDBCPreparedStatement ps2;
146         try {
147             if (!rs.next()) {
148                 if (log.isDebugEnabled())
149                     log.debug("Property doesnt currently exist, inserting value '" + value + "'");
150
151                 ps2 = db.getStatement("insert.property");
152                 ps2.setString(1, key1);
153                 ps2.setString(2, key2);
154                 ps2.setString(3, key3);
155                 ps2.setString(4, key4);
156                 ps2.setString(5, key5);
157
158                 // Insert new property
159
ps2.setString(6, value);
160
161                 try {
162                     ps2.execute();
163                 } finally {
164                     ps2.releasePreparedStatement();
165                 }
166
167             } else {
168                 if (log.isDebugEnabled())
169                     log.debug("Property exists, updating value '" + value + "'");
170
171                 ps2 = db.getStatement("update.property");
172
173                 // Insert new property
174
ps2.setString(1, value);
175                 ps2.setString(2, key1);
176                 ps2.setString(3, key2);
177                 ps2.setString(4, key3);
178                 ps2.setString(5, key4);
179                 ps2.setString(6, key5);
180                 try {
181                     ps2.execute();
182                 } finally {
183                     ps2.releasePreparedStatement();
184                 }
185
186             }
187         } finally {
188             rs.close();
189             ps.releasePreparedStatement();
190         }
191
192     }
193
194     /* (non-Javadoc)
195      * @see com.sslexplorer.properties.PropertyDatabase#getPropertyProfiles(java.lang.String, boolean, int)
196      */

197     public List JavaDoc<PropertyProfile> getPropertyProfiles(String JavaDoc username, boolean includeGlobal, int realmID) throws Exception JavaDoc {
198
199         JDBCPreparedStatement ps;
200         if (includeGlobal) {
201             ps = db.getStatement("select.global.profiles");
202         } else {
203             ps = db.getStatement("select.profiles");
204         }
205
206         try {
207             ps.setString(1, username == null ? "" : username);
208             ps.setInt(2, realmID);
209
210             ResultSet JavaDoc rs = ps.executeQuery();
211             try {
212
213                 Set JavaDoc<PropertyProfile> v = new HashSet JavaDoc<PropertyProfile>();
214                 while (rs.next()) {
215                     v.add(buildPropertyProfile(rs));
216                 }
217                 return new ArrayList JavaDoc<PropertyProfile>(v);
218             } finally {
219                 rs.close();
220             }
221         } finally {
222             ps.releasePreparedStatement();
223         }
224     }
225
226     /*
227      * (non-Javadoc)
228      *
229      * @see com.sslexplorer.boot.PropertyDatabase#getPropertyProfile(int)
230      */

231     public PropertyProfile getPropertyProfile(int id) throws Exception JavaDoc {
232
233         JDBCPreparedStatement ps = db.getStatement("select.profile");
234         ResultSet JavaDoc rs = null;
235         try {
236             ps.setInt(1, id);
237
238             rs = ps.executeQuery();
239             if (rs.next()) {
240                 return buildPropertyProfile(rs);
241             }
242         } finally {
243             if (rs != null)
244                 rs.close();
245             ps.releasePreparedStatement();
246         }
247         return null;
248     }
249
250
251     /* (non-Javadoc)
252      * @see com.sslexplorer.properties.PropertyDatabase#createPropertyProfile(java.lang.String, java.lang.String, java.lang.String, int, int)
253      */

254     public PropertyProfile createPropertyProfile(String JavaDoc username, String JavaDoc shortName, String JavaDoc description, int baseOn,
255                                                  int realmID) throws Exception JavaDoc {
256
257         JDBCPreparedStatement ps = db.getStatement("insert.profile");
258         Calendar JavaDoc c = Calendar.getInstance();
259
260         try {
261             ps.setString(1, username == null ? "" : username);
262             ps.setString(2, shortName);
263             ps.setString(3, description);
264             ps.setString(4, db.formatTimestamp(c));
265             ps.setString(5, db.formatTimestamp(c));
266             ps.setInt(6, realmID);
267             ps.execute();
268         } finally {
269             ps.releasePreparedStatement();
270         }
271         int id = db.getLastInsertId(ps, "insert.profile.lastInsertId");
272         PropertyProfile profile = new DefaultPropertyProfile(realmID, id, username == null ? "" : username, shortName, description,
273                         c, c);
274         profile.setResourceName(shortName);
275         profile.setResourceDescription(description);
276
277         if (baseOn != -1) {
278             for (PropertyDefinition def : PropertyClassManager.getInstance()
279                             .getPropertyClass(ProfileProperties.NAME)
280                             .getDefinitions()) {
281                 String JavaDoc val = Property.getProperty(new ProfilePropertyKey(baseOn, username, def.getName(), realmID));
282                 storeGenericProperty(def.getName(), username == null ? "" : username, String.valueOf(id), String.valueOf(realmID), "", val);
283             }
284         }
285
286         return profile;
287
288     }
289
290     /* (non-Javadoc)
291      * @see com.sslexplorer.properties.PropertyDatabase#updatePropertyProfile(int, java.lang.String, java.lang.String)
292      */

293     public void updatePropertyProfile(int id, String JavaDoc shortName, String JavaDoc description) throws Exception JavaDoc {
294
295         JDBCPreparedStatement ps = db.getStatement("update.profile");
296
297         try {
298             ps.setString(1, shortName);
299             ps.setString(2, description);
300             ps.setString(3, db.formatTimestamp(Calendar.getInstance()));
301             ps.setInt(4, id);
302             ps.execute();
303         } finally {
304             ps.releasePreparedStatement();
305         }
306
307     }
308
309     /*
310      * (non-Javadoc)
311      *
312      * @see com.sslexplorer.boot.PropertyDatabase#deletePropertyProfile(int)
313      */

314     public PropertyProfile deletePropertyProfile(int id) throws Exception JavaDoc {
315         PropertyProfile prof = getPropertyProfile(id);
316         if (prof == null) {
317             throw new Exception JavaDoc("No property profile with " + id + ".");
318         }
319         propertyCache.clear();
320         JDBCPreparedStatement ps = db.getStatement("delete.profile.1");
321         ps.setInt(1, id);
322
323         try {
324             ps.execute();
325         } finally {
326             ps.releasePreparedStatement();
327         }
328
329         ps = db.getStatement("delete.profile.2");
330         ps.setInt(1, id);
331
332         try {
333             ps.execute();
334         } finally {
335             ps.releasePreparedStatement();
336         }
337         return prof;
338     }
339
340     /* (non-Javadoc)
341      * @see com.sslexplorer.properties.PropertyDatabase#getPropertyProfile(java.lang.String, java.lang.String, int)
342      */

343     public PropertyProfile getPropertyProfile(String JavaDoc username, String JavaDoc name, int realmID) throws Exception JavaDoc {
344
345         JDBCPreparedStatement ps = db.getStatement("select.profile.short");
346         ResultSet JavaDoc rs = null;
347
348         try {
349             ps.setString(1, username == null ? "" : username);
350             ps.setString(2, name);
351             ps.setInt(3, realmID);
352
353             rs = ps.executeQuery();
354
355             if (rs.next()) {
356                 return buildPropertyProfile(rs);
357             }
358             return null;
359         } finally {
360             if (rs != null)
361                 rs.close();
362             ps.releasePreparedStatement();
363         }
364     }
365
366     /*
367      * (non-Javadoc)
368      *
369      * @see com.sslexplorer.boot.Database#cleanup()
370      */

371     public void cleanup() throws Exception JavaDoc {
372     }
373
374     public void storeAttributeValue(AbstractAttributeKey key, String JavaDoc value) throws Exception JavaDoc {
375         // Delete the entry if there is 1.
376
JDBCPreparedStatement ps = db.getStatement("storeAttributeValue.delete");
377         try {
378             ps.setString(1, key.getPropertyClassName());
379             ps.setString(2, key.getAttributeClassKey());
380             ps.setString(3, key.getName());
381             ps.execute();
382         } finally {
383             ps.releasePreparedStatement();
384         }
385         // now re-insert the attribute.
386
if (value != null) {
387             JDBCPreparedStatement ps2 = db.getStatement(ps, "storeAttributeValue.insert");
388             try {
389                 ps2.setString(1, key.getPropertyClassName());
390                 ps2.setString(2, key.getAttributeClassKey());
391                 ps2.setString(3, key.getName());
392                 ps2.setString(4, value);
393                 ps2.execute();
394             } finally {
395                 ps2.releasePreparedStatement();
396             }
397         }
398     }
399
400     /*
401      * (non-Javadoc)
402      *
403      * @see com.sslexplorer.security.UserDatabase#loadAttributes(com.sslexplorer.security.User)
404      */

405     public String JavaDoc retrieveAttributeValue(AbstractAttributeKey attribute) throws Exception JavaDoc {
406         JDBCPreparedStatement ps = db.getStatement("retrieveAttributeValue.select");
407         try {
408             ps.setString(1, attribute.getAttributeClassKey());
409             ps.setString(2, attribute.getPropertyClassName());
410             ps.setString(3, attribute.getName());
411             ResultSet JavaDoc rs = ps.executeQuery();
412             if (rs.next()) {
413                 return rs.getString("attribute_value");
414             }
415         } finally {
416             ps.releasePreparedStatement();
417         }
418         return null;
419     }
420
421     /*
422      * (non-Javadoc)
423      *
424      * @see com.sslexplorer.properties.PropertyDatabase#createAttributeDefinition(com.sslexplorer.properties.AttributeDefinition)
425      */

426     public void createAttributeDefinition(AttributeDefinition definition) throws Exception JavaDoc {
427         if (definition.isSystem()) {
428             throw new Exception JavaDoc("System attribute definitions may not be created.");
429         }
430         JDBCPreparedStatement ps = db.getStatement("createAttributeDefinition.create");
431         try {
432             ps.setString(1, definition.getName());
433             ps.setString(2, definition.getPropertyClass().getName());
434             ps.setInt(3, definition.getVisibility());
435             ps.setInt(4, definition.getType());
436             ps.setInt(5, definition.getSortOrder());
437             ps.setString(6, definition.getLabel());
438             ps.setString(7, definition.getDescription());
439             ps.setString(8, definition.getTypeMeta());
440             ps.setInt(9, definition.getCategory());
441             ps.setString(10, definition.getCategoryLabel());
442             ps.setString(11, definition.getDefaultValue());
443             ps.setInt(12, definition.isHidden() ? 1 : 0);
444             ps.setString(13, definition.getValidationString());
445             ps.execute();
446         } finally {
447             ps.releasePreparedStatement();
448         }
449     }
450
451     /*
452      * (non-Javadoc)
453      *
454      * @see com.sslexplorer.properties.PropertyDatabase#deleteAttributeDefinition(java.lang.String,
455      * java.lang.String)
456      */

457     public void deleteAttributeDefinition(String JavaDoc propertyClassName, String JavaDoc definitionName) throws Exception JavaDoc {
458         AttributeDefinition def = (AttributeDefinition) PropertyClassManager.getInstance()
459                         .getPropertyClass(propertyClassName)
460                         .getDefinition(definitionName);
461         if (def == null) {
462             throw new Exception JavaDoc("Definition with name " + definitionName + " cannot be deleted as it does not exist.");
463         }
464         if (def.isSystem()) {
465             throw new Exception JavaDoc("Definition with name " + definitionName + " cannot be deleted as it is a system definition.");
466         }
467         JDBCPreparedStatement ps = db.getStatement("deleteAttributeDefinition.delete");
468         try {
469             ps.setString(1, propertyClassName);
470             ps.setString(2, definitionName);
471             ps.execute();
472         } finally {
473             ps.releasePreparedStatement();
474         }
475     }
476
477     /*
478      * (non-Javadoc)
479      *
480      * @see com.sslexplorer.properties.PropertyDatabase#updateAttributeDefinition(com.sslexplorer.properties.AttributeDefinition)
481      */

482     public void updateAttributeDefinition(AttributeDefinition definition) throws Exception JavaDoc {
483         if (definition.isSystem()) {
484             throw new Exception JavaDoc("System attribute definitions may not be updated.");
485         }
486         JDBCPreparedStatement ps = db.getStatement("updateAttributeDefinition.update");
487         try {
488             ps.setInt(1, definition.getVisibility());
489             ps.setInt(2, definition.getType());
490             ps.setInt(3, definition.getSortOrder());
491             ps.setString(4, definition.getLabel());
492             ps.setString(5, definition.getDescription());
493             ps.setString(6, definition.getTypeMeta());
494             ps.setInt(7, definition.getCategory());
495             ps.setString(8, definition.getCategoryLabel());
496             ps.setString(9, definition.getDefaultValue());
497             ps.setInt(10, definition.isHidden() ? 1 : 0);
498             ps.setString(11, definition.getValidationString());
499             ps.setString(12, definition.getName());
500             ps.setString(13, definition.getPropertyClass().getName());
501             ps.execute();
502         } finally {
503             ps.releasePreparedStatement();
504         }
505
506     }
507
508     void loadAttributeDefinitions() throws Exception JavaDoc {
509         JDBCPreparedStatement ps = db.getStatement("loadAttributeDefinitions.select");
510         ResultSet JavaDoc rs = ps.executeQuery();
511         try {
512             while (rs.next()) {
513                 String JavaDoc propertyClassName = rs.getString("property_class");
514                 PropertyClass ua = PropertyClassManager.getInstance().getPropertyClass(propertyClassName);
515                 if (ua == null) {
516                     log.warn("Found user attribute '" + rs.getString("name")
517                         + "' with a property class of '"
518                         + propertyClassName
519                         + "'. This property class does not exist. Perhaps a plugin has been uninstalled?");
520                 } else {
521                     ua.registerPropertyDefinition(new DefaultAttributeDefinition(rs.getInt("type"),
522                                     rs.getString("name"),
523                                     rs.getString("type_meta"),
524                                     rs.getInt("category"),
525                                     rs.getString("category_label"),
526                                     rs.getString("default_value"),
527                                     rs.getInt("visibility"),
528                                     rs.getInt("sort_order"),
529                                     null,
530                                     rs.getInt("hidden") == 1,
531                                     rs.getString("text_label"),
532                                     rs.getString("text_description"),
533                                     false,
534                                     true,
535                                     rs.getString("validation_string")));
536                 }
537             }
538         } finally {
539             rs.close();
540             ps.releasePreparedStatement();
541         }
542     }
543
544     PropertyProfile buildPropertyProfile(ResultSet JavaDoc rs) throws SQLException JavaDoc {
545         String JavaDoc username = rs.getString("username");
546         Timestamp JavaDoc cd = rs.getTimestamp("date_created");
547         Calendar JavaDoc c = Calendar.getInstance();
548         c.setTimeInMillis(cd == null ? System.currentTimeMillis() : cd.getTime());
549         Timestamp JavaDoc ad = rs.getTimestamp("date_amended");
550         Calendar JavaDoc a = Calendar.getInstance();
551         a.setTimeInMillis(ad == null ? System.currentTimeMillis() : ad.getTime());
552         return new DefaultPropertyProfile(rs.getInt("realm_id"), rs.getInt("id"), username.equals("") ? null : username, rs
553                         .getString("short_name"), rs.getString("description"), c, a);
554     }
555
556     void storeToCache(Serializable JavaDoc key, Serializable JavaDoc object) {
557         if (log.isDebugEnabled()) {
558             log.debug("Caching under " + key + ", ttl=" + CACHE_TTL + ", cost=" + CACHE_COST);
559         }
560         
561         // NOTE Temporary code to make sure policy objects are serializable, in development and testing
562
if ("true".equals(System.getProperty("sslexplorer.useDevConfig")) | "true".equals(System.getProperty("sslexplorer.testing"))) {
563             ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
564             try {
565                 ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(baos);
566                 oos.writeObject(object);
567             } catch (Exception JavaDoc e) {
568                 String JavaDoc string = "********** Failed to cache policy database object. There is probably a non-serializable object somewhere in the object graph. PLEASE FIX ME ****************";
569                 System.err
570                         .println(string);
571                 e.printStackTrace();
572                 throw new RuntimeException JavaDoc(string);
573             }
574         }
575         
576         propertyCache.store(key, object, new Long JavaDoc(CACHE_TTL.longValue() + System.currentTimeMillis()), CACHE_COST);
577         if (log.isDebugEnabled()) {
578             log.debug("NUM_RETRIEVE_REQUESTED " + propertyCache.getStat(CacheStat.NUM_RETRIEVE_REQUESTED));
579             log.debug("NUM_RETRIEVE_FOUND " + propertyCache.getStat(CacheStat.NUM_RETRIEVE_FOUND));
580             log.debug("NUM_RETRIEVE_NOT_FOUND " + propertyCache.getStat(CacheStat.NUM_RETRIEVE_NOT_FOUND));
581             log.debug("NUM_STORE_REQUESTED " + propertyCache.getStat(CacheStat.NUM_STORE_REQUESTED));
582             log.debug("NUM_STORE_STORED " + propertyCache.getStat(CacheStat.NUM_STORE_STORED));
583             log.debug("NUM_STORE_NOT_STORED " + propertyCache.getStat(CacheStat.NUM_STORE_NOT_STORED));
584             log.debug("CUR_CAPACITY " + propertyCache.getStat(CacheStat.CUR_CAPACITY));
585         }
586     }
587
588 }
589
Popular Tags