001: /**
002: * Copyright (C) 2001 Yasna.com. All rights reserved.
003: *
004: * ===================================================================
005: * The Apache Software License, Version 1.1
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution,
020: * if any, must include the following acknowledgment:
021: * "This product includes software developed by
022: * Yasna.com (http://www.yasna.com)."
023: * Alternately, this acknowledgment may appear in the software itself,
024: * if and wherever such third-party acknowledgments normally appear.
025: *
026: * 4. The names "Yazd" and "Yasna.com" must not be used to
027: * endorse or promote products derived from this software without
028: * prior written permission. For written permission, please
029: * contact yazd@yasna.com.
030: *
031: * 5. Products derived from this software may not be called "Yazd",
032: * nor may "Yazd" appear in their name, without prior written
033: * permission of Yasna.com.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL YASNA.COM OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many
050: * individuals on behalf of Yasna.com. For more information
051: * on Yasna.com, please see <http://www.yasna.com>.
052: */
053:
054: /**
055: * Copyright (C) 2000 CoolServlets.com. All rights reserved.
056: *
057: * ===================================================================
058: * The Apache Software License, Version 1.1
059: *
060: * Redistribution and use in source and binary forms, with or without
061: * modification, are permitted provided that the following conditions
062: * are met:
063: *
064: * 1. Redistributions of source code must retain the above copyright
065: * notice, this list of conditions and the following disclaimer.
066: *
067: * 2. Redistributions in binary form must reproduce the above copyright
068: * notice, this list of conditions and the following disclaimer in
069: * the documentation and/or other materials provided with the
070: * distribution.
071: *
072: * 3. The end-user documentation included with the redistribution,
073: * if any, must include the following acknowledgment:
074: * "This product includes software developed by
075: * CoolServlets.com (http://www.coolservlets.com)."
076: * Alternately, this acknowledgment may appear in the software itself,
077: * if and wherever such third-party acknowledgments normally appear.
078: *
079: * 4. The names "Jive" and "CoolServlets.com" must not be used to
080: * endorse or promote products derived from this software without
081: * prior written permission. For written permission, please
082: * contact webmaster@coolservlets.com.
083: *
084: * 5. Products derived from this software may not be called "Jive",
085: * nor may "Jive" appear in their name, without prior written
086: * permission of CoolServlets.com.
087: *
088: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
089: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
090: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
091: * DISCLAIMED. IN NO EVENT SHALL COOLSERVLETS.COM OR
092: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
093: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
094: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
095: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
096: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
097: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
098: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
099: * SUCH DAMAGE.
100: * ====================================================================
101: *
102: * This software consists of voluntary contributions made by many
103: * individuals on behalf of CoolServlets.com. For more information
104: * on CoolServlets.com, please see <http://www.coolservlets.com>.
105: */package com.Yasna.forum.database;
106:
107: import java.util.*;
108: import java.sql.*;
109: import com.Yasna.forum.*;
110: import com.Yasna.util.*;
111:
112: /**
113: * Database implementation of the ProfileManager interface.
114: */
115: public class DbProfileManager implements ProfileManager {
116:
117: /** DATABASE QUERIES **/
118: private static final String USER_GROUPS = "SELECT groupID from yazdGroupUser WHERE userID=?";
119: private static final String USER_MESSAGE_COUNT = "SELECT count(*) FROM yazdMessage,yazdForum,yazdThread WHERE "
120: + "yazdMessage.userID=? AND yazdForum.forumID=? AND "
121: + "yazdThread.forumID=yazdForum.forumID AND "
122: + "yazdMessage.threadID=yazdThread.threadID";
123: private static final String USER_COUNT = "SELECT count(*) FROM "
124: + SystemProperty.getProperty("User.Table");
125: private static final String ALL_USER_MESSAGES = "SELECT messageID FROM yazdMessage WHERE userID=?";
126: private static final String DELETE_USER_MESSAGES = "UPDATE yazdMessage set userID=-1 WHERE userID=?";
127: private static final String DELETE_USER_PERMS = "DELETE FROM yazdUserPerm WHERE userID=?";
128: private static final String DELETE_USER_GROUPS = "DELETE FROM yazdGroupUser WHERE userID=?";
129: private static final String DELETE_USER_PROPS = "DELETE FROM yazdUserProp WHERE userID=?";
130: private static final String DELETE_USER = "DELETE FROM "
131: + SystemProperty.getProperty("User.Table") + " WHERE "
132: + SystemProperty.getProperty("User.Column.UserID") + "=?";
133: private static final String GROUP_COUNT = "SELECT count(*) FROM yazdGroup";
134: private static final String DELETE_GROUP_USERS = "DELETE FROM yazdGroupUser WHERE groupID=?";
135: private static final String DELETE_GROUP = "DELETE FROM yazdGroup WHERE groupID=?";
136:
137: private User anonymousUser = null;
138: private User specialUser = null;
139: private DbForumFactory factory;
140:
141: /**
142: * Creates a new ProfileManager.
143: */
144: public DbProfileManager(DbForumFactory factory) {
145: this .factory = factory;
146: try {
147: anonymousUser = getUser(-1);
148: specialUser = getUser(0);
149: } catch (UserNotFoundException unfe) {
150: }
151: }
152:
153: //FROM THE PROFILEMANAGER INTERFACE//
154:
155: public User createUser(String username, String password,
156: String email) throws UserAlreadyExistsException {
157: User newUser = null;
158: try {
159: User existingUser = getUser(username);
160:
161: //The user already exists since now exception, so:
162: throw new UserAlreadyExistsException();
163: } catch (UserNotFoundException unfe) {
164: //The user doesn't already exist so we can create a new user
165: newUser = new DbUser(username, password, email);
166: }
167: return newUser;
168: }
169:
170: public boolean activateUser(int userID, String Code) {
171: DbUser user;
172: boolean success = false;
173: try {
174: DbCacheManager cacheManager = factory.getCacheManager();
175: //If cache is not enabled, do a new lookup of object
176: if (!cacheManager.isCacheEnabled()) {
177: user = new DbUser(userID);
178: }
179: //Cache is enabled.
180: Integer userIDInteger = new Integer(userID);
181: user = (DbUser) cacheManager.get(DbCacheManager.USER_CACHE,
182: userIDInteger);
183: if (user == null) {
184: user = new DbUser(userID);
185: cacheManager.add(DbCacheManager.USER_CACHE,
186: userIDInteger, user);
187: }
188: } catch (Exception e) {
189: return success;
190: }
191: if (user.getProperty("notactive") != null
192: && user.getProperty("notactive").equals(Code)) {
193: user.activateUser();
194: return true;
195: } else {
196: return false;
197: }
198:
199: }
200:
201: public User getUser(int userID) throws UserNotFoundException {
202: DbCacheManager cacheManager = factory.getCacheManager();
203: //If cache is not enabled, do a new lookup of object
204: if (!cacheManager.isCacheEnabled()) {
205: return new DbUser(userID);
206: }
207: //Cache is enabled.
208: Integer userIDInteger = new Integer(userID);
209: DbUser user = (DbUser) cacheManager.get(
210: DbCacheManager.USER_CACHE, userIDInteger);
211: if (user == null) {
212: user = new DbUser(userID);
213: cacheManager.add(DbCacheManager.USER_CACHE, userIDInteger,
214: user);
215: }
216: return user;
217: }
218:
219: public User getUser(String username) throws UserNotFoundException {
220: DbCacheManager cacheManager = factory.getCacheManager();
221: //If cache is not enabled, do a new lookup of object
222: if (!cacheManager.isCacheEnabled()) {
223: User user = new DbUser(username);
224: return getUser(user.getID());
225: }
226: //Cache is enabled.
227: CacheableInteger userIDInteger = (CacheableInteger) cacheManager
228: .get(DbCacheManager.USER_ID_CACHE, username);
229: //if id wan't found in cache, load it up and put it there.
230: if (userIDInteger == null) {
231: User user = new DbUser(username);
232: userIDInteger = new CacheableInteger(new Integer(user
233: .getID()));
234: cacheManager.add(DbCacheManager.USER_ID_CACHE, username,
235: userIDInteger);
236: }
237: return getUser(userIDInteger.getInteger().intValue());
238: }
239:
240: public User getAnonymousUser() {
241: return anonymousUser;
242: }
243:
244: public User getSpecialUser() {
245: return specialUser;
246: }
247:
248: public void deleteUser(User user) throws UnauthorizedException {
249: int userID = user.getID();
250: int[] messages;
251: //Get array of all user's messages in the system so that
252: //we can expire them from cache.
253: ArrayList tempMessages = new ArrayList();
254: Connection con = null;
255: PreparedStatement pstmt = null;
256: try {
257: con = DbConnectionManager.getConnection();
258: pstmt = con.prepareStatement(ALL_USER_MESSAGES);
259: pstmt.setInt(1, user.getID());
260: ResultSet rs = pstmt.executeQuery();
261: while (rs.next()) {
262: tempMessages.add(new Integer(rs.getInt("messageID")));
263: }
264: } catch (SQLException sqle) {
265: System.err
266: .println("Error in DbProfileManager:deleteUser()-"
267: + sqle);
268: sqle.printStackTrace();
269: } finally {
270: try {
271: pstmt.close();
272: } catch (Exception e) {
273: e.printStackTrace();
274: }
275: try {
276: con.close();
277: } catch (Exception e) {
278: e.printStackTrace();
279: }
280: }
281: //Now copy into an array.
282: messages = new int[tempMessages.size()];
283: for (int i = 0; i < messages.length; i++) {
284: messages[i] = ((Integer) tempMessages.get(i)).intValue();
285: }
286:
287: con = null;
288: pstmt = null;
289: try {
290: con = DbConnectionManager.getConnection();
291: //mark all message by user as anonymous
292: pstmt = con.prepareStatement(DELETE_USER_MESSAGES);
293: pstmt.setInt(1, userID);
294: pstmt.execute();
295: pstmt.close();
296: //remove all permissions given to user
297: pstmt = con.prepareStatement(DELETE_USER_PERMS);
298: pstmt.setInt(1, userID);
299: pstmt.execute();
300: pstmt.close();
301: //remove user from all groups
302: pstmt = con.prepareStatement(DELETE_USER_GROUPS);
303: pstmt.setInt(1, userID);
304: pstmt.execute();
305: pstmt.close();
306: //delete all of the users's extended properties
307: pstmt = con.prepareStatement(DELETE_USER_PROPS);
308: pstmt.setInt(1, userID);
309: pstmt.execute();
310: pstmt.close();
311: //delete the actual user entry
312: pstmt = con.prepareStatement(DELETE_USER);
313: pstmt.setInt(1, userID);
314: pstmt.execute();
315: } catch (SQLException sqle) {
316: sqle.printStackTrace();
317: } finally {
318: try {
319: pstmt.close();
320: } catch (Exception e) {
321: e.printStackTrace();
322: }
323: try {
324: con.close();
325: } catch (Exception e) {
326: e.printStackTrace();
327: }
328: }
329:
330: //Finally, expire all relevant caches
331: //all of users's messages
332: DbCacheManager cacheManager = factory.getCacheManager();
333: for (int i = 0; i < messages.length; i++) {
334: cacheManager.remove(DbCacheManager.MESSAGE_CACHE,
335: new Integer(messages[i]));
336: }
337: //user cache
338: cacheManager.remove(DbCacheManager.USER_ID_CACHE, user
339: .getUsername());
340: cacheManager.remove(DbCacheManager.USER_CACHE, new Integer(
341: userID));
342: }
343:
344: public Group createGroup(String name) throws UnauthorizedException,
345: GroupAlreadyExistsException {
346: Group newGroup = null;
347: try {
348: Group existingGroup = getGroup(name);
349:
350: //The group already exists since now exception, so:
351: throw new GroupAlreadyExistsException();
352: } catch (GroupNotFoundException unfe) {
353: //The group doesn't already exist so we can create a new group
354: newGroup = new DbGroup(name, factory);
355: }
356: return newGroup;
357: }
358:
359: public Group getGroup(int groupID) throws GroupNotFoundException {
360: DbCacheManager cacheManager = factory.getCacheManager();
361: //If cache is not enabled, do a new lookup of object
362: if (!cacheManager.isCacheEnabled()) {
363: return new DbGroup(groupID, factory);
364: }
365: //Cache is enabled.
366: Integer groupIDInteger = new Integer(groupID);
367: DbGroup group = (DbGroup) cacheManager.get(
368: DbCacheManager.GROUP_CACHE, groupIDInteger);
369: if (group == null) {
370: group = new DbGroup(groupID, factory);
371: cacheManager.add(DbCacheManager.GROUP_CACHE,
372: groupIDInteger, group);
373: }
374: return group;
375: }
376:
377: public Group getGroup(String name) throws GroupNotFoundException {
378: DbCacheManager cacheManager = factory.getCacheManager();
379: //If cache is not enabled, do a new lookup of object
380: if (!cacheManager.isCacheEnabled()) {
381: Group group = new DbGroup(name, null, factory);
382: return getGroup(group.getID());
383: }
384: //Cache is enabled.
385: CacheableInteger groupIDInteger = (CacheableInteger) cacheManager
386: .get(DbCacheManager.GROUP_ID_CACHE, name);
387: //if id wan't found in cache, load it up and put it there.
388: if (groupIDInteger == null) {
389: Group group = new DbGroup(name, null, factory);
390: groupIDInteger = new CacheableInteger(new Integer(group
391: .getID()));
392: cacheManager.add(DbCacheManager.GROUP_ID_CACHE, name,
393: groupIDInteger);
394: }
395: return getGroup(groupIDInteger.getInteger().intValue());
396: }
397:
398: public void deleteGroup(Group group) throws UnauthorizedException {
399: int groupID = group.getID();
400: int[] members = new int[group.getMemberCount()];
401: Iterator iter = group.members();
402: for (int i = 0; i < members.length; i++) {
403: User user = (User) iter.next();
404: members[i] = user.getID();
405: }
406:
407: Connection con = null;
408: PreparedStatement pstmt = null;
409: try {
410: con = DbConnectionManager.getConnection();
411: //mark all message by user as anonymous
412: pstmt = con.prepareStatement(DELETE_GROUP_USERS);
413: pstmt.setInt(1, groupID);
414: pstmt.execute();
415: pstmt.close();
416: //remove all permissions given to user
417: pstmt = con.prepareStatement(DELETE_GROUP);
418: pstmt.setInt(1, groupID);
419: pstmt.execute();
420: pstmt.close();
421: } catch (SQLException sqle) {
422: sqle.printStackTrace();
423: } finally {
424: try {
425: pstmt.close();
426: } catch (Exception e) {
427: e.printStackTrace();
428: }
429: try {
430: con.close();
431: } catch (Exception e) {
432: e.printStackTrace();
433: }
434: }
435:
436: //Finally, expire all relevant caches
437: DbCacheManager cacheManager = factory.getCacheManager();
438: cacheManager.remove(DbCacheManager.GROUP_ID_CACHE, group
439: .getName());
440: cacheManager.remove(DbCacheManager.GROUP_CACHE, new Integer(
441: groupID));
442: //Removing a group can change the permissions of all the users in that
443: //group. Therefore, remove each user from the user perms cache.
444: for (int i = 0; i < members.length; i++) {
445: cacheManager.removeUserPerm(new Integer(members[i]));
446: }
447: }
448:
449: public int getUserCount() {
450: int count = 0;
451: Connection con = null;
452: PreparedStatement pstmt = null;
453: try {
454: con = DbConnectionManager.getConnection();
455: pstmt = con.prepareStatement(USER_COUNT);
456: ResultSet rs = pstmt.executeQuery();
457: if (rs.next()) {
458: count = rs.getInt(1);
459: }
460: } catch (SQLException sqle) {
461: sqle.printStackTrace();
462: } finally {
463: try {
464: pstmt.close();
465: } catch (Exception e) {
466: e.printStackTrace();
467: }
468: try {
469: con.close();
470: } catch (Exception e) {
471: e.printStackTrace();
472: }
473: }
474: return count;
475: }
476:
477: public int getGroupCount() {
478: int count = 0;
479: Connection con = null;
480: PreparedStatement pstmt = null;
481: try {
482: con = DbConnectionManager.getConnection();
483: pstmt = con.prepareStatement(GROUP_COUNT);
484: ResultSet rs = pstmt.executeQuery();
485: if (rs.next()) {
486: count = rs.getInt(1);
487: }
488: } catch (SQLException sqle) {
489: sqle.printStackTrace();
490: } finally {
491: try {
492: pstmt.close();
493: } catch (Exception e) {
494: e.printStackTrace();
495: }
496: try {
497: con.close();
498: } catch (Exception e) {
499: e.printStackTrace();
500: }
501: }
502: return count;
503: }
504:
505: public Iterator users() {
506: return new DbUserIterator(this );
507: }
508:
509: public Iterator users(int startIndex, int numResults) {
510: return new DbUserIterator(this , startIndex, numResults);
511: }
512:
513: public Iterator groups() {
514: return new DbGroupIterator(this );
515: }
516:
517: public Iterator groups(int startIndex, int numResults) {
518: return new DbGroupIterator(this , startIndex, numResults);
519: }
520:
521: public int userMessageCount(User user, Forum forum) {
522: int count = 0;
523: Connection con = null;
524: PreparedStatement pstmt = null;
525: try {
526: con = DbConnectionManager.getConnection();
527: pstmt = con.prepareStatement(USER_MESSAGE_COUNT);
528: pstmt.setInt(1, user.getID());
529: pstmt.setInt(2, forum.getID());
530: ResultSet rs = pstmt.executeQuery();
531: if (rs.next()) {
532: count = rs.getInt(1);
533: }
534: } catch (SQLException sqle) {
535: sqle.printStackTrace();
536: } finally {
537: try {
538: pstmt.close();
539: } catch (Exception e) {
540: e.printStackTrace();
541: }
542: try {
543: con.close();
544: } catch (Exception e) {
545: e.printStackTrace();
546: }
547: }
548: return count;
549: }
550:
551: public Iterator userMessages(User user, Forum forum, int start,
552: int numRes) {
553: return new DbUserMessagesIterator(factory, user, forum, start,
554: numRes);
555: }
556:
557: /**
558: * Returns an array of all the groups that the user belongs to.
559: */
560: protected int[] getUserGroups(int userID) {
561: Connection con = null;
562: PreparedStatement pstmt = null;
563: int[] groups = new int[0];
564: try {
565: con = DbConnectionManager.getConnection();
566: pstmt = con.prepareStatement(USER_GROUPS);
567: pstmt.setInt(1, userID);
568: ResultSet rs = pstmt.executeQuery();
569: ArrayList groupList = new ArrayList();
570: while (rs.next()) {
571: groupList.add(new Integer(rs.getInt("groupID")));
572: }
573: groups = new int[groupList.size()];
574: for (int i = 0; i < groups.length; i++) {
575: groups[i] = ((Integer) groupList.get(i)).intValue();
576: }
577: } catch (SQLException sqle) {
578: sqle.printStackTrace();
579: } finally {
580: try {
581: pstmt.close();
582: } catch (Exception e) {
583: e.printStackTrace();
584: }
585: try {
586: con.close();
587: } catch (Exception e) {
588: e.printStackTrace();
589: }
590: }
591: return groups;
592: }
593: }
|