KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > nemesis > forum > impl > DbForumFactory


1 /*
2  * NEMESIS-FORUM.
3  * Copyright (C) 2002 David Laurent(lithium2@free.fr). All rights reserved.
4  *
5  * Copyright (c) 2000 The Apache Software Foundation. All rights reserved.
6  *
7  * Copyright (C) 2001 Yasna.com. All rights reserved.
8  *
9  * Copyright (C) 2000 CoolServlets.com. All rights reserved.
10  *
11  * NEMESIS-FORUM. is free software; you can redistribute it and/or
12  * modify it under the terms of the Apache Software License, Version 1.1,
13  * or (at your option) any later version.
14  *
15  * NEMESIS-FORUM core framework, NEMESIS-FORUM backoffice, NEMESIS-FORUM frontoffice
16  * application are parts of NEMESIS-FORUM and are distributed under
17  * same terms of licence.
18  *
19  *
20  * NEMESIS-FORUM includes software developed by the Apache Software Foundation (http://www.apache.org/)
21  * and software developed by CoolServlets.com (http://www.coolservlets.com).
22  * and software developed by Yasna.com (http://www.yasna.com).
23  *
24  */

25 package org.nemesis.forum.impl;
26
27 import java.sql.Connection JavaDoc;
28 import java.sql.PreparedStatement JavaDoc;
29 import java.sql.ResultSet JavaDoc;
30 import java.sql.SQLException JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.Iterator JavaDoc;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.nemesis.forum.Authorization;
37 import org.nemesis.forum.Forum;
38 import org.nemesis.forum.ForumFactory;
39 import org.nemesis.forum.ForumPermissions;
40 import org.nemesis.forum.ForumThread;
41 import org.nemesis.forum.Message;
42 import org.nemesis.forum.ProfileManager;
43 import org.nemesis.forum.exception.ForumAlreadyExistsException;
44 import org.nemesis.forum.exception.ForumMessageNotFoundException;
45 import org.nemesis.forum.exception.ForumNotFoundException;
46 import org.nemesis.forum.exception.ForumThreadNotFoundException;
47 import org.nemesis.forum.exception.UnauthorizedException;
48 import org.nemesis.forum.util.cache.Cache;
49 import org.nemesis.forum.util.cache.CacheableInteger;
50 import org.nemesis.forum.util.jdbc.DbConnectionManager;
51 /**
52  * Database implementation of the ForumFactory interface.
53  */

54 public class DbForumFactory extends ForumFactory {
55 static protected Log log = LogFactory.getLog(DbForumFactory.class);
56     /** DATABASE QUERIES **/
57     private static final String JavaDoc FORUM_COUNT = "SELECT count(*) FROM yazdForum";
58     private static final String JavaDoc DELETE_FORUM = "DELETE FROM yazdForum WHERE forumID=?";
59     private static final String JavaDoc DELETE_FORUM_USER_PERMS = "DELETE FROM yazdUserPerm WHERE forumID=?";
60     private static final String JavaDoc DELETE_FORUM_GROUP_PERMS = "DELETE FROM yazdGroupPerm WHERE forumID=?";
61     private static final String JavaDoc DELETE_FORUM_PROPERTIES = "DELETE FROM yazdForumProp WHERE forumID=?";
62     private static final String JavaDoc GET_USER_PERMS = "SELECT DISTINCT permission FROM yazdUserPerm WHERE forumID=? " + "AND userID=?";
63     private static final String JavaDoc USERS_WITH_PERM = "SELECT DISTINCT userID FROM yazdUserPerm WHERE forumID=? AND permission=?";
64     private static final String JavaDoc GET_GROUP_PERMS = "SELECT DISTINCT permission from yazdGroupPerm WHERE forumID=? " + "AND groupID=?";
65     private static final String JavaDoc GROUPS_WITH_PERM = "SELECT DISTINCT groupID FROM yazdGroupPerm WHERE forumID=? AND permission=?";
66     private static final String JavaDoc ALL_MESSAGES = "SELECT messageID FROM yazdMessage";
67     private static final String JavaDoc DELETE_MESSAGE = "DELETE FROM yazdMessage WHERE messageID=?";
68
69     protected DbCacheManager cacheManager;
70
71     /**
72      * The profile manager provides access to users and groups.
73      */

74     private ProfileManager profileManager;
75
76
77
78     /**
79      * Creates a new DbForumFactory.
80      */

81     public DbForumFactory() {
82         cacheManager = new DbCacheManager();
83
84         profileManager = new DbProfileManager(this);
85         //searchIndexer = new DbSearchIndexer(this);
86
}
87
88     //FROM THE FORUMFACTORY INTERFACE//
89

90     public Forum createForum(String JavaDoc name, String JavaDoc description) throws UnauthorizedException, ForumAlreadyExistsException {
91         Forum newForum = null;
92         try {
93             Forum existingForum = getForum(name);
94
95             //The forum already exists since now exception, so:
96
throw new ForumAlreadyExistsException();
97         } catch (ForumNotFoundException fnfe) {
98             //The forum doesn't already exist so we can create a new one
99
newForum = new DbForum(name, description, this);
100         }
101         return newForum;
102     }
103
104     public void deleteForum(Forum forum) throws UnauthorizedException {
105         //First, remove forum from memory.
106
cacheManager.remove(DbCacheManager.FORUM_CACHE, new Integer JavaDoc(forum.getID()));
107         cacheManager.remove(DbCacheManager.USER_PERMS_CACHE, new Integer JavaDoc(forum.getID()));
108         cacheManager.remove(DbCacheManager.FORUM_ID_CACHE, forum.getName());
109
110         //Delete all messages and threads in the forum.
111
Iterator JavaDoc threads = forum.threads();
112         while (threads.hasNext()) {
113             ForumThread thread = (ForumThread) threads.next();
114             forum.deleteThread(thread);
115         }
116
117         //Now, delete all filters associated with the forum. We delete in
118
//reverse order since filter indexes will change if we don't delete
119
//the last filter entry.
120
int filterCount = forum.getForumMessageFilters().length;
121         for (int i = filterCount - 1; i >= 0; i--) {
122             forum.removeForumMessageFilter(i);
123         }
124
125         //Finally, delete the forum itself and all permissions and properties
126
//associated with it.
127
Connection JavaDoc con = null;
128         PreparedStatement JavaDoc pstmt = null;
129         try {
130             con = DbConnectionManager.getConnection();
131             pstmt = con.prepareStatement(DELETE_FORUM);
132             pstmt.setInt(1, forum.getID());
133             pstmt.execute();
134             pstmt.close();
135             //User perms
136
pstmt = con.prepareStatement(DELETE_FORUM_USER_PERMS);
137             pstmt.setInt(1, forum.getID());
138             pstmt.execute();
139             pstmt.close();
140             //Group perms
141
pstmt = con.prepareStatement(DELETE_FORUM_GROUP_PERMS);
142             pstmt.setInt(1, forum.getID());
143             pstmt.execute();
144             pstmt.close();
145             //Properties
146
pstmt = con.prepareStatement(DELETE_FORUM_PROPERTIES);
147             pstmt.setInt(1, forum.getID());
148             pstmt.execute();
149         } catch (Exception JavaDoc sqle) {
150             log.error("Error in DbForumFactory:deleteForum()-",sqle);
151         } finally {
152             try {
153                 pstmt.close();
154             } catch (Exception JavaDoc e) {
155                 log.error("",e);
156             }
157             try {
158                 con.close();
159             } catch (Exception JavaDoc e) {
160                 log.error("",e);
161             }
162         }
163     }
164     public Iterator JavaDoc forumsModeration() { //this has to be revisited again
165
return null;
166     }
167     public Forum getForum(int forumID) throws ForumNotFoundException, UnauthorizedException {
168         //If cache is not enabled, do a new lookup of object
169
if (!cacheManager.isCacheEnabled()) {
170             return new DbForum(forumID, this);
171         }
172         //Cache is enabled.
173
Integer JavaDoc forumIDInteger = new Integer JavaDoc(forumID);
174         DbForum forum = (DbForum) cacheManager.get(DbCacheManager.FORUM_CACHE, forumIDInteger);
175         if (forum == null) {
176             forum = new DbForum(forumID, this);
177             cacheManager.add(DbCacheManager.FORUM_CACHE, forumIDInteger, forum);
178         }
179         return forum;
180     }
181
182     public Forum getForum(String JavaDoc name) throws ForumNotFoundException, UnauthorizedException {
183         //If cache is not enabled, do a new lookup of object
184
if (!cacheManager.isCacheEnabled()) {
185             Forum forum = new DbForum(name, this);
186             return forum;
187         }
188         //Cache is enabled.
189
CacheableInteger forumIDInteger = (CacheableInteger) cacheManager.get(DbCacheManager.FORUM_ID_CACHE, name);
190         //if id wan't found in cache, load it up and put it there.
191
if (forumIDInteger == null) {
192             Forum forum = new DbForum(name, this);
193             forumIDInteger = new CacheableInteger(new Integer JavaDoc(forum.getID()));
194             cacheManager.add(DbCacheManager.FORUM_ID_CACHE, name, forumIDInteger);
195         }
196         return getForum(forumIDInteger.getInteger().intValue());
197     }
198
199     public int getForumCount() {
200         int forumCount = 0;
201         Connection JavaDoc con = null;
202         PreparedStatement JavaDoc pstmt = null;
203         try {
204             con = DbConnectionManager.getConnection();
205             pstmt = con.prepareStatement(FORUM_COUNT);
206             ResultSet JavaDoc rs = pstmt.executeQuery();
207             rs.next();
208             forumCount = rs.getInt(1);
209         } catch (SQLException JavaDoc sqle) {
210             log.error("DbForumFactory:getForumCount() failed: " , sqle);
211         } finally {
212             try {
213                 pstmt.close();
214             } catch (Exception JavaDoc e) {
215                 log.error("",e);
216             }
217             try {
218                 con.close();
219             } catch (Exception JavaDoc e) {
220                 log.error("",e);
221             }
222         }
223         return forumCount;
224     }
225
226     public Iterator JavaDoc forums() {
227         return new DbForumFactoryIterator(this);
228     }
229
230     public ProfileManager getProfileManager() {
231         return profileManager;
232     }
233
234
235     public int[] usersWithPermission(int permissionType) throws UnauthorizedException {
236         int[] users = new int[0];
237         Connection JavaDoc con = null;
238         PreparedStatement JavaDoc pstmt = null;
239         try {
240             con = DbConnectionManager.getConnection();
241             pstmt = con.prepareStatement(USERS_WITH_PERM);
242             pstmt.setInt(1, -1);
243             pstmt.setInt(2, permissionType);
244             ResultSet JavaDoc rs = pstmt.executeQuery();
245             ArrayList JavaDoc userList = new ArrayList JavaDoc();
246             while (rs.next()) {
247                 userList.add(new Integer JavaDoc(rs.getInt("userID")));
248             }
249             users = new int[userList.size()];
250             for (int i = 0; i < users.length; i++) {
251                 users[i] = ((Integer JavaDoc) userList.get(i)).intValue();
252             }
253         } catch (SQLException JavaDoc sqle) {
254             log.error("",sqle);
255         } finally {
256             try {
257                 pstmt.close();
258             } catch (Exception JavaDoc e) {
259                 log.error("",e);
260             }
261             try {
262                 con.close();
263             } catch (Exception JavaDoc e) {
264                 log.error("",e);
265             }
266         }
267         return users;
268     }
269
270     public int[] groupsWithPermission(int permissionType) throws UnauthorizedException {
271         int[] groups = new int[0];
272         Connection JavaDoc con = null;
273         PreparedStatement JavaDoc pstmt = null;
274         try {
275             con = DbConnectionManager.getConnection();
276             pstmt = con.prepareStatement(GROUPS_WITH_PERM);
277             pstmt.setInt(1, -1);
278             pstmt.setInt(2, permissionType);
279             ResultSet JavaDoc rs = pstmt.executeQuery();
280             ArrayList JavaDoc groupList = new ArrayList JavaDoc();
281             while (rs.next()) {
282                 groupList.add(new Integer JavaDoc(rs.getInt("groupID")));
283             }
284             groups = new int[groupList.size()];
285             for (int i = 0; i < groups.length; i++) {
286                 groups[i] = ((Integer JavaDoc) groupList.get(i)).intValue();
287             }
288         } catch (SQLException JavaDoc sqle) {
289             log.error("Error in DbForum.groupsWithPermission:" , sqle);
290             
291         } finally {
292             try {
293                 pstmt.close();
294             } catch (Exception JavaDoc e) {
295                 log.error("",e);
296             }
297             try {
298                 con.close();
299             } catch (Exception JavaDoc e) {
300                 log.error("",e);
301             }
302         }
303         return groups;
304     }
305
306     public ForumPermissions getPermissions(Authorization authorization) {
307         int userID = authorization.getUserID();
308
309         //Get the user perm cache for this forum
310
Cache userPermCache = (Cache) getCacheManager().get(DbCacheManager.USER_PERMS_CACHE, new Integer JavaDoc(-1));
311
312         //Simple case: if cache is turned on and the user is already cached,
313
//we can simply return the cached permissions.
314
if (userPermCache != null) {
315             ForumPermissions permissions = (ForumPermissions) userPermCache.get(new Integer JavaDoc(userID));
316             if (permissions != null) {
317                 return permissions;
318             }
319         }
320
321         //Not so simple case: cache is not turned on or the user permissions
322
//have not been cached yet.
323
boolean isAnonymous = (userID == -1);
324         boolean isUser = !isAnonymous;
325
326         ForumPermissions finalPermissions = ForumPermissions.none();
327         // check each forum for a specific permission
328
Iterator JavaDoc allForums = this.forums();
329         Forum forum;
330         ForumPermissions forumUserPermissions;
331         while (allForums.hasNext()) {
332             forum = (Forum) allForums.next();
333             forumUserPermissions = getUserPermissions(userID, forum.getID());
334             finalPermissions = new ForumPermissions(finalPermissions, forumUserPermissions);
335         }
336
337         //Step 1 - Get permissions for the User. This includes anonymous
338
//perms, "special user" perms, and the specific perms for the user.
339
if (isUser) {
340             ForumPermissions userPermissions = getUserPermissions(userID, -1);
341             //Combine permissions
342
finalPermissions = new ForumPermissions(finalPermissions, userPermissions);
343         }
344         //Add in anonymous perms.
345
ForumPermissions anonyPermissions = null;
346         if (userPermCache != null) {
347             anonyPermissions = (ForumPermissions) userPermCache.get(new Integer JavaDoc(-1));
348         }
349         //Otherwise, do our own lookup.
350
if (anonyPermissions == null) {
351             anonyPermissions = getUserPermissions(-1, -1);
352             //Add to cache so it will be there next time.
353
if (userPermCache != null) {
354                 userPermCache.add(new Integer JavaDoc(-1), anonyPermissions);
355             }
356         }
357         //Combine permissions
358
finalPermissions = new ForumPermissions(finalPermissions, anonyPermissions);
359
360         //If they are a valid user, figure out "any user" permissions.
361
if (isUser) {
362             ForumPermissions specialUserPermissions = null;
363             //Check for cache
364
if (userPermCache != null) {
365                 specialUserPermissions = (ForumPermissions) userPermCache.get(new Integer JavaDoc(0));
366             }
367             //Otherwise, do our own lookup.
368
if (specialUserPermissions == null) {
369                 specialUserPermissions = getUserPermissions(0, -1);
370                 //Add to cache so it will be there next time.
371
if (userPermCache != null) {
372                     userPermCache.add(new Integer JavaDoc(0), specialUserPermissions);
373                 }
374             }
375             //Combine permissions
376
finalPermissions = new ForumPermissions(finalPermissions, specialUserPermissions);
377         }
378
379         //Step 2 -- get Permissions for all groups the user is in.
380
int[] groups = ((DbProfileManager) getProfileManager()).getUserGroups(userID);
381         for (int i = 0; i < groups.length; i++) {
382             ForumPermissions groupPermissions = getGroupPermissions(groups[i], -1);
383             finalPermissions = new ForumPermissions(finalPermissions, groupPermissions);
384         }
385
386         //Finally, add user to cache so it will be there next time.
387
if (isUser && userPermCache != null) {
388             userPermCache.add(new Integer JavaDoc(userID), finalPermissions);
389         }
390
391         return finalPermissions;
392     }
393
394     public boolean hasPermission(int type) {
395         return true;
396     }
397
398     //OTHER METHODS//
399

400     /**
401      * Returns the cache manager object.
402      */

403     public DbCacheManager getCacheManager() {
404         return cacheManager;
405     }
406
407     /**
408      * Cleans the database of "junk". This is currently defined as: <ul>
409      * <li> Messages with no subject or body.
410      * <li> Messages that do not belong to a thread.</ul>
411      *
412      * Please be aware that this method will <b>permanently</b> delete forum
413      * content. You may want to perform a database backup before calling this
414      * method.<p>
415      *
416      * This method requires two database connections and may take a long time
417      * to execute, as it must iterate through ever message record in the
418      * database.
419      * :TODO: WEB IHM cleanDatabase
420      */

421     public void cleanDatabase() {
422         //Iterate through all forums, threads to delete unwanted messages.
423
Iterator JavaDoc forums = forums();
424         while (forums.hasNext()) {
425             Forum forum = (Forum) forums.next();
426             Iterator JavaDoc threads = forum.threads();
427             while (threads.hasNext()) {
428                 try {
429                     ForumThread thread = (ForumThread) threads.next();
430                     Iterator JavaDoc messages = thread.messages();
431                     while (messages.hasNext()) {
432                         try {
433                             Message message = (Message) messages.next();
434                             if (/*message.getSubject() == null ||*/
435                                 message.getBody() == null) {
436                                 
437                                 thread.deleteMessage(message);
438                             }
439                         } catch (Exception JavaDoc me) {
440                             log.error("",me);
441                         }
442                     }
443                 } catch (Exception JavaDoc te) {
444                     log.error("",te);
445                 }
446             }
447         }
448
449         /*
450                 //Select all message ID's directly from the message table.
451                 Connection con = null;
452                 PreparedStatement pstmt = null;
453                 try {
454                     con = DbConnectionManager.getConnection();
455                     pstmt = con.prepareStatement(ALL_MESSAGES);
456                     ResultSet rs = pstmt.executeQuery();
457                     while(rs.next()) {
458                         try {
459                             int messageID = rs.getInt(1);
460                             //Convert to object
461                             ForumMessage message = new DbForumMessage(messageID, this);
462                             ForumThread thread = message.getForumThread();
463                             if (thread == null) {
464                                 //manually delete this message from the database. It won't
465                                 //appear in any search indexes or in any threads, so this
466                                 //shouldn't have any side effects.
467                                 Connection con2 = null;
468                                 PreparedStatement pstmt2 = null;
469                                 try {
470                                     con2 = DbConnectionManager.getConnection();
471                                     pstmt2 = con.prepareStatement(DELETE_MESSAGE);
472                                     pstmt2.setInt(1, messageID);
473                                     pstmt2.execute();
474                                 }
475                                 catch( SQLException sqle ) {
476                                     
477                                 }
478                                 finally {
479                                     try { pstmt2.close(); }
480                                     catch (Exception e) { log.error("",e); }
481                                     try { con2.close(); }
482                                     catch (Exception e) { log.error("",e); }
483                                 }
484                             }
485                         }
486                         catch (ForumMessageNotFoundException fmnfe) {
487                             
488                         }
489                     }
490                 }
491                 catch( SQLException sqle ) {
492                    
493                 }
494                 finally {
495                     try { pstmt.close(); }
496                     catch (Exception e) { }
497                     try { con.close(); }
498                     catch (Exception e) { }
499                 }
500         */

501     }
502
503     /**
504      * Returns a thread specified by its id. Will return null
505      * if the thread is not in the forum. If cache is turned
506      * on, it will use it.
507      */

508     public DbForumThread getThread(int threadID, DbForum forum) throws ForumThreadNotFoundException {
509         //If cache is not enabled, do a new lookup of object
510
if (!cacheManager.isCacheEnabled()) {
511             return new DbForumThread(threadID, forum, this);
512         }
513         //Cache is enabled.
514
Integer JavaDoc threadIDInteger = new Integer JavaDoc(threadID);
515         DbForumThread thread = (DbForumThread) cacheManager.get(DbCacheManager.THREAD_CACHE, threadIDInteger);
516         if (thread == null) {
517             thread = new DbForumThread(threadID, forum, this);
518             cacheManager.add(DbCacheManager.THREAD_CACHE, threadIDInteger, thread);
519         }
520         return thread;
521     }
522
523     /**
524      * Returns a message from the thread based on its id. If cache is turned
525      * on, it will use it.
526      *
527      * @param messageID the ID of the message to get from the thread.
528      */

529     public DbForumMessage getMessage(int messageID) throws ForumMessageNotFoundException {
530         //If cache is not enabled, do a new lookup of object
531
if (!cacheManager.isCacheEnabled()) {
532             return new DbForumMessage(messageID, this);
533         }
534         //Cache is enabled.
535
Integer JavaDoc messageIDInteger = new Integer JavaDoc(messageID);
536         DbForumMessage message = (DbForumMessage) cacheManager.get(DbCacheManager.MESSAGE_CACHE, messageIDInteger);
537         if (message == null) {
538             //Load the message
539
message = new DbForumMessage(messageID, this);
540             //Add it to cache.
541
cacheManager.add(DbCacheManager.MESSAGE_CACHE, messageIDInteger, message);
542         }
543         return message;
544     }
545
546
547
548     /**
549      * Returns the permissions that a particular user has for the forum.
550      */

551     protected ForumPermissions getUserPermissions(int userID, int forumID) {
552         Connection JavaDoc con = null;
553         PreparedStatement JavaDoc pstmt = null;
554         //Initialize a permissions array with no permissions.
555
boolean[] permissions = new boolean[8];
556         for (int i = 0; i < permissions.length; i++) {
557             permissions[i] = false;
558         }
559         try {
560             con = DbConnectionManager.getConnection();
561             pstmt = con.prepareStatement(GET_USER_PERMS);
562             pstmt.setInt(1, forumID);
563             pstmt.setInt(2, userID);
564             ResultSet JavaDoc rs = pstmt.executeQuery();
565             while (rs.next()) {
566                 int newPerm = rs.getInt("permission");
567                 permissions[newPerm] = true;
568             }
569         } catch (SQLException JavaDoc sqle) {
570             log.error("Error in DbForum.java:" , sqle);
571             
572         } finally {
573             try {
574                 pstmt.close();
575             } catch (Exception JavaDoc e) {
576                 log.error("",e);
577             }
578             try {
579                 con.close();
580             } catch (Exception JavaDoc e) {
581                 log.error("",e);
582             }
583         }
584         return new ForumPermissions(permissions);
585     }
586
587     /**
588      * Returns the permissions that a particular group has for the forum.
589      */

590     protected ForumPermissions getGroupPermissions(int groupID, int forumID) {
591         Connection JavaDoc con = null;
592         PreparedStatement JavaDoc pstmt = null;
593         //Initialize a permissions array with no permissions.
594
boolean[] permissions = new boolean[8];
595         for (int i = 0; i < permissions.length; i++) {
596             permissions[i] = false;
597         }
598         try {
599             con = DbConnectionManager.getConnection();
600             pstmt = con.prepareStatement(GET_GROUP_PERMS);
601             pstmt.setInt(1, forumID);
602             pstmt.setInt(2, groupID);
603             ResultSet JavaDoc rs = pstmt.executeQuery();
604             while (rs.next()) {
605                 int newPerm = rs.getInt("permission");
606                 permissions[newPerm] = true;
607             }
608         } catch (SQLException JavaDoc sqle) {
609             log.error("",sqle);
610         } finally {
611             try {
612                 pstmt.close();
613             } catch (Exception JavaDoc e) {
614                 log.error("",e);
615             }
616             try {
617                 con.close();
618             } catch (Exception JavaDoc e) {
619                 log.error("",e);
620             }
621         }
622         return new ForumPermissions(permissions);
623     }
624 }
625
Popular Tags