001: /*
002: * NEMESIS-FORUM.
003: * Copyright (C) 2002 David Laurent(lithium2@free.fr). All rights reserved.
004: *
005: * Copyright (c) 2000 The Apache Software Foundation. All rights reserved.
006: *
007: * Copyright (C) 2001 Yasna.com. All rights reserved.
008: *
009: * Copyright (C) 2000 CoolServlets.com. All rights reserved.
010: *
011: * NEMESIS-FORUM. is free software; you can redistribute it and/or
012: * modify it under the terms of the Apache Software License, Version 1.1,
013: * or (at your option) any later version.
014: *
015: * NEMESIS-FORUM core framework, NEMESIS-FORUM backoffice, NEMESIS-FORUM frontoffice
016: * application are parts of NEMESIS-FORUM and are distributed under
017: * same terms of licence.
018: *
019: *
020: * NEMESIS-FORUM includes software developed by the Apache Software Foundation (http://www.apache.org/)
021: * and software developed by CoolServlets.com (http://www.coolservlets.com).
022: * and software developed by Yasna.com (http://www.yasna.com).
023: *
024: */
025: package org.nemesis.forum.impl;
026:
027: import java.sql.Connection;
028: import java.sql.PreparedStatement;
029: import java.sql.ResultSet;
030: import java.sql.SQLException;
031: import java.util.ArrayList;
032: import java.util.Iterator;
033:
034: import org.apache.commons.logging.Log;
035: import org.apache.commons.logging.LogFactory;
036: import org.nemesis.forum.Forum;
037: import org.nemesis.forum.Group;
038: import org.nemesis.forum.ProfileManager;
039: import org.nemesis.forum.User;
040: import org.nemesis.forum.exception.GroupAlreadyExistsException;
041: import org.nemesis.forum.exception.GroupNotFoundException;
042: import org.nemesis.forum.exception.UnauthorizedException;
043: import org.nemesis.forum.exception.UserAlreadyExistsException;
044: import org.nemesis.forum.exception.UserNotFoundException;
045: import org.nemesis.forum.util.cache.CacheableInteger;
046: import org.nemesis.forum.util.jdbc.DbConnectionManager;
047:
048: /**
049: * Database implementation of the ProfileManager interface.
050: */
051: public class DbProfileManager implements ProfileManager {
052: static protected Log log = LogFactory
053: .getLog(DbProfileManager.class);
054: /** DATABASE QUERIES **/
055: private static final String USER_GROUPS = "SELECT groupID from yazdGroupUser WHERE userID=?";
056: private static final String USER_MESSAGE_COUNT = "SELECT count(*) FROM yazdMessage,yazdForum,yazdThread WHERE "
057: + "yazdMessage.userID=? AND yazdForum.forumID=? AND "
058: + "yazdThread.forumID=yazdForum.forumID AND "
059: + "yazdMessage.threadID=yazdThread.threadID";
060: private static final String USER_COUNT = "SELECT count(*) FROM yazdUser";
061: private static final String ALL_USER_MESSAGES = "SELECT messageID FROM yazdMessage WHERE userID=?";
062: private static final String DELETE_USER_MESSAGES = "UPDATE yazdMessage set userID=-1 WHERE userID=?";
063: private static final String DELETE_USER_PERMS = "DELETE FROM yazdUserPerm WHERE userID=?";
064: private static final String DELETE_USER_GROUPS = "DELETE FROM yazdGroupUser WHERE userID=?";
065: private static final String DELETE_USER_PROPS = "DELETE FROM yazdUserProp WHERE userID=?";
066: private static final String DELETE_USER = "DELETE FROM yazdUser WHERE userID=?";
067: private static final String GROUP_COUNT = "SELECT count(*) FROM yazdGroup";
068: private static final String DELETE_GROUP_USERS = "DELETE FROM yazdGroupUser WHERE groupID=?";
069: private static final String DELETE_GROUP = "DELETE FROM yazdGroup WHERE groupID=?";
070:
071: private User anonymousUser = null;
072: private User specialUser = null;
073: private DbForumFactory factory;
074:
075: /**
076: * Creates a new ProfileManager.
077: */
078: public DbProfileManager(DbForumFactory factory) {
079: this .factory = factory;
080: try {
081: anonymousUser = getUser(-1);
082: specialUser = getUser(0);
083: } catch (UserNotFoundException unfe) {
084: }
085: }
086:
087: //FROM THE PROFILEMANAGER INTERFACE//
088:
089: public User createUser(String username, String password,
090: String email) throws UserAlreadyExistsException {
091: User newUser = null;
092: try {
093: User existingUser = getUser(username);
094:
095: //The user already exists since now exception, so:
096: throw new UserAlreadyExistsException();
097: } catch (UserNotFoundException unfe) {
098: //The user doesn't already exist so we can create a new user
099: newUser = new DbUser(username, password, email);
100: }
101: return newUser;
102: }
103:
104: public User getUser(int userID) throws UserNotFoundException {
105: DbCacheManager cacheManager = factory.getCacheManager();
106: //If cache is not enabled, do a new lookup of object
107: if (!cacheManager.isCacheEnabled()) {
108: return new DbUser(userID);
109: }
110: //Cache is enabled.
111: Integer userIDInteger = new Integer(userID);
112: DbUser user = (DbUser) cacheManager.get(
113: DbCacheManager.USER_CACHE, userIDInteger);
114: if (user == null) {
115: user = new DbUser(userID);
116: cacheManager.add(DbCacheManager.USER_CACHE, userIDInteger,
117: user);
118: }
119: return user;
120: }
121:
122: public User getUser(String username) throws UserNotFoundException {
123: DbCacheManager cacheManager = factory.getCacheManager();
124: //If cache is not enabled, do a new lookup of object
125: if (!cacheManager.isCacheEnabled()) {
126: User user = new DbUser(username);
127: return getUser(user.getID());
128: }
129: //Cache is enabled.
130: CacheableInteger userIDInteger = (CacheableInteger) cacheManager
131: .get(DbCacheManager.USER_ID_CACHE, username);
132: //if id wan't found in cache, load it up and put it there.
133: if (userIDInteger == null) {
134: User user = new DbUser(username);
135: userIDInteger = new CacheableInteger(new Integer(user
136: .getID()));
137: cacheManager.add(DbCacheManager.USER_ID_CACHE, username,
138: userIDInteger);
139: }
140: return getUser(userIDInteger.getInteger().intValue());
141: }
142:
143: public User getAnonymousUser() {
144: return anonymousUser;
145: }
146:
147: public User getSpecialUser() {
148: return specialUser;
149: }
150:
151: public void deleteUser(User user) throws UnauthorizedException {
152: int userID = user.getID();
153: int[] messages;
154: //Get array of all user's messages in the system so that
155: //we can expire them from cache.
156: ArrayList tempMessages = new ArrayList();
157: Connection con = null;
158: PreparedStatement pstmt = null;
159: try {
160: con = DbConnectionManager.getConnection();
161: pstmt = con.prepareStatement(ALL_USER_MESSAGES);
162: pstmt.setInt(1, user.getID());
163: ResultSet rs = pstmt.executeQuery();
164: while (rs.next()) {
165: tempMessages.add(new Integer(rs.getInt("messageID")));
166: }
167: } catch (SQLException sqle) {
168: log.error("Error in DbProfileManager:deleteUser()-", sqle);
169:
170: } finally {
171: try {
172: pstmt.close();
173: } catch (Exception e) {
174: log.error("", e);
175: }
176: try {
177: con.close();
178: } catch (Exception e) {
179: log.error("", e);
180: }
181: }
182: //Now copy into an array.
183: messages = new int[tempMessages.size()];
184: for (int i = 0; i < messages.length; i++) {
185: messages[i] = ((Integer) tempMessages.get(i)).intValue();
186: }
187:
188: con = null;
189: pstmt = null;
190: try {
191: con = DbConnectionManager.getConnection();
192: //mark all message by user as anonymous
193: pstmt = con.prepareStatement(DELETE_USER_MESSAGES);
194: pstmt.setInt(1, userID);
195: pstmt.execute();
196: pstmt.close();
197: //remove all permissions given to user
198: pstmt = con.prepareStatement(DELETE_USER_PERMS);
199: pstmt.setInt(1, userID);
200: pstmt.execute();
201: pstmt.close();
202: //remove user from all groups
203: pstmt = con.prepareStatement(DELETE_USER_GROUPS);
204: pstmt.setInt(1, userID);
205: pstmt.execute();
206: pstmt.close();
207: //delete all of the users's extended properties
208: pstmt = con.prepareStatement(DELETE_USER_PROPS);
209: pstmt.setInt(1, userID);
210: pstmt.execute();
211: pstmt.close();
212: //delete the actual user entry
213: pstmt = con.prepareStatement(DELETE_USER);
214: pstmt.setInt(1, userID);
215: pstmt.execute();
216: } catch (SQLException sqle) {
217: log.error("", sqle);
218: } finally {
219: try {
220: pstmt.close();
221: } catch (Exception e) {
222: log.error("", e);
223: }
224: try {
225: con.close();
226: } catch (Exception e) {
227: log.error("", e);
228: }
229: }
230:
231: //Finally, expire all relevant caches
232: //all of users's messages
233: DbCacheManager cacheManager = factory.getCacheManager();
234: for (int i = 0; i < messages.length; i++) {
235: cacheManager.remove(DbCacheManager.MESSAGE_CACHE,
236: new Integer(messages[i]));
237: }
238: //user cache
239: cacheManager.remove(DbCacheManager.USER_ID_CACHE, user
240: .getUsername());
241: cacheManager.remove(DbCacheManager.USER_CACHE, new Integer(
242: userID));
243: }
244:
245: public Group createGroup(String name) throws UnauthorizedException,
246: GroupAlreadyExistsException {
247: Group newGroup = null;
248: try {
249: Group existingGroup = getGroup(name);
250:
251: //The group already exists since now exception, so:
252: throw new GroupAlreadyExistsException();
253: } catch (GroupNotFoundException unfe) {
254: //The group doesn't already exist so we can create a new group
255: newGroup = new DbGroup(name, factory);
256: }
257: return newGroup;
258: }
259:
260: public Group getGroup(int groupID) throws GroupNotFoundException {
261: DbCacheManager cacheManager = factory.getCacheManager();
262: //If cache is not enabled, do a new lookup of object
263: if (!cacheManager.isCacheEnabled()) {
264: return new DbGroup(groupID, factory);
265: }
266: //Cache is enabled.
267: Integer groupIDInteger = new Integer(groupID);
268: DbGroup group = (DbGroup) cacheManager.get(
269: DbCacheManager.GROUP_CACHE, groupIDInteger);
270: if (group == null) {
271: group = new DbGroup(groupID, factory);
272: cacheManager.add(DbCacheManager.GROUP_CACHE,
273: groupIDInteger, group);
274: }
275: return group;
276: }
277:
278: public Group getGroup(String name) throws GroupNotFoundException {
279: DbCacheManager cacheManager = factory.getCacheManager();
280: //If cache is not enabled, do a new lookup of object
281: if (!cacheManager.isCacheEnabled()) {
282: Group group = new DbGroup(name, null, factory);
283: return getGroup(group.getID());
284: }
285: //Cache is enabled.
286: CacheableInteger groupIDInteger = (CacheableInteger) cacheManager
287: .get(DbCacheManager.GROUP_ID_CACHE, name);
288: //if id wan't found in cache, load it up and put it there.
289: if (groupIDInteger == null) {
290: Group group = new DbGroup(name, null, factory);
291: groupIDInteger = new CacheableInteger(new Integer(group
292: .getID()));
293: cacheManager.add(DbCacheManager.GROUP_ID_CACHE, name,
294: groupIDInteger);
295: }
296: return getGroup(groupIDInteger.getInteger().intValue());
297: }
298:
299: public void deleteGroup(Group group) throws UnauthorizedException {
300: int groupID = group.getID();
301: int[] members = new int[group.getMemberCount()];
302: Iterator iter = group.members();
303: for (int i = 0; i < members.length; i++) {
304: User user = (User) iter.next();
305: members[i] = user.getID();
306: }
307:
308: Connection con = null;
309: PreparedStatement pstmt = null;
310: try {
311: con = DbConnectionManager.getConnection();
312: //mark all message by user as anonymous
313: pstmt = con.prepareStatement(DELETE_GROUP_USERS);
314: pstmt.setInt(1, groupID);
315: pstmt.execute();
316: pstmt.close();
317: //remove all permissions given to user
318: pstmt = con.prepareStatement(DELETE_GROUP);
319: pstmt.setInt(1, groupID);
320: pstmt.execute();
321: pstmt.close();
322: } catch (SQLException sqle) {
323: log.error("", sqle);
324: } finally {
325: try {
326: pstmt.close();
327: } catch (Exception e) {
328: log.error("", e);
329: }
330: try {
331: con.close();
332: } catch (Exception e) {
333: log.error("", e);
334: }
335: }
336:
337: //Finally, expire all relevant caches
338: DbCacheManager cacheManager = factory.getCacheManager();
339: cacheManager.remove(DbCacheManager.GROUP_ID_CACHE, group
340: .getName());
341: cacheManager.remove(DbCacheManager.GROUP_CACHE, new Integer(
342: groupID));
343: //Removing a group can change the permissions of all the users in that
344: //group. Therefore, remove each user from the user perms cache.
345: for (int i = 0; i < members.length; i++) {
346: cacheManager.removeUserPerm(new Integer(members[i]));
347: }
348: }
349:
350: public int getUserCount() {
351: int count = 0;
352: Connection con = null;
353: PreparedStatement pstmt = null;
354: try {
355: con = DbConnectionManager.getConnection();
356: pstmt = con.prepareStatement(USER_COUNT);
357: ResultSet rs = pstmt.executeQuery();
358: if (rs.next()) {
359: count = rs.getInt(1);
360: }
361: } catch (SQLException sqle) {
362: log.error("", sqle);
363: } finally {
364: try {
365: pstmt.close();
366: } catch (Exception e) {
367: log.error("", e);
368: }
369: try {
370: con.close();
371: } catch (Exception e) {
372: log.error("", e);
373: }
374: }
375: return count;
376: }
377:
378: public int getGroupCount() {
379: int count = 0;
380: Connection con = null;
381: PreparedStatement pstmt = null;
382: try {
383: con = DbConnectionManager.getConnection();
384: pstmt = con.prepareStatement(GROUP_COUNT);
385: ResultSet rs = pstmt.executeQuery();
386: if (rs.next()) {
387: count = rs.getInt(1);
388: }
389: } catch (SQLException sqle) {
390: log.error("", sqle);
391: } finally {
392: try {
393: pstmt.close();
394: } catch (Exception e) {
395: log.error("", e);
396: }
397: try {
398: con.close();
399: } catch (Exception e) {
400: log.error("", e);
401: }
402: }
403: return count;
404: }
405:
406: public Iterator users() {
407: return new DbUserIterator(this );
408: }
409:
410: public Iterator users(int startIndex, int numResults) {
411: return new DbUserIterator(this , startIndex, numResults);
412: }
413:
414: public Iterator groups() {
415: return new DbGroupIterator(this );
416: }
417:
418: public Iterator groups(int startIndex, int numResults) {
419: return new DbGroupIterator(this , startIndex, numResults);
420: }
421:
422: public int userMessageCount(User user, Forum forum) {
423: int count = 0;
424: Connection con = null;
425: PreparedStatement pstmt = null;
426: try {
427: con = DbConnectionManager.getConnection();
428: pstmt = con.prepareStatement(USER_MESSAGE_COUNT);
429: pstmt.setInt(1, user.getID());
430: pstmt.setInt(2, forum.getID());
431: ResultSet rs = pstmt.executeQuery();
432: if (rs.next()) {
433: count = rs.getInt(1);
434: }
435: } catch (SQLException sqle) {
436: log.error("", sqle);
437: } finally {
438: try {
439: pstmt.close();
440: } catch (Exception e) {
441: log.error("", e);
442: }
443: try {
444: con.close();
445: } catch (Exception e) {
446: log.error("", e);
447: }
448: }
449: return count;
450: }
451:
452: public Iterator userMessages(User user, Forum forum) {
453: return new DbUserMessagesIterator(factory, user, forum);
454: }
455:
456: /**
457: * Returns an array of all the groups that the user belongs to.
458: */
459: protected int[] getUserGroups(int userID) {
460: Connection con = null;
461: PreparedStatement pstmt = null;
462: int[] groups = new int[0];
463: try {
464: con = DbConnectionManager.getConnection();
465: pstmt = con.prepareStatement(USER_GROUPS);
466: pstmt.setInt(1, userID);
467: ResultSet rs = pstmt.executeQuery();
468: ArrayList groupList = new ArrayList();
469: while (rs.next()) {
470: groupList.add(new Integer(rs.getInt("groupID")));
471: }
472: groups = new int[groupList.size()];
473: for (int i = 0; i < groups.length; i++) {
474: groups[i] = ((Integer) groupList.get(i)).intValue();
475: }
476: } catch (SQLException sqle) {
477: log.error("", sqle);
478: } finally {
479: try {
480: pstmt.close();
481: } catch (Exception e) {
482: log.error("", e);
483: }
484: try {
485: con.close();
486: } catch (Exception e) {
487: log.error("", e);
488: }
489: }
490: return groups;
491: }
492: }
|