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.sql.*;
108: import java.util.*;
109: import java.text.SimpleDateFormat;
110:
111: import com.Yasna.forum.*;
112: import com.Yasna.forum.Exceptions.RapidPostingException;
113: import com.Yasna.forum.Exceptions.UserBlackListedException;
114: import com.Yasna.forum.util.ClientIP;
115: import com.Yasna.util.Cacheable;
116: import com.Yasna.util.CacheSizes;
117: import com.Yasna.util.StringUtils;
118:
119: /**
120: * Database implementation of the ForumMessage interface. It stores messages
121: * in the YazdMessage database table, and message properties in yazdMessageProp
122: * table.
123: */
124: public final class DbForumMessage implements ForumMessage, Cacheable {
125:
126: /** DATABASE QUERIES **/
127: private static final String CHECK_LASTPOST = "select max(a.creationDate) as lastpost from yazdMessage a,yazdMessageProp b where a.messageID=b.messageID and b.name=? and b.propValue=?";
128: private static final String CHECK_LASTPOSTWITHUSER = "select max(creationDate) as lastpost from yazdMessage where userID=?";
129: private static final String LOAD_PROPERTIES = "SELECT name, propValue FROM yazdMessageProp WHERE messageID=?";
130: private static final String DELETE_PROPERTIES = "DELETE FROM yazdMessageProp WHERE messageID=?";
131: private static final String INSERT_PROPERTY = "INSERT INTO yazdMessageProp(messageID,name,propValue) VALUES(?,?,?)";
132: private static final String LOAD_MESSAGE = "SELECT userID, creationDate, modifiedDate, subject, body, threadID, "
133: + "replyPrivateUserId, approved,ranking FROM yazdMessage WHERE messageID=?";
134: private static final String INSERT_MESSAGE = "INSERT INTO yazdMessage(messageID, threadID,creationDate,modifiedDate,userID,"
135: + "subject,body,approved, replyPrivateUserId,ranking) VALUES(?,?,?,?,?,?,?,?,?,0)";
136: private static final String SAVE_MESSAGE = "UPDATE yazdMessage SET userID=?, subject=?, body=?, creationDate=?, "
137: + "modifiedDate=?, replyPrivateUserId = ?, approved = ?,ranking=? WHERE messageID=?";
138: private static final String GET_FORUM_BY_THREAD = "SELECT forumID FROM yazdThread where threadID=?";
139: private static final String CHECK_BLACK_LIST_IP = "select ip from yazdBlackList where ip=?";
140: private static final String UPDATE_BLACK_LIST_IP = "update yazdBlackList set blockcount=blockcount+1 where ip=?";
141: private static final String CHECK_BLACK_LIST_USER = "select userID from yazdUserProp where userID=? and name=? and propValue=?";
142: private static final String CHECK_SESSION = "select initime from yazdSessions where IP=?";
143:
144: private int id = -1;
145: private java.util.Date creationDate;
146: private java.util.Date modifiedDate;
147: private String subject = "";
148: private int replyPrivateUserId = 0;
149: private boolean approved;
150: private String body = "";
151: private int userID;
152: private int threadID;
153: private Map properties;
154: private Object propertyLock = new Object();
155: private DbForumFactory factory;
156: private ForumThread thread = null;
157: private int ranking = MessageRanking.NOTRANKED; // default to neutral
158:
159: /**
160: * Indicates if the object is ready to be saved or not. An object is not
161: * ready to be saved if it has just been created and has not yet been added
162: * to its container. For example, a message added to a thread, etc.
163: */
164: private boolean isReadyToSave = false;
165:
166: /**
167: * Creates a new dummy DbForumMessage object.
168: * this is used to obtain the filtered message
169: */
170: protected DbForumMessage(User user, DbForumFactory factory) {
171: this .id = -1;
172: long now = System.currentTimeMillis();
173: creationDate = new java.util.Date(now);
174: modifiedDate = new java.util.Date(now);
175: this .userID = user.getID();
176: this .factory = factory;
177: this .approved = true;
178: properties = Collections.synchronizedMap(new HashMap());
179: isReadyToSave = false;
180: }
181:
182: /**
183: * Creates a new DbForumMessage object.
184: */
185: protected DbForumMessage(User user, DbForumFactory factory,
186: boolean approved, ClientIP clientIP)
187: throws RapidPostingException, UserBlackListedException {
188: checkBlackList(user, clientIP);
189: checkForRapidPosts(user, clientIP);
190: checkForSession(user, clientIP);
191: this .id = DbSequenceManager.nextID("ForumMessage");
192: long now = System.currentTimeMillis();
193: creationDate = new java.util.Date(now);
194: modifiedDate = new java.util.Date(now);
195: this .userID = user.getID();
196: this .factory = factory;
197: this .approved = approved;
198: properties = Collections.synchronizedMap(new HashMap());
199: }
200:
201: /**
202: * Loads the specified DbForumMessage by its message id.
203: */
204: protected DbForumMessage(int id, DbForumFactory factory)
205: throws ForumMessageNotFoundException {
206: this .id = id;
207: this .factory = factory;
208: loadFromDb();
209: loadProperties();
210: isReadyToSave = true;
211: }
212:
213: //FROM THE FORUMMESSAGE INTERFACE//
214:
215: public int getID() {
216: return id;
217: }
218:
219: public java.util.Date getCreationDate() {
220: return creationDate;
221: }
222:
223: public void setCreationDate(java.util.Date creationDate)
224: throws UnauthorizedException {
225: this .creationDate = creationDate;
226: //Only save to the db if the object is read
227: if (!isReadyToSave) {
228: return;
229: }
230: saveToDb();
231: }
232:
233: public java.util.Date getModifiedDate() {
234: return modifiedDate;
235: }
236:
237: public void setModifiedDate(java.util.Date modifiedDate)
238: throws UnauthorizedException {
239: this .modifiedDate = modifiedDate;
240: //Only save to the db if the object is read
241: if (!isReadyToSave) {
242: return;
243: }
244: saveToDb();
245: }
246:
247: public String getSubject() {
248: return subject;
249: }
250:
251: public int getReplyPrivateUserId() {
252: return replyPrivateUserId;
253: }
254:
255: public boolean isPrivate() {
256: return replyPrivateUserId > 0;
257: }
258:
259: public String getUnfilteredSubject() {
260: return subject;
261: }
262:
263: public void setSubject(String subject) throws UnauthorizedException {
264: this .subject = subject;
265: //Only save to the db if the object is read
266: if (!isReadyToSave) {
267: return;
268: }
269: //Update modifiedDate to the current time.
270: modifiedDate.setTime(System.currentTimeMillis());
271: saveToDb();
272: }
273:
274: public void setReplyPrivateUserId(int replyPrivateUserId)
275: throws UnauthorizedException {
276: this .replyPrivateUserId = replyPrivateUserId;
277: //Only save to the db if the object is read
278: if (!isReadyToSave) {
279: return;
280: }
281: //Update modifiedDate to the current time.
282: modifiedDate.setTime(System.currentTimeMillis());
283: saveToDb();
284: }
285:
286: public void setApprovment(boolean approved)
287: throws UnauthorizedException {
288: this .approved = approved;
289: //Only save to the db if the object is read
290: if (!isReadyToSave) {
291: return;
292: }
293: //Update modifiedDate to the current time.
294: modifiedDate.setTime(System.currentTimeMillis());
295: saveToDb();
296: }
297:
298: public boolean isApproved() {
299: return approved;
300: }
301:
302: public String getBody() {
303: return body;
304: }
305:
306: public String getUnfilteredBody() {
307: return body;
308: }
309:
310: public void setBody(String body) throws UnauthorizedException {
311: this .body = body;
312: //Only save to the db if the object is read
313: if (!isReadyToSave) {
314: return;
315: }
316: //Update modifiedDate to the current time.
317: modifiedDate.setTime(System.currentTimeMillis());
318: saveToDb();
319: }
320:
321: public User getUser() {
322: User user = null;
323: try {
324: if (userID == -1) {
325: user = factory.getProfileManager().getAnonymousUser();
326: } else {
327: user = factory.getProfileManager().getUser(userID);
328: }
329: } catch (UserNotFoundException unfe) {
330: unfe.printStackTrace();
331: }
332: return user;
333: }
334:
335: public String getProperty(String name) {
336: //For security reasons, pass through the HTML filter.
337: return StringUtils
338: .escapeHTMLTags((String) properties.get(name));
339: }
340:
341: public String getUnfilteredProperty(String name) {
342: return (String) properties.get(name);
343: }
344:
345: public void setProperty(String name, String value) {
346: properties.put(name, value);
347: //Only save to the db if the object is read
348: if (!isReadyToSave) {
349: return;
350: }
351: saveProperties();
352: }
353:
354: public Iterator propertyNames() {
355: return Collections.unmodifiableSet(properties.keySet())
356: .iterator();
357: }
358:
359: public boolean isAnonymous() {
360: return (userID == -1);
361: }
362:
363: public ForumThread getForumThread() {
364: if (thread != null) {
365: return thread;
366: }
367: //Load the thread since this is the first time the method has been
368: //called.
369: else {
370: //First, we need a handle on the parent Forum object based
371: //on the threadID.
372:
373: int forumID = -1;
374: Connection con = null;
375: PreparedStatement pstmt = null;
376: try {
377: con = DbConnectionManager.getConnection();
378: pstmt = con.prepareStatement(GET_FORUM_BY_THREAD);
379: pstmt.setInt(1, threadID);
380: ResultSet rs = pstmt.executeQuery();
381: if (rs.next()) {
382: forumID = rs.getInt("forumID");
383: }
384: } catch (SQLException sqle) {
385: sqle.printStackTrace();
386: } finally {
387: try {
388: pstmt.close();
389: } catch (Exception e) {
390: e.printStackTrace();
391: }
392: try {
393: con.close();
394: } catch (Exception e) {
395: e.printStackTrace();
396: }
397: }
398: //If the forumID for the message is less than 1, we have problems.
399: //Print a warning and return null
400: if (forumID < 1) {
401: System.err
402: .println("WARNING: forumID of "
403: + forumID
404: + " found for message "
405: + id
406: + " in DbForumMessage.getForumThread()."
407: + " You may wish to delete the message from your database.");
408: return null;
409: }
410:
411: Forum forum = null;
412: ForumThread thread = null;
413: try {
414: forum = factory.getForum(forumID);
415: //Now, get the thread
416: thread = forum.getThread(threadID);
417: } catch (Exception e) {
418: e.printStackTrace();
419: return null;
420: }
421: this .thread = thread;
422: return thread;
423: }
424: }
425:
426: public boolean hasPermission(int type) {
427: return true;
428: }
429:
430: //FROM CACHEABLE INTERFACE//
431:
432: public int getSize() {
433: //Approximate the size of the object in bytes by calculating the size
434: //of each field.
435: int size = 0;
436: size += CacheSizes.sizeOfObject(); //overhead of object
437: size += CacheSizes.sizeOfInt(); //id
438: size += CacheSizes.sizeOfString(subject); //subject
439: size += CacheSizes.sizeOfString(body); //body
440: size += CacheSizes.sizeOfDate(); //creation date
441: size += CacheSizes.sizeOfDate(); //modified date
442: size += CacheSizes.sizeOfInt(); //userID
443: size += CacheSizes.sizeOfInt(); //threadID
444: size += CacheSizes.sizeOfInt(); //replyPrivateUserId
445: size += CacheSizes.sizeOfBoolean(); //approved
446: size += CacheSizes.sizeOfMap(properties); //map object
447: size += CacheSizes.sizeOfObject(); //property lock
448: size += CacheSizes.sizeOfObject(); //ref to factory
449:
450: return size;
451: }
452:
453: //OTHER METHODS//
454:
455: /**
456: * Returns a String representation of the message object using the subject.
457: *
458: * @return a String representation of the ForumMessage object.
459: */
460: public String toString() {
461: return subject;
462: }
463:
464: public int hashCode() {
465: return id;
466: }
467:
468: public boolean equals(Object object) {
469: if (this == object) {
470: return true;
471: }
472: if (object != null && object instanceof DbForumMessage) {
473: return id == ((DbForumMessage) object).getID();
474: } else {
475: return false;
476: }
477: }
478:
479: /**
480: * Loads message properties from the database.
481: */
482: private void loadProperties() {
483: synchronized (propertyLock) {
484: Properties newProps = new Properties();
485: Connection con = null;
486: PreparedStatement pstmt = null;
487: try {
488: con = DbConnectionManager.getConnection();
489: pstmt = con.prepareStatement(LOAD_PROPERTIES);
490: pstmt.setInt(1, id);
491: ResultSet rs = pstmt.executeQuery();
492: while (rs.next()) {
493: String name = rs.getString("name");
494: String value = rs.getString("propValue");
495: newProps.put(name, value);
496: }
497: } catch (SQLException sqle) {
498: System.err
499: .println("Error in DbForumMessage:loadProperties():"
500: + sqle);
501: sqle.printStackTrace();
502: } finally {
503: try {
504: pstmt.close();
505: } catch (Exception e) {
506: e.printStackTrace();
507: }
508: try {
509: con.close();
510: } catch (Exception e) {
511: e.printStackTrace();
512: }
513: }
514: this .properties = newProps;
515: }
516: }
517:
518: /**
519: * Saves message properties to the database.
520: */
521: private void saveProperties() {
522: synchronized (propertyLock) {
523: Connection con = null;
524: PreparedStatement pstmt = null;
525: try {
526: con = DbConnectionManager.getConnection();
527: //Delete all old values.
528: pstmt = con.prepareStatement(DELETE_PROPERTIES);
529: pstmt.setInt(1, id);
530: pstmt.execute();
531: pstmt.close();
532: //Now insert new values.
533: pstmt = con.prepareStatement(INSERT_PROPERTY);
534: Iterator iter = properties.keySet().iterator();
535: while (iter.hasNext()) {
536: String name = (String) iter.next();
537: String value = (String) properties.get(name);
538: pstmt.setInt(1, id);
539: pstmt.setString(2, name);
540: pstmt.setString(3, value);
541: pstmt.executeUpdate();
542: }
543: } catch (SQLException sqle) {
544: System.err.println(sqle);
545: } finally {
546: try {
547: pstmt.close();
548: } catch (Exception e) {
549: e.printStackTrace();
550: }
551: try {
552: con.close();
553: } catch (Exception e) {
554: e.printStackTrace();
555: }
556: }
557: }
558: }
559:
560: /**
561: * Loads message and user data from the database.
562: */
563: private void loadFromDb() throws ForumMessageNotFoundException {
564: // Based on the id in the object, get the message data from the database.
565: Connection con = null;
566: PreparedStatement pstmt = null;
567: try {
568: con = DbConnectionManager.getConnection();
569: pstmt = con.prepareStatement(LOAD_MESSAGE);
570: pstmt.setInt(1, id);
571: ResultSet rs = pstmt.executeQuery();
572: if (!rs.next()) {
573: throw new ForumMessageNotFoundException("Message " + id
574: + " could not be loaded from the database.");
575: }
576: //Get the query results. We use int indexes into the ResultSet
577: //because it is slightly faster. Care should be taken so that the
578: //SQL query is not modified without modifying these indexes.
579: this .userID = rs.getInt(1);
580: //We trim() the dates before trying to parse them because some
581: //databases pad with extra characters when returning the data.
582: this .creationDate = new java.util.Date(Long.parseLong(rs
583: .getString(2).trim()));
584: this .modifiedDate = new java.util.Date(Long.parseLong(rs
585: .getString(3).trim()));
586: this .subject = rs.getString(4);
587: this .body = rs.getString(5);
588: this .threadID = rs.getInt(6);
589: this .replyPrivateUserId = rs.getInt(7);
590: this .approved = rs.getInt(8) == 1 ? true : false;
591: this .ranking = rs.getInt("ranking");
592: } catch (SQLException sqle) {
593: throw new ForumMessageNotFoundException("Message of id "
594: + id + " was not found in the database.");
595: } catch (NumberFormatException nfe) {
596: System.err
597: .println("WARNING: In DbForumMessage.loadFromDb() -- there "
598: + "was an error parsing the dates returned from the database. Ensure "
599: + "that they're being stored correctly.");
600: } finally {
601: try {
602: pstmt.close();
603: } catch (Exception e) {
604: e.printStackTrace();
605: }
606: try {
607: con.close();
608: } catch (Exception e) {
609: e.printStackTrace();
610: }
611: }
612: }
613:
614: /**
615: * Inserts a new message into the database. A connection object must
616: * be passed in. The connection must be open when passed in, and will
617: * remain open when passed back. This method allows us to make insertions
618: * be transactional.
619: *
620: * @param con an open Connection used to insert the thread to the db.
621: * @param thread the ForumThread the message is being added to.
622: */
623: public void insertIntoDb(Connection con, ForumThread thread)
624: throws SQLException {
625: //Set the message threadID to the thread that the message is being
626: //added to.
627: this .threadID = thread.getID();
628: PreparedStatement pstmt = con.prepareStatement(INSERT_MESSAGE);
629: pstmt.setInt(1, id);
630: pstmt.setInt(2, threadID);
631: pstmt.setString(3, Long.toString(creationDate.getTime()));
632: pstmt.setString(4, Long.toString(modifiedDate.getTime()));
633: pstmt.setInt(5, userID);
634: pstmt.setString(6, subject);
635: pstmt.setString(7, body);
636: pstmt.setInt(8, approved ? 1 : 0);
637: pstmt.setInt(9, replyPrivateUserId);
638: pstmt.executeUpdate();
639: pstmt.close();
640:
641: //We're done inserting the message, so now save any extended
642: //properties to the database.
643: saveProperties();
644:
645: //Now add the message to the watch list so that the proper users are notified.
646: factory.getWatchManager().addMessage(this );
647: //since we're done inserting the object to the database, it is ready
648: //for future insertions.
649: isReadyToSave = true;
650: }
651:
652: /**
653: * Saves message data to the database.
654: */
655: private synchronized void saveToDb() {
656: Connection con = null;
657: PreparedStatement pstmt = null;
658: try {
659: con = DbConnectionManager.getConnection();
660: pstmt = con.prepareStatement(SAVE_MESSAGE);
661: pstmt.setInt(1, userID);
662: pstmt.setString(2, subject);
663: pstmt.setString(3, body);
664: pstmt.setString(4, Long.toString(creationDate.getTime()));
665: pstmt.setString(5, Long.toString(modifiedDate.getTime()));
666: pstmt.setInt(6, replyPrivateUserId);
667: pstmt.setInt(7, approved ? 1 : 0);
668: pstmt.setInt(8, this .ranking);
669: pstmt.setInt(9, id);
670: pstmt.executeUpdate();
671: } catch (SQLException sqle) {
672: System.err
673: .println("SQLException in DbForumMessage:saveToDb()- "
674: + sqle);
675: sqle.printStackTrace();
676: } finally {
677: try {
678: pstmt.close();
679: } catch (Exception e) {
680: e.printStackTrace();
681: }
682: try {
683: con.close();
684: } catch (Exception e) {
685: e.printStackTrace();
686: }
687: }
688: }
689:
690: /**
691: * this method checks to see if the user has already posted another message in the restricted window.
692: * @param user
693: * @param clientIP
694: * @throws RapidPostingException
695: */
696: private void checkForRapidPosts(User user, ClientIP clientIP)
697: throws RapidPostingException {
698: // there is minor problem with this method:
699: // A user who is logged in can post a message, then logout and post another message without a problem.
700: // We need to check against the IP addresses of the messages.
701: Connection con = null;
702: PreparedStatement pstmt = null;
703: try {
704: con = DbConnectionManager.getConnection();
705: int ranking = 10; //This would be anonymous ranking
706: if (user.isAnonymous()) {
707: pstmt = con.prepareStatement(CHECK_LASTPOST);
708: pstmt.setString(1, "IP");
709: pstmt.setString(2, clientIP.getRemoteIP());
710: } else {
711: pstmt = con.prepareStatement(CHECK_LASTPOSTWITHUSER);
712: pstmt.setInt(1, user.getID());
713: ranking = Integer.parseInt(user.getProperty("ranking"));
714: }
715: ResultSet rs = pstmt.executeQuery();
716: if (rs.next()) {
717: if (rs.getString("lastpost") != null
718: && !rs.getString("lastpost").toUpperCase()
719: .equals("NULL")
720: && !rs.getString("lastpost").equals("")) {
721: if (Calendar.getInstance().getTimeInMillis()
722: - Long.parseLong(rs.getString("lastpost")) < Long
723: .parseLong(SystemProperty
724: .getProperty("PeriodBetweenPosts"))
725: * ranking) {
726: long timediff = (Calendar.getInstance()
727: .getTimeInMillis() - Long.parseLong(rs
728: .getString("lastpost"))) / 1000;
729: throw new RapidPostingException(
730: "Rapid Posting Error. There was a post already posted at "
731: + Long.toString(timediff)
732: + " seconds ago!");
733: }
734: }
735: }
736: } catch (SQLException sqle) {
737: System.err
738: .println("an error occured in DbForumMessage (0934):"
739: + sqle.getMessage());
740: sqle.printStackTrace();
741: } finally {
742: try {
743: pstmt.close();
744: } catch (Exception e) {
745: e.printStackTrace();
746: }
747: try {
748: con.close();
749: } catch (Exception e) {
750: e.printStackTrace();
751: }
752: }
753: }
754:
755: private void checkForSession(User user, ClientIP clientIP)
756: throws RapidPostingException {
757: Connection con = null;
758: PreparedStatement pstmt = null;
759: try {
760: con = DbConnectionManager.getConnection();
761: pstmt = con.prepareStatement(CHECK_SESSION);
762: pstmt.setString(1, clientIP.getRemoteIP());
763: ResultSet rs = pstmt.executeQuery();
764: if (rs.next()) {
765: if (Calendar.getInstance().getTimeInMillis()
766: - Long.parseLong(rs.getString("initime"))
767: * 1000.0 < Long.parseLong(SystemProperty
768: .getProperty("WaitPeriod"))) {
769: throw new RapidPostingException(
770: "Rapid Posting Error. Wait period is "
771: + SystemProperty
772: .getProperty("WaitPeriod")
773: + "!");
774: }
775: }
776: } catch (SQLException sqle) {
777: System.err
778: .println("an error occured in DbForumMessage (0936):"
779: + sqle.getMessage());
780: sqle.printStackTrace();
781: } finally {
782: try {
783: pstmt.close();
784: } catch (Exception e) {
785: e.printStackTrace();
786: }
787: try {
788: con.close();
789: } catch (Exception e) {
790: e.printStackTrace();
791: }
792: }
793: }
794:
795: private void checkBlackList(User user, ClientIP clientIP)
796: throws UserBlackListedException {
797: System.err.println("checking blacklist");
798: Connection con = null;
799: PreparedStatement pstmt = null;
800: try {
801: con = DbConnectionManager.getConnection();
802: pstmt = con.prepareStatement(CHECK_BLACK_LIST_IP);
803: pstmt.setString(1, clientIP.getRemoteIP());
804: ResultSet rs = pstmt.executeQuery();
805: if (rs.next()) {
806: pstmt = con.prepareStatement(UPDATE_BLACK_LIST_IP);
807: pstmt.setString(1, clientIP.getRemoteIP());
808: pstmt.executeUpdate();
809: throw new UserBlackListedException(
810: "User Black Listed Error. The IP address "
811: + clientIP.getRemoteIP()
812: + " has been black listed");
813: }
814: pstmt = con.prepareStatement(CHECK_BLACK_LIST_USER);
815: pstmt.setInt(1, user.getID());
816: pstmt.setString(2, "BLOCKED");
817: pstmt.setString(3, "true");
818: rs = pstmt.executeQuery();
819: if (rs.next()) {
820: throw new UserBlackListedException(
821: "User Black Listed Error. This user has been black listed from the sytem");
822: }
823: } catch (SQLException sqle) {
824: System.err
825: .println("an error occured in DbForumMessage (0935):"
826: + sqle.getMessage());
827: sqle.printStackTrace();
828: } finally {
829: try {
830: pstmt.close();
831: } catch (Exception e) {
832: e.printStackTrace();
833: }
834: try {
835: con.close();
836: } catch (Exception e) {
837: e.printStackTrace();
838: }
839: }
840: }
841:
842: public MessageRanking getRanking() {
843: return new MessageRanking(this .ranking);
844: }
845:
846: public void setRanking(int para) throws UnauthorizedException {
847: this.ranking = para;
848: saveToDb();
849:
850: }
851:
852: }
|