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 com.Yasna.forum.*;
108: import com.Yasna.forum.locale.YazdLocale;
109: import com.Yasna.util.*;
110:
111: import java.util.*;
112: import java.text.*;
113: import java.sql.*;
114: import java.security.*;
115:
116: /**
117: * Database implementation of the User interface. Additionally, it filters all
118: * HTML tags from fields before returning them for security purposes.<p>
119: *
120: * Use of the Yazd user system is optional. There a number of different ways
121: * to create your own user system or to integrate into an existing user
122: * system:<ul>
123: * <li> Edit the source of this class and modify the database queries to match
124: * your user system.
125: * <li> Implement a set of custom classes and tell the ForumFactory to load
126: * them. In this case, it is still recommended to use the Yazd user API
127: * since that will mean much less reimplementation work in the other
128: * classes.</ul>
129: *
130: * If you can follow the Yazd API for your own user data, but need access
131: * within Yazd to extended user properties, such as addresses or other
132: * personal data, and easy solution is to adapt the user properties facility
133: * to load and access this data.
134: */
135: public class DbUser implements User, Cacheable {
136:
137: /** DATABASE QUERIES **/
138: private static final String LOAD_PROPERTIES = "SELECT name, propValue FROM yazdUserProp WHERE userID=?";
139: private static final String LOAD_LASTPOST = "select max(creationDate) as lastpost from yazdMessage where userID=?";
140: private static final String DELETE_PROPERTIES = "DELETE FROM yazdUserProp WHERE userID=?";
141: private static final String INSERT_PROPERTY = "INSERT INTO yazdUserProp(userID,name,propValue) VALUES(?,?,?)";
142: private static final String LOAD_USER_BY_USERNAME = "SELECT * FROM "
143: + SystemProperty.getProperty("User.Table")
144: + " WHERE "
145: + SystemProperty.getProperty("User.Column.Username") + "=?";
146: private static final String LOAD_USER_BY_ID = "SELECT * FROM "
147: + SystemProperty.getProperty("User.Table") + " WHERE "
148: + SystemProperty.getProperty("User.Column.UserID") + "=?";
149: private static final String INSERT_USER = "INSERT INTO "
150: + SystemProperty.getProperty("User.Table") + "("
151: + SystemProperty.getProperty("User.Column.UserID") + ","
152: + SystemProperty.getProperty("User.Column.Username") + ","
153: + SystemProperty.getProperty("User.Column.PasswordHash")
154: + ",email)" + "VALUES(?,?,?,?)";
155: private static final String SAVE_USER = "UPDATE "
156: + SystemProperty.getProperty("User.Table") + " SET "
157: + SystemProperty.getProperty("User.Column.PasswordHash")
158: + "=?, " + SystemProperty.getProperty("User.Column.Email")
159: + "=?, " + SystemProperty.getProperty("User.Column.Name")
160: + "=? " + " WHERE "
161: + SystemProperty.getProperty("User.Column.UserID") + "=?";
162: private static final String DELETE_PERMISSIONS = "DELETE FROM yazdUserPerm WHERE userID=?";
163: private static final String INSERT_PERMISSION = "INSERT INTO yazdUserPerm(userID,forumID,permission) VALUES(?,?,?)";
164: private static final String INSERT_AUTO_GROUP = "insert into yazdGroupUser(groupID,userID,administrator) select groupID,?,0 from yazdGroup where automember=1";
165:
166: /**
167: * user id of -2 means no user id has been set yet. -1 is reserved for
168: * "anonymous user" and 0 is reserved for "all users".
169: */
170: private int id = -2;
171: private String username;
172: private String passwordHash;
173: private String name = "";
174: private String email;
175: private boolean nameVisible = true;
176: private boolean emailVisible = true;
177: private boolean threadSubscribe = false;
178: private long lastlogin;
179: private long regdate;
180: private long lastpost = -1;
181: private Properties properties;
182: private Object propertyLock = new Object();
183:
184: /**
185: * Create a new DbUser with all required fields.
186: *
187: * @param username the username for the user.
188: * @param password a password for the user.
189: * @param email the email address for the user.
190: */
191: protected DbUser(String username, String password, String email)
192: throws UserAlreadyExistsException {
193: this .id = DbSequenceManager.nextID("User");
194: this .username = username;
195: //Compute hash of password.
196: this .passwordHash = StringUtils.hash(password);
197: this .email = email;
198: properties = new Properties();
199: insertIntoDb();
200: insertAutoGroupMembership();
201: setProperty("namevisible", Boolean.toString(nameVisible));
202: setProperty("emailvisible", Boolean.toString(emailVisible));
203: setProperty("lastlogin", Long.toString(Calendar.getInstance()
204: .getTimeInMillis()));
205: setProperty("regdate", Long.toString(Calendar.getInstance()
206: .getTimeInMillis()));
207: setProperty("ranking", "3");
208: if (!Boolean.valueOf(
209: PropertyManager.getProperty("User.DisableActivation"))
210: .booleanValue()) {
211: String code = StringUtils.randomString(7);
212: setProperty("notactive", code);
213: if (this .email != null && !"".equals(email)) {
214: // ok ready to send mail to user
215: String emailBody = PropertyManager
216: .getProperty("yazdActivate.MailBody")
217: + " \n\r"
218: + PropertyManager.getProperty("yazdUrl")
219: + "activate.jsp?user="
220: + this .id
221: + "&code="
222: + code;
223: MailSender
224: .send(
225: PropertyManager
226: .getProperty("yazdMailSMTPServer"),
227: PropertyManager
228: .getProperty("yazdMailFrom"),
229: this .email,
230: PropertyManager
231: .getProperty("yazdActivate.MailSubject"),
232: emailBody);
233: }
234: }
235:
236: }
237:
238: /**
239: * Load a DbUser object specified by userID.
240: *
241: * @param userID the userID of the user to load.
242: */
243: protected DbUser(int userID) throws UserNotFoundException {
244: this .id = userID;
245: loadFromDb();
246: loadProperties();
247: loadLastPost();
248: //This is done to be backward compatible with Yazd 1.0
249: nameVisible = Boolean.valueOf(getProperty("namevisible"))
250: .booleanValue();
251: emailVisible = Boolean.valueOf(getProperty("emailvisible"))
252: .booleanValue();
253: threadSubscribe = Boolean.valueOf(
254: getProperty("threadSubscribe")).booleanValue();
255: try {
256: lastlogin = Long.parseLong(getProperty("lastlogin"));
257: } catch (Exception e) {
258: lastlogin = 0;
259: }
260: try {
261: regdate = Long.parseLong(getProperty("regdate"));
262: } catch (Exception e) {
263: regdate = 0;
264: }
265: if (getProperty("ranking") == null) {
266: setProperty("ranking", "3");
267: }
268: }
269:
270: /**
271: * Load a DbUser object specified by username.
272: *
273: * @param username the username of the user to load.
274: */
275: protected DbUser(String username) throws UserNotFoundException {
276: this .username = username;
277: loadFromDb();
278: loadProperties();
279: loadLastPost();
280: //This is done to be backward compatible with Yazd 1.0
281: nameVisible = Boolean.valueOf(getProperty("namevisible"))
282: .booleanValue();
283: emailVisible = Boolean.valueOf(getProperty("emailvisible"))
284: .booleanValue();
285: threadSubscribe = Boolean.valueOf(
286: getProperty("threadSubscribe")).booleanValue();
287: try {
288: lastlogin = Long.parseLong(getProperty("lastlogin"));
289: } catch (Exception e) {
290: lastlogin = 0;
291: }
292: try {
293: regdate = Long.parseLong(getProperty("regdate"));
294: } catch (Exception e) {
295: regdate = 0;
296: }
297: if (getProperty("ranking") == null) {
298: setProperty("ranking", "3");
299: }
300:
301: }
302:
303: //FROM THE USER INTERFACE//
304: protected void activateUser() {
305: properties.remove("notactive");
306: saveProperties();
307: }
308:
309: public int getID() {
310: return id;
311: }
312:
313: public boolean isAnonymous() {
314: return (id == -1);
315: }
316:
317: public String getUsername() {
318: return StringUtils.escapeHTMLTags(username);
319: }
320:
321: public String getName() {
322: return StringUtils.escapeHTMLTags(name);
323: }
324:
325: public void setName(String name) throws UnauthorizedException {
326: this .name = name;
327: saveToDb();
328: }
329:
330: public boolean isNameVisible() {
331: return nameVisible;
332: }
333:
334: public void setNameVisible(boolean visible)
335: throws UnauthorizedException {
336: this .nameVisible = visible;
337: saveToDb();
338: }
339:
340: public boolean getThreadSubscribe() {
341: return threadSubscribe;
342: }
343:
344: public Calendar getLastLogin() {
345: Calendar cal = Calendar.getInstance();
346: cal.setTimeInMillis(lastlogin);
347: return cal;
348: }
349:
350: public Calendar getLastPost() {
351: // This date might be cached and therefore incorrect.
352: if (lastpost < 0) {
353: // this means that the user hasn't posted a message yet and we are returning a null value.
354: return null;
355: } else {
356: Calendar cal = Calendar.getInstance();
357: cal.setTimeInMillis(lastpost);
358: return cal;
359: }
360: }
361:
362: public Locale getUserLocale() {
363: String locale = this .getProperty("locale");
364: if (locale == null) {
365: //if there is no user locale then return the default locale
366: return YazdLocale.getDefaultYazdLocale();
367: }
368: String lang = null, country = null, variant = null;
369: int pos = 0;
370: int delPos = 0;
371: if ((delPos = locale.indexOf(",", pos)) != -1) {
372: lang = locale.substring(pos, delPos);
373: pos = delPos + 1; // next character after the delimiter
374: } else if (pos <= locale.length()) {
375: lang = locale.substring(pos);
376: pos = locale.length() + 1;
377: }
378: if ((delPos = locale.indexOf(",", pos)) != -1) {
379: country = locale.substring(pos, delPos);
380: pos = delPos + 1; // next character after the delimiter
381: } else if (pos <= locale.length()) {
382: country = locale.substring(pos);
383: pos = locale.length() + 1;
384: }
385: if (pos <= locale.length()) {
386: // add rest of String
387: variant = locale.substring(pos);
388:
389: }
390: if (variant != null) {
391: return new Locale(lang, country, variant);
392: } else if (country != null) {
393: //this is the one that should return most values.
394: return new Locale(lang, country);
395: } else {
396: return new Locale(lang);
397: }
398:
399: }
400:
401: public TimeZone getUserTimeZone() {
402: String timezone = this .getProperty("timezone");
403: if (timezone == null) {
404: //if there is no user locale then return the default locale
405: return TimeZone.getDefault();
406: }
407: return TimeZone.getTimeZone(timezone);
408: }
409:
410: public void setUserTimeZone(String timezoneid)
411: throws UnauthorizedException {
412: this .setProperty("timezone", timezoneid);
413: }
414:
415: public void setUserLocale(Locale locale)
416: throws UnauthorizedException {
417: this .setProperty("Locale", locale.getLanguage()
418: + ("".equals(locale.getCountry()) ? "" : ","
419: + locale.getCountry())
420: + ("".equals(locale.getVariant()) ? "" : ","
421: + locale.getVariant()));
422: }
423:
424: public void setThreadSubscribe(boolean emailReply)
425: throws UnauthorizedException {
426: this .threadSubscribe = emailReply;
427: setProperty("threadSubscribe", Boolean.toString(emailReply));
428: }
429:
430: public void setPassword(String password)
431: throws UnauthorizedException {
432: //Compute hash of password.
433: this .passwordHash = StringUtils.hash(password);
434: saveToDb();
435: }
436:
437: public String getPasswordHash() throws UnauthorizedException {
438: return passwordHash;
439: }
440:
441: public void setPasswordHash(String passwordHash) {
442: this .passwordHash = passwordHash;
443: saveToDb();
444: }
445:
446: public String getEmail() {
447: return StringUtils.escapeHTMLTags(email);
448: }
449:
450: public void setEmail(String email) throws UnauthorizedException {
451: this .email = email;
452: saveToDb();
453: }
454:
455: public boolean isEmailVisible() {
456: return emailVisible;
457: }
458:
459: public void setEmailVisible(boolean visible)
460: throws UnauthorizedException {
461: this .emailVisible = visible;
462: setProperty("emailvisible", Boolean.toString(visible));
463: }
464:
465: public String getProperty(String name) {
466: return StringUtils
467: .escapeHTMLTags((String) properties.get(name));
468: }
469:
470: public Enumeration propertyNames() {
471: return properties.propertyNames();
472: }
473:
474: public void setProperty(String name, String value) {
475: properties.put(name, value);
476: saveProperties();
477: }
478:
479: public ForumPermissions getPermissions(Authorization authorization) {
480: if (authorization.getUserID() == id || id == -1 || id == 0) {
481: return new ForumPermissions(false, false, false, true,
482: false, false, false, false);
483: } else {
484: return ForumPermissions.none();
485: }
486: }
487:
488: public boolean hasPermission(int type) {
489: return true;
490: }
491:
492: //FROM THE CACHEABLE INTERFACE//
493:
494: public int getSize() {
495: //Approximate the size of the object in bytes by calculating the size
496: //of each field.
497: int size = 0;
498: size += CacheSizes.sizeOfObject(); //overhead of object
499: size += CacheSizes.sizeOfInt(); //id
500: size += CacheSizes.sizeOfString(username); //username
501: size += CacheSizes.sizeOfString(passwordHash); //password
502: size += CacheSizes.sizeOfString(name); //name
503: size += CacheSizes.sizeOfString(email); //email
504: size += CacheSizes.sizeOfBoolean(); //nameVisible
505: size += CacheSizes.sizeOfBoolean(); //emailVisible
506: size += CacheSizes.sizeOfObject(); //property lock
507: size += CacheSizes.sizeOfProperties(properties);//properties object
508: size += CacheSizes.sizeOfLong(); //last login
509: size += CacheSizes.sizeOfLong(); //last post
510:
511: return size;
512: }
513:
514: //OTHER METHODS
515:
516: /**
517: * Returns a String representation of the User object using the username.
518: *
519: * @return a String representation of the User object.
520: */
521: public String toString() {
522: return username;
523: }
524:
525: public int hashCode() {
526: return id;
527: }
528:
529: public boolean equals(Object object) {
530: if (this == object) {
531: return true;
532: }
533: if (object != null && object instanceof DbUser) {
534: return id == ((DbUser) object).getID();
535: } else {
536: return false;
537: }
538: }
539:
540: /**
541: * Loads user properties from the database.
542: */
543: private void loadProperties() {
544: //If "anonymous" or "all users", do nothing.
545: if (id == -1 || id == 0) {
546: properties = new Properties();
547: return;
548: }
549: //Acquire a lock so that no other property loading or saving can be
550: //performed at the same time.
551: synchronized (propertyLock) {
552: Properties newProps = new Properties();
553: Connection con = null;
554: PreparedStatement pstmt = null;
555: try {
556: con = DbConnectionManager.getConnection();
557: pstmt = con.prepareStatement(LOAD_PROPERTIES);
558: pstmt.setInt(1, id);
559: ResultSet rs = pstmt.executeQuery();
560: while (rs.next()) {
561: String name = rs.getString("name");
562: String value = rs.getString("propValue");
563: newProps.put(name, value);
564: }
565: } catch (SQLException sqle) {
566: System.err.println("Error in DbUser:loadProperties():"
567: + sqle);
568: sqle.printStackTrace();
569: } finally {
570: try {
571: pstmt.close();
572: } catch (Exception e) {
573: e.printStackTrace();
574: }
575: try {
576: con.close();
577: } catch (Exception e) {
578: e.printStackTrace();
579: }
580: }
581: this .properties = newProps;
582: }
583: }
584:
585: /**
586: * Loads user properties from the database.
587: */
588: private void loadLastPost() {
589: if (id == -1 || id == 0) {
590: return;
591: }
592: Connection con = null;
593: PreparedStatement pstmt = null;
594: try {
595: con = DbConnectionManager.getConnection();
596: pstmt = con.prepareStatement(LOAD_LASTPOST);
597: pstmt.setInt(1, id);
598: ResultSet rs = pstmt.executeQuery();
599: if (rs.next()) {
600: lastpost = Long.parseLong(rs.getString("lastpost"));
601: }
602: } catch (SQLException sqle) {
603: System.err.println("Error in DbUser:loadProperties():"
604: + sqle);
605: sqle.printStackTrace();
606: } catch (NumberFormatException e) {
607: lastpost = -1;
608: } finally {
609: try {
610: pstmt.close();
611: } catch (Exception e) {
612: e.printStackTrace();
613: }
614: try {
615: con.close();
616: } catch (Exception e) {
617: e.printStackTrace();
618: }
619: }
620:
621: }
622:
623: /**
624: * Saves user properties to the database.
625: */
626: private void saveProperties() {
627: //If "anonymous" or "all users", do nothing.
628: if (id == -1 || id == 0) {
629: return;
630: }
631: //Acquire a lock so that no other property loading or saving can be
632: //performed at the same time.
633: synchronized (propertyLock) {
634: Connection con = null;
635: PreparedStatement pstmt = null;
636: try {
637: con = DbConnectionManager.getConnection();
638: //Delete all old values.
639: pstmt = con.prepareStatement(DELETE_PROPERTIES);
640: pstmt.setInt(1, id);
641: pstmt.execute();
642: pstmt.close();
643: //Now insert new values.
644: pstmt = con.prepareStatement(INSERT_PROPERTY);
645: Enumeration enume = properties.keys();
646: while (enume.hasMoreElements()) {
647: String name = (String) enume.nextElement();
648: String value = (String) properties.get(name);
649: pstmt.setInt(1, id);
650: pstmt.setString(2, name);
651: pstmt.setString(3, value);
652: pstmt.executeUpdate();
653: }
654: } catch (SQLException sqle) {
655: System.err.println(sqle);
656: } finally {
657: try {
658: pstmt.close();
659: } catch (Exception e) {
660: e.printStackTrace();
661: }
662: try {
663: con.close();
664: } catch (Exception e) {
665: e.printStackTrace();
666: }
667: }
668: }
669: }
670:
671: /**
672: * Load the user data from the database.
673: */
674: private void loadFromDb() throws UserNotFoundException {
675: //If the user is anonymous or "all users", do nothing.
676: if (id == -1 || id == 0) {
677: return;
678: }
679: // Otherwise, select user data from User table and fill in relevant fields.
680: String query;
681: //We may want to do a username lookup.
682: if (username != null) {
683: query = LOAD_USER_BY_USERNAME;
684: }
685: //Otherwise, a lookup by id
686: else {
687: query = LOAD_USER_BY_ID;
688: }
689: Connection con = null;
690: PreparedStatement pstmt = null;
691: try {
692: con = DbConnectionManager.getConnection();
693: pstmt = con.prepareStatement(query);
694: if (username != null) {
695: pstmt.setString(1, username);
696: } else {
697: pstmt.setInt(1, id);
698: }
699:
700: ResultSet rs = pstmt.executeQuery();
701: if (!rs.next()) {
702: throw new UserNotFoundException("Failed to read user "
703: + id + " from database.");
704: }
705: this .id = rs.getInt(SystemProperty
706: .getProperty("User.Column.UserID"));
707: this .username = rs.getString(SystemProperty
708: .getProperty("User.Column.Username"));
709: this .passwordHash = rs.getString(SystemProperty
710: .getProperty("User.Column.PasswordHash"));
711: this .name = rs.getString(SystemProperty
712: .getProperty("User.Column.Name"));
713: this .email = rs.getString(SystemProperty
714: .getProperty("User.Column.Email"));
715: } catch (SQLException sqle) {
716: throw new UserNotFoundException("Failed to read user " + id
717: + " from database.", sqle);
718: } finally {
719: try {
720: pstmt.close();
721: } catch (Exception e) {
722: e.printStackTrace();
723: }
724: try {
725: con.close();
726: } catch (Exception e) {
727: e.printStackTrace();
728: }
729: }
730: }
731:
732: /**
733: * Inserts a new user record into the database.
734: */
735: private void insertIntoDb() throws UserAlreadyExistsException {
736: Connection con = null;
737: PreparedStatement pstmt = null;
738: try {
739: con = DbConnectionManager.getConnection();
740: pstmt = con.prepareStatement(INSERT_USER);
741: pstmt.setInt(1, id);
742: pstmt.setString(2, username);
743: pstmt.setString(3, passwordHash);
744: pstmt.setString(4, email);
745: pstmt.executeUpdate();
746: } catch (SQLException sqle) {
747: System.err
748: .println("Error in DbUser:insertIntoDb()-" + sqle);
749: sqle.printStackTrace();
750: throw new UserAlreadyExistsException();
751: } finally {
752: try {
753: pstmt.close();
754: } catch (Exception e) {
755: e.printStackTrace();
756: }
757: try {
758: con.close();
759: } catch (Exception e) {
760: e.printStackTrace();
761: }
762: }
763: }
764:
765: private void insertAutoGroupMembership() {
766: Connection con = null;
767: PreparedStatement pstmt = null;
768: try {
769: con = DbConnectionManager.getConnection();
770: pstmt = con.prepareStatement(INSERT_AUTO_GROUP);
771: pstmt.setInt(1, id);
772: pstmt.executeUpdate();
773: } catch (SQLException sqle) {
774: System.err
775: .println("Error in DbUser:insertAutoGroupMembership()-"
776: + sqle);
777: sqle.printStackTrace();
778: } finally {
779: try {
780: pstmt.close();
781: } catch (Exception e) {
782: e.printStackTrace();
783: }
784: try {
785: con.close();
786: } catch (Exception e) {
787: e.printStackTrace();
788: }
789: }
790:
791: }
792:
793: /**
794: * Save the user data to the database.
795: */
796: private void saveToDb() {
797: if (id == -1 || id == 0) {
798: //"anonymous" or "all users", do nothing
799: return;
800: }
801: Connection con = null;
802: PreparedStatement pstmt = null;
803: try {
804: con = DbConnectionManager.getConnection();
805: pstmt = con.prepareStatement(SAVE_USER);
806: pstmt.setString(1, passwordHash);
807: pstmt.setString(2, email);
808: pstmt.setString(3, name);
809: pstmt.setInt(4, id);
810: pstmt.executeUpdate();
811: } catch (SQLException sqle) {
812: System.err
813: .println("SQLException in DbUser.java:saveToDb(): "
814: + sqle);
815: sqle.printStackTrace();
816: } finally {
817: try {
818: pstmt.close();
819: } catch (Exception e) {
820: e.printStackTrace();
821: }
822: try {
823: con.close();
824: } catch (Exception e) {
825: e.printStackTrace();
826: }
827: }
828: }
829: }
|