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.Authorization;
037: import org.nemesis.forum.ForumPermissions;
038: import org.nemesis.forum.Group;
039: import org.nemesis.forum.ProfileManager;
040: import org.nemesis.forum.User;
041: import org.nemesis.forum.exception.GroupNotFoundException;
042: import org.nemesis.forum.exception.UnauthorizedException;
043: import org.nemesis.forum.exception.UserNotFoundException;
044: import org.nemesis.forum.util.cache.CacheSizes;
045: import org.nemesis.forum.util.cache.Cacheable;
046: import org.nemesis.forum.util.jdbc.DbConnectionManager;
047:
048: /**
049: * Database implementation of the Group interface.
050: *
051: * @see Group
052: */
053: public class DbGroup implements Group, Cacheable {
054: static protected Log log = LogFactory.getLog(DbGroup.class);
055: /** DATABASE QUERIES **/
056: private static final String ADD_ADMIN = "INSERT INTO yazdGroupUser(groupID,userID,administrator) VALUES(?,?,1)";
057: private static final String REMOVE_ADMIN = "DELETE FROM yazdGroupUser WHERE groupID=? AND userID=? AND administrator=1";
058: private static final String ADD_USER = "INSERT INTO yazdGroupUser(groupID,userID,administrator) VALUES(?,?,0)";
059: private static final String REMOVE_USER = "DELETE FROM yazdGroupUser WHERE groupID=? AND userID=? AND administrator=0";
060: private static final String ADMIN_TEST = "SELECT userID FROM yazdGroupUser WHERE groupID=? AND userID=? AND "
061: + "administrator=1";
062: private static final String MEMBER_TEST = "SELECT userID FROM yazdGroupUser WHERE groupID=? AND userID=?";
063: private static final String ADMIN_COUNT = "SELECT count(*) FROM yazdGroupUser WHERE groupID=? "
064: + "AND administrator=1";
065: private static final String MEMBER_COUNT = "SELECT DISTINCT count(userID) FROM yazdGroupUser "
066: + "WHERE groupID=?";
067: private static final String LOAD_ADMINS = "SELECT userID FROM yazdGroupUser WHERE administrator=1 AND groupID=?";
068: private static final String LOAD_USERS = "SELECT userID FROM yazdGroupUser WHERE groupID=?";
069: private static final String LOAD_GROUP_BY_ID = "SELECT * FROM yazdGroup WHERE groupID=?";
070: private static final String LOAD_GROUP_BY_NAME = "SELECT * FROM yazdGroup WHERE name=?";
071: private static final String INSERT_GROUP = "INSERT INTO yazdGroup(name,description,groupID) VALUES(?,?,?)";
072: private static final String SAVE_GROUP = "UPDATE yazdGroup SET name=?, description=? WHERE groupID=?";
073:
074: private int id;
075: private String name = null;
076: private String description = "";
077:
078: private ProfileManager profileManager;
079: private DbForumFactory factory;
080:
081: /**
082: * Creates a new group.
083: *
084: * @param the name of the group.
085: * @param profileManager a ProfileManager that can be used to perform user
086: * and group operations.
087: */
088: protected DbGroup(String name, DbForumFactory factory) {
089: this .name = name;
090: this .factory = factory;
091: this .profileManager = factory.getProfileManager();
092: this .id = DbSequenceManager.nextID("Group");
093: insertIntoDb();
094: }
095:
096: /**
097: * Loads a group from the database based on its id.
098: *
099: * @param id the id of the group to load.
100: * @param profileManager a ProfileManager that can be used to perform user
101: * and group operations.
102: */
103: protected DbGroup(int id, DbForumFactory factory)
104: throws GroupNotFoundException {
105: this .id = id;
106: this .factory = factory;
107: this .profileManager = factory.getProfileManager();
108: loadFromDb();
109: }
110:
111: /**
112: * Loads a group from the database based on its name. The implementation
113: * of this method is rather hackish since it includes a fake parameter just
114: * so that it can have a different method signature than the first
115: * constructor. Even so, this methodology makes this class behave more like
116: * our other classes, so we're gleefully leaving it this way. :)
117: *
118: * @param name the name of the group to load.
119: * @param fake a fake paramater that can always be null.
120: * @param profileManager a ProfileManager that can be used to perform user
121: * and group operations.
122: */
123: protected DbGroup(String name, Object fake, DbForumFactory factory)
124: throws GroupNotFoundException {
125: this .name = name;
126: this .factory = factory;
127: this .profileManager = factory.getProfileManager();
128: loadFromDb();
129: }
130:
131: //FROM THE USER INTERFACE//
132:
133: public int getID() {
134: return id;
135: }
136:
137: public String getName() {
138: return name;
139: }
140:
141: public void setName(String name) throws UnauthorizedException {
142: this .name = name;
143: saveToDb();
144: }
145:
146: public String getDescription() {
147: return description;
148: }
149:
150: public void setDescription(String description)
151: throws UnauthorizedException {
152: this .description = description;
153: saveToDb();
154: }
155:
156: public void addAdministrator(User user)
157: throws UnauthorizedException {
158: Connection con = null;
159: PreparedStatement pstmt = null;
160: try {
161: con = DbConnectionManager.getConnection();
162: pstmt = con.prepareStatement(ADD_ADMIN);
163: pstmt.setInt(1, id);
164: pstmt.setInt(2, user.getID());
165: pstmt.execute();
166: } catch (SQLException sqle) {
167: log.error("", sqle);
168: } finally {
169: try {
170: pstmt.close();
171: } catch (Exception e) {
172: log.error("", e);
173: }
174: try {
175: con.close();
176: } catch (Exception e) {
177: log.error("", e);
178: }
179: }
180:
181: //Now, remove the user from the USER_PERM_CACHE since being in the
182: //group could affect their permissions.
183: DbCacheManager cacheManager = factory.getCacheManager();
184: cacheManager.removeUserPerm(new Integer(user.getID()));
185: }
186:
187: public void removeAdministrator(User user)
188: throws UnauthorizedException {
189: Connection con = null;
190: PreparedStatement pstmt = null;
191: try {
192: con = DbConnectionManager.getConnection();
193: pstmt = con.prepareStatement(REMOVE_ADMIN);
194: pstmt.setInt(1, id);
195: pstmt.setInt(2, user.getID());
196: pstmt.execute();
197: } catch (SQLException sqle) {
198: log.error("", sqle);
199: } finally {
200: try {
201: pstmt.close();
202: } catch (Exception e) {
203: log.error("", e);
204: }
205: try {
206: con.close();
207: } catch (Exception e) {
208: log.error("", e);
209: }
210: }
211:
212: //Now, remove the user from the USER_PERM_CACHE since being in the
213: //group could affect their permissions.
214: DbCacheManager cacheManager = factory.getCacheManager();
215: cacheManager.removeUserPerm(new Integer(user.getID()));
216: }
217:
218: public void addMember(User user) throws UnauthorizedException {
219: Connection con = null;
220: PreparedStatement pstmt = null;
221: try {
222: con = DbConnectionManager.getConnection();
223: pstmt = con.prepareStatement(ADD_USER);
224: pstmt.setInt(1, id);
225: pstmt.setInt(2, user.getID());
226: pstmt.execute();
227: } catch (SQLException sqle) {
228: log.error("", sqle);
229: } finally {
230: try {
231: pstmt.close();
232: } catch (Exception e) {
233: log.error("", e);
234: }
235: try {
236: con.close();
237: } catch (Exception e) {
238: log.error("", e);
239: }
240: }
241:
242: //Now, remove the user from the USER_PERM_CACHE since being in the
243: //group could affect their permissions.
244: DbCacheManager cacheManager = factory.getCacheManager();
245: cacheManager.removeUserPerm(new Integer(user.getID()));
246: }
247:
248: public void removeMember(User user) throws UnauthorizedException {
249: Connection con = null;
250: PreparedStatement pstmt = null;
251: try {
252: con = DbConnectionManager.getConnection();
253: pstmt = con.prepareStatement(REMOVE_USER);
254: pstmt.setInt(1, id);
255: pstmt.setInt(2, user.getID());
256: pstmt.execute();
257: } catch (SQLException sqle) {
258: log.error("", sqle);
259: } finally {
260: try {
261: pstmt.close();
262: } catch (Exception e) {
263: log.error("", e);
264: }
265: try {
266: con.close();
267: } catch (Exception e) {
268: log.error("", e);
269: }
270: }
271:
272: //Now, remove the user from the USER_PERM_CACHE since being in the
273: //group could affect their permissions.
274: DbCacheManager cacheManager = factory.getCacheManager();
275: cacheManager.removeUserPerm(new Integer(user.getID()));
276: }
277:
278: public boolean isAdministrator(User user) {
279: boolean answer = false;
280: Connection con = null;
281: PreparedStatement pstmt = null;
282: try {
283: con = DbConnectionManager.getConnection();
284: pstmt = con.prepareStatement(ADMIN_TEST);
285: pstmt.setInt(1, id);
286: pstmt.setInt(2, user.getID());
287: ResultSet rs = pstmt.executeQuery();
288: if (rs.next()) {
289: answer = true;
290: }
291: } catch (SQLException sqle) {
292: log.error("", sqle);
293: } finally {
294: try {
295: pstmt.close();
296: } catch (Exception e) {
297: log.error("", e);
298: }
299: try {
300: con.close();
301: } catch (Exception e) {
302: log.error("", e);
303: }
304: }
305: return answer;
306: }
307:
308: public boolean isMember(User user) {
309: boolean answer = false;
310: Connection con = null;
311: PreparedStatement pstmt = null;
312: try {
313: con = DbConnectionManager.getConnection();
314: pstmt = con.prepareStatement(MEMBER_TEST);
315: pstmt.setInt(1, id);
316: pstmt.setInt(2, user.getID());
317: ResultSet rs = pstmt.executeQuery();
318: if (rs.next()) {
319: answer = true;
320: }
321: } catch (SQLException sqle) {
322: log.error("", sqle);
323: } finally {
324: try {
325: pstmt.close();
326: } catch (Exception e) {
327: log.error("", e);
328: }
329: try {
330: con.close();
331: } catch (Exception e) {
332: log.error("", e);
333: }
334: }
335: return answer;
336: }
337:
338: public int getAdministratorCount() {
339: int count = 0;
340: boolean answer = false;
341: Connection con = null;
342: PreparedStatement pstmt = null;
343: try {
344: con = DbConnectionManager.getConnection();
345: pstmt = con.prepareStatement(ADMIN_COUNT);
346: pstmt.setInt(1, id);
347: ResultSet rs = pstmt.executeQuery();
348: if (rs.next()) {
349: count = rs.getInt(1);
350: }
351: } catch (SQLException sqle) {
352: log.error("", sqle);
353: } finally {
354: try {
355: pstmt.close();
356: } catch (Exception e) {
357: log.error("", e);
358: }
359: try {
360: con.close();
361: } catch (Exception e) {
362: log.error("", e);
363: }
364: }
365: return count;
366: }
367:
368: public int getMemberCount() {
369: int count = 0;
370: boolean answer = false;
371: Connection con = null;
372: PreparedStatement pstmt = null;
373: try {
374: con = DbConnectionManager.getConnection();
375: pstmt = con.prepareStatement(MEMBER_COUNT);
376: pstmt.setInt(1, id);
377: ResultSet rs = pstmt.executeQuery();
378: if (rs.next()) {
379: count = rs.getInt(1);
380: }
381: } catch (SQLException sqle) {
382: log.error("", sqle);
383: } finally {
384: try {
385: pstmt.close();
386: } catch (Exception e) {
387: log.error("", e);
388: }
389: try {
390: con.close();
391: } catch (Exception e) {
392: log.error("", e);
393: }
394: }
395: return count;
396: }
397:
398: public Iterator members() {
399: ArrayList admins = new ArrayList();
400: //Load list of group admins from db.
401: Connection con = null;
402: PreparedStatement pstmt = null;
403:
404: try {
405: con = DbConnectionManager.getConnection();
406: pstmt = con.prepareStatement(LOAD_USERS);
407: pstmt.setInt(1, id);
408: ResultSet rs = pstmt.executeQuery();
409: User user = null;
410: while (rs.next()) {
411: try {
412: user = profileManager.getUser(rs.getInt("userID"));
413: } catch (UserNotFoundException unfe) {
414: log.error("", unfe);
415: }
416: admins.add(user);
417: }
418: } catch (SQLException sqle) {
419: log.error("SQLException in DbGroup.java:"
420: + "users():reading group data ", sqle);
421:
422: } finally {
423: try {
424: pstmt.close();
425: } catch (Exception e) {
426: log.error("", e);
427: }
428: try {
429: con.close();
430: } catch (Exception e) {
431: log.error("", e);
432: }
433: }
434: return admins.iterator();
435: }
436:
437: public Iterator administrators() {
438: ArrayList admins = new ArrayList();
439: //Load list of group admins from db.
440: Connection con = null;
441: PreparedStatement pstmt = null;
442:
443: try {
444: con = DbConnectionManager.getConnection();
445: pstmt = con.prepareStatement(LOAD_ADMINS);
446: pstmt.setInt(1, id);
447: ResultSet rs = pstmt.executeQuery();
448: User user = null;
449: while (rs.next()) {
450: try {
451: user = profileManager.getUser(rs.getInt("userID"));
452: } catch (UserNotFoundException unfe) {
453: log.error("", unfe);
454: }
455: admins.add(user);
456: }
457: } catch (SQLException sqle) {
458: log.error("SQLException in DbGroup.java:"
459: + "administrators():reading group data ", sqle);
460:
461: } finally {
462: try {
463: pstmt.close();
464: } catch (Exception e) {
465: log.error("", e);
466: }
467: try {
468: con.close();
469: } catch (Exception e) {
470: log.error("", e);
471: }
472: }
473: return admins.iterator();
474: }
475:
476: public ForumPermissions getPermissions(Authorization authorization) {
477: int userID = authorization.getUserID();
478: try {
479: User user = profileManager.getUser(userID);
480: if (isAdministrator(user)) {
481: return new ForumPermissions(false, false, false, false,
482: true, false, false, false);
483: }
484: } catch (Exception e) {
485: }
486:
487: return ForumPermissions.none();
488: }
489:
490: public boolean hasPermission(int type) {
491: return true;
492: }
493:
494: //FROM THE CACHEABLE INTERFACE//
495:
496: public int getSize() {
497: //Approximate the size of the object in bytes by calculating the size
498: //of each field.
499: int size = 0;
500: size += CacheSizes.sizeOfObject(); //overhead of object
501: size += CacheSizes.sizeOfInt(); //id
502: size += CacheSizes.sizeOfString(name); //name
503: size += CacheSizes.sizeOfString(description); //description
504: size += CacheSizes.sizeOfObject(); //profile manager ref.
505: size += CacheSizes.sizeOfObject(); //forum factory ref.
506:
507: return size;
508: }
509:
510: //OTHER METHODS
511:
512: /**
513: * Returns a String representation of the Group object using the group name.
514: *
515: * @return a String representation of the Group object.
516: */
517: public String toString() {
518: return name;
519: }
520:
521: public int hashCode() {
522: return id;
523: }
524:
525: public boolean equals(Object object) {
526: if (this == object) {
527: return true;
528: }
529: if (object != null && object instanceof DbGroup) {
530: return id == ((DbGroup) object).getID();
531: } else {
532: return false;
533: }
534: }
535:
536: /**
537: * Load the group data from the database.
538: */
539: private synchronized void loadFromDb()
540: throws GroupNotFoundException {
541: String query;
542: if (name == null) {
543: query = LOAD_GROUP_BY_ID;
544: } else {
545: query = LOAD_GROUP_BY_NAME;
546: }
547: Connection con = null;
548: PreparedStatement pstmt = null;
549: try {
550: con = DbConnectionManager.getConnection();
551: pstmt = con.prepareStatement(query);
552: if (name == null) {
553: pstmt.setInt(1, id);
554: } else {
555: pstmt.setString(1, name);
556: }
557: ResultSet rs = pstmt.executeQuery();
558: if (!rs.next()) {
559: throw new GroupNotFoundException();
560: }
561: this .id = rs.getInt("groupID");
562: this .name = rs.getString("name");
563: this .description = rs.getString("description");
564: } catch (SQLException sqle) {
565: log.error("SQLException in DbGroup.java:"
566: + "loadFromDb():reading group data ", sqle);
567: throw new GroupNotFoundException();
568: } finally {
569: try {
570: pstmt.close();
571: } catch (Exception e) {
572: log.error("", e);
573: }
574: try {
575: con.close();
576: } catch (Exception e) {
577: log.error("", e);
578: }
579: }
580: }
581:
582: /**
583: * Inserts a new record into the database.
584: */
585: private void insertIntoDb() {
586: StringBuffer insert = new StringBuffer();
587: Connection con = null;
588: PreparedStatement pstmt = null;
589: try {
590: con = DbConnectionManager.getConnection();
591: pstmt = con.prepareStatement(INSERT_GROUP);
592: pstmt.setString(1, name);
593: pstmt.setString(2, description);
594: pstmt.setInt(3, id);
595: pstmt.executeUpdate();
596: } catch (SQLException sqle) {
597: log.error("Error in DbGroup:insertIntoDb()-", sqle);
598:
599: } finally {
600: try {
601: pstmt.close();
602: } catch (Exception e) {
603: log.error("", e);
604: }
605: try {
606: con.close();
607: } catch (Exception e) {
608: log.error("", e);
609: }
610: }
611: }
612:
613: /**
614: * Saves group data to the db.
615: */
616: private synchronized void saveToDb() {
617: Connection con = null;
618: PreparedStatement pstmt = null;
619: try {
620: con = DbConnectionManager.getConnection();
621: pstmt = con.prepareStatement(SAVE_GROUP);
622: pstmt.setString(1, name);
623: pstmt.setString(2, description);
624: pstmt.setInt(3, id);
625: pstmt.executeUpdate();
626: } catch (SQLException sqle) {
627: log
628: .error("SQLException in DbGroup.java:saveToDb(): ",
629: sqle);
630:
631: } finally {
632: try {
633: pstmt.close();
634: } catch (Exception e) {
635: log.error("", e);
636: }
637: try {
638: con.close();
639: } catch (Exception e) {
640: log.error("", e);
641: }
642: }
643: }
644: }
|