KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > Yasna > forum > database > DbForumThread


1 /**
2  * Copyright (C) 2001 Yasna.com. All rights reserved.
3  *
4  * ===================================================================
5  * The Apache Software License, Version 1.1
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  * if any, must include the following acknowledgment:
21  * "This product includes software developed by
22  * Yasna.com (http://www.yasna.com)."
23  * Alternately, this acknowledgment may appear in the software itself,
24  * if and wherever such third-party acknowledgments normally appear.
25  *
26  * 4. The names "Yazd" and "Yasna.com" must not be used to
27  * endorse or promote products derived from this software without
28  * prior written permission. For written permission, please
29  * contact yazd@yasna.com.
30  *
31  * 5. Products derived from this software may not be called "Yazd",
32  * nor may "Yazd" appear in their name, without prior written
33  * permission of Yasna.com.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL YASNA.COM OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of Yasna.com. For more information
51  * on Yasna.com, please see <http://www.yasna.com>.
52  */

53
54 /**
55  * Copyright (C) 2000 CoolServlets.com. All rights reserved.
56  *
57  * ===================================================================
58  * The Apache Software License, Version 1.1
59  *
60  * Redistribution and use in source and binary forms, with or without
61  * modification, are permitted provided that the following conditions
62  * are met:
63  *
64  * 1. Redistributions of source code must retain the above copyright
65  * notice, this list of conditions and the following disclaimer.
66  *
67  * 2. Redistributions in binary form must reproduce the above copyright
68  * notice, this list of conditions and the following disclaimer in
69  * the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3. The end-user documentation included with the redistribution,
73  * if any, must include the following acknowledgment:
74  * "This product includes software developed by
75  * CoolServlets.com (http://www.coolservlets.com)."
76  * Alternately, this acknowledgment may appear in the software itself,
77  * if and wherever such third-party acknowledgments normally appear.
78  *
79  * 4. The names "Jive" and "CoolServlets.com" must not be used to
80  * endorse or promote products derived from this software without
81  * prior written permission. For written permission, please
82  * contact webmaster@coolservlets.com.
83  *
84  * 5. Products derived from this software may not be called "Jive",
85  * nor may "Jive" appear in their name, without prior written
86  * permission of CoolServlets.com.
87  *
88  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
89  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
90  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91  * DISCLAIMED. IN NO EVENT SHALL COOLSERVLETS.COM OR
92  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
93  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
94  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
95  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
97  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
98  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
99  * 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  */

106
107 package com.Yasna.forum.database;
108
109 import java.sql.*;
110 import java.util.Date JavaDoc;
111 import java.util.Iterator JavaDoc;
112 import java.util.Calendar JavaDoc;
113
114 import com.Yasna.forum.*;
115 import com.Yasna.util.*;
116 import com.Yasna.util.Cacheable;
117 import com.Yasna.util.CacheSizes;
118
119 /**
120  * Database implementation of the ForumThread interface.
121  *
122  * @see ForumThread
123  */

124 public class DbForumThread implements ForumThread, Cacheable {
125
126     /** DATABASE QUERIES **/
127     private static final String JavaDoc MESSAGE_COUNT =
128         "SELECT count(*) FROM yazdMessage WHERE threadID=?";
129     private static final String JavaDoc ADD_MESSAGE =
130         "INSERT INTO yazdMessageTree(parentID,childID) VALUES(?,?)";
131     private static final String JavaDoc MOVE_MESSAGE =
132         "UPDATE yazdMessageTree SET parentID=? WHERE childID=?";
133     private static final String JavaDoc CHANGE_MESSAGE_THREAD =
134         "UPDATE yazdMessage SET threadID=? WHERE messageID=?";
135     private static final String JavaDoc UPDATE_THREAD_MODIFIED_DATE =
136         "UPDATE yazdThread SET modifiedDate=? WHERE threadID=?";
137     private static final String JavaDoc DELETE_MESSAGE1 =
138         "DELETE FROM yazdMessageTree WHERE childID=?";
139     private static final String JavaDoc DELETE_MESSAGE2 =
140         "DELETE FROM yazdMessage WHERE messageID=?";
141     private static final String JavaDoc DELETE_MESSAGE_PROPERTIES =
142         "DELETE FROM yazdMessageProp WHERE messageID=?";
143     private static final String JavaDoc LOAD_THREAD =
144         "SELECT rootMessageID, creationDate, modifiedDate, approved, readcnt,typeID,sticky,closedflag FROM yazdThread WHERE threadID=? and forumID=?";
145     private static final String JavaDoc INSERT_THREAD =
146         "INSERT INTO yazdThread(threadID,forumID, rootMessageID,creationDate," +
147         "modifiedDate,approved,readcnt,typeID,sticky,closedflag) VALUES(?,?,?,?,?,?,0,?,0,0)";
148     private static final String JavaDoc UPDATE_READ_CNT =
149         "update yazdThread set readcnt=readcnt+1 where threadID=?";
150     private static final String JavaDoc SAVE_THREAD =
151         "UPDATE yazdThread SET rootMessageID=?, creationDate=?, " +
152         "modifiedDate=?, approved = ?,sticky=?,closedflag=? WHERE threadID=?";
153
154     private int id = -1;
155     //Temporary object reference for when inserting new record.
156
private ForumMessage rootMessage;
157     private int rootMessageID;
158     private int readcount;
159     private java.util.Date JavaDoc creationDate;
160     private java.util.Date JavaDoc modifiedDate;
161     private boolean approved;
162     private boolean sticky=false;
163     private boolean closed=false;
164     private int typeID;
165     private long timestamp = Calendar.getInstance().getTimeInMillis();
166
167     /**
168      * Indicates if the object is ready to be saved or not. An object is not
169      * ready to be saved if it has just been created and has not yet been added
170      * to its container. For example, a message added to a thread, etc.
171      */

172     private boolean isReadyToSave = false;
173
174     /**
175      * The forum allows us access to the message filters.
176      */

177     private DbForum forum;
178
179     /**
180      * The factory provides services such as db connections and logging.
181      */

182     private DbForumFactory factory;
183
184     /**
185      * Creates a new DbForumThread. The supplied message object is used to
186      * derive the name of the thread (subject of message), as well as the
187      * creation date and modified date of thread.
188      *
189      * @param rootMessage the root message of the thread.
190      */

191     protected DbForumThread(ForumMessage rootMessage, boolean approved,
192             DbForum forum, DbForumFactory factory,ThreadType type) throws UnauthorizedException
193     {
194         this.id = DbSequenceManager.nextID("ForumThread");
195         this.forum = forum;
196         this.factory = factory;
197         this.rootMessage = rootMessage;
198         this.rootMessageID = rootMessage.getID();
199         //Set the creation and modified dates to be the same as those of
200
//root message.
201
long rootMessageTime = rootMessage.getCreationDate().getTime();
202         this.creationDate = new java.util.Date JavaDoc(rootMessageTime);
203         this.modifiedDate = new java.util.Date JavaDoc(rootMessageTime);
204         this.approved = approved;
205         this.typeID=type.getID();
206     }
207
208     /**
209      * Loads a DbForumThread from the database based on its id.
210      *
211      * @param id in unique id of the ForumThread to load.
212      * @param forum the Forum that the thread belongs to.
213      * @param factory a ForumFactory to use for loading.
214      */

215     protected DbForumThread(int id, DbForum forum, DbForumFactory factory)
216             throws ForumThreadNotFoundException
217     {
218         this.id = id;
219         this.forum = forum;
220         this.factory = factory;
221         loadFromDb();
222         isReadyToSave = true;
223     }
224
225     //FROM THE FORUMMESSAGE INTERFACE//
226

227     public int getID() {
228         return id;
229     }
230
231     public String JavaDoc getName() {
232         return getRootMessage().getSubject();
233     }
234
235     public boolean isApproved() {
236         return approved;
237     }
238
239     public java.util.Date JavaDoc getCreationDate() {
240         return creationDate;
241     }
242
243     public void setCreationDate(java.util.Date JavaDoc creationDate)
244             throws UnauthorizedException
245     {
246         this.creationDate = creationDate;
247         //Only save to the db if the object is ready
248
if (!isReadyToSave) {
249             return;
250         }
251         saveToDb();
252     }
253
254     public java.util.Date JavaDoc getModifiedDate() {
255         return modifiedDate;
256     }
257
258     public void setModifiedDate(java.util.Date JavaDoc modifiedDate)
259             throws UnauthorizedException
260     {
261         this.modifiedDate = modifiedDate;
262         //Only save to the db if the object is ready
263
if (!isReadyToSave) {
264             return;
265         }
266         saveToDb();
267     }
268
269     public void setApprovment(boolean approved)
270             throws UnauthorizedException
271     {
272         this.approved = approved;
273         //Only save to the db if the object is ready
274
if (!isReadyToSave) {
275             return;
276         }
277         saveToDb();
278         this.getRootMessage().setApprovment(approved);
279     }
280
281     public Forum getForum() {
282         return forum;
283     }
284
285     public ForumMessage getMessage(int messageID)
286             throws ForumMessageNotFoundException
287     {
288         ForumMessage message = factory.getMessage(messageID);
289
290         //Apply filters to message.
291
message = forum.applyFilters(message);
292         return message;
293     }
294
295     public ForumMessage getRootMessage() {
296         try {
297             return getMessage(rootMessageID);
298         }
299         catch (ForumMessageNotFoundException e) {
300             System.err.println("Could not load root message with id " + rootMessageID);
301             e.printStackTrace();
302             return null;
303         }
304         /*DbForumMessage message = (DbForumMessage)factory.cacheManager.get(
305                 DbCacheManager.MESSAGE_CACHE,
306                 new Integer(rootMessageID)
307         );
308         if (message == null) {
309             //Load and add to cache
310             try {
311                 message = new DbForumMessage(rootMessageID, factory);
312                 factory.cacheManager.add(DbCacheManager.MESSAGE_CACHE, new Integer(rootMessageID), message);
313             }
314             catch (ForumMessageNotFoundException e) {
315                 System.err.println("Could not load root message with id " + rootMessageID);
316                 e.printStackTrace();
317             }
318         }
319         return message;
320         */

321     }
322
323     public int getMessageCount() {
324         int messageCount = 0;
325         Connection con = null;
326         PreparedStatement pstmt = null;
327         try {
328             con = DbConnectionManager.getConnection();
329             pstmt = con.prepareStatement(MESSAGE_COUNT);
330             pstmt.setInt(1, id);
331             ResultSet rs = pstmt.executeQuery();
332             rs.next();
333             messageCount = rs.getInt(1);
334         }
335         catch( SQLException sqle ) {
336             System.err.println("DbForumThread:getMessageCount() failed: "+sqle);
337         }
338         finally {
339             try { pstmt.close(); }
340             catch (Exception JavaDoc e) { e.printStackTrace(); }
341             try { con.close(); }
342             catch (Exception JavaDoc e) { e.printStackTrace(); }
343         }
344         return messageCount;
345     }
346     public int getReadCount(){
347         return this.readcount;
348     }
349     public void addReadCount(){
350         Connection con = null;
351         PreparedStatement pstmt = null;
352         try {
353             this.readcount++;
354             con = DbConnectionManager.getConnection();
355             pstmt = con.prepareStatement(UPDATE_READ_CNT);
356             pstmt.setInt(1, id);
357             pstmt.executeUpdate();
358             //System.err.println(this.timestamp +" id "+ this.id+" - count:"+readcount);
359
}
360         catch( SQLException sqle ) {
361             System.err.println("DbForumThread:addReadCount() failed: "+sqle);
362         }
363         finally {
364             try { pstmt.close(); }
365             catch (Exception JavaDoc e) { e.printStackTrace(); }
366             try { con.close(); }
367             catch (Exception JavaDoc e) { e.printStackTrace(); }
368         }
369
370     }
371
372     public void addMessage(ForumMessage parentMessage, ForumMessage newMessage) throws UnauthorizedException{
373         boolean abortTransaction = false;
374         boolean supportsTransactions = false;
375         //Add message to db
376
Connection con = null;
377         PreparedStatement pstmt = null;
378         try {
379             con = DbConnectionManager.getConnection();
380             supportsTransactions = con.getMetaData().supportsTransactions();
381             if (supportsTransactions) {
382                 con.setAutoCommit(false);
383             }
384
385             //Now, insert the message into the database.
386
((ForumMessageProxy)newMessage).insertIntoDb(con, this);
387
388             pstmt = con.prepareStatement(ADD_MESSAGE);
389             pstmt.setInt(1, parentMessage.getID());
390             pstmt.setInt(2, newMessage.getID());
391             pstmt.executeUpdate();
392             pstmt.close();
393
394             //if the user wants to automatically subscribe to the thread then we add it.
395
User newUser = newMessage.getUser();
396             if(newUser.getThreadSubscribe() && newUser.getID() > 1){
397                 newUser.setProperty("WatchThread"+id,"true");
398             }
399
400         }
401         catch( Exception JavaDoc e ) {
402             e.printStackTrace();
403             abortTransaction = true;
404             return;
405         }
406         finally {
407             try {
408                 if (supportsTransactions) {
409                     if (abortTransaction == true) {
410                         con.rollback();
411                     }
412                     else {
413                         con.commit();
414                     }
415                 }
416             }
417             catch (Exception JavaDoc e) { e.printStackTrace(); }
418             try {
419                 if (supportsTransactions) {
420                     con.setAutoCommit(true);
421                 }
422                 con.close();
423             }
424             catch (Exception JavaDoc e) { e.printStackTrace(); }
425         }
426
427         //Added new message, so update the modified date of this thread
428
updateModifiedDate(newMessage.getModifiedDate());
429         //Also, update the modified date of the forum
430
DbForum dbForum = (DbForum)factory.cacheManager.get(
431                 DbCacheManager.FORUM_CACHE,
432                 new Integer JavaDoc(forum.getID())
433             );
434         if (dbForum != null) {
435             dbForum.updateModifiedDate(modifiedDate);
436         }
437         else {
438             forum.updateModifiedDate(modifiedDate);
439         }
440     }
441
442     public void deleteMessage(ForumMessage message)
443             throws UnauthorizedException
444     {
445         //Skip null messages or the case that we're already deleting the thread.
446
if (message == null) {
447             return;
448         }
449         //If the message does not belong to this thread, don't perform delete.
450
if (message.getForumThread().getID() != this.id) {
451             throw new IllegalArgumentException JavaDoc("Message " + message.getID() +
452                 " could not be deleted. It belongs to thread " +
453                 message.getForumThread().getID() + ", and not thread " +
454                 this.id + ".");
455         }
456         Connection con = null;
457         PreparedStatement pstmt = null;
458         try {
459             con = DbConnectionManager.getConnection();
460             //Delete the message from the parent/child table
461
pstmt = con.prepareStatement(DELETE_MESSAGE1);
462             pstmt.setInt(1, message.getID());
463             pstmt.execute();
464         }
465         catch( SQLException sqle ) {
466             System.err.println("Error in DbForumThread:deleteMessage()-" + sqle);
467         }
468         finally {
469             try { pstmt.close(); }
470             catch (Exception JavaDoc e) { e.printStackTrace(); }
471             try { con.close(); }
472             catch (Exception JavaDoc e) { e.printStackTrace(); }
473         }
474
475         //Recursively delete all children
476
TreeWalker walker = treeWalker();
477         int childCount = walker.getChildCount(message);
478         for (int i=childCount-1; i>=0; i--) {
479             ForumMessage childMessage = walker.getChild(message, i);
480             if (childMessage == null) {
481                 System.err.println("child message was null -- index " + i);
482             }
483             deleteMessage(childMessage);
484         }
485         try {
486             //Delete the actual message.
487
con = DbConnectionManager.getConnection();
488             pstmt = con.prepareStatement(DELETE_MESSAGE2);
489             pstmt.setInt(1, message.getID());
490             pstmt.execute();
491             pstmt.close();
492
493             //Delete any message properties.
494
pstmt = con.prepareStatement(DELETE_MESSAGE_PROPERTIES);
495             pstmt.setInt(1, message.getID());
496             pstmt.execute();
497         }
498         catch( SQLException sqle ) {
499             System.err.println("Error in DbForumThread:deleteMessage()-" + sqle);
500         }
501         finally {
502             try { pstmt.close(); }
503             catch (Exception JavaDoc e) { e.printStackTrace(); }
504             try { con.close(); }
505             catch (Exception JavaDoc e) { e.printStackTrace(); }
506         }
507         //Now, delete from the cache.
508
factory.getCacheManager().remove(
509                 DbCacheManager.MESSAGE_CACHE,
510                 new Integer JavaDoc(message.getID())
511         );
512
513         //Finally, delete it from the search index
514
factory.getSearchIndexer().removeFromIndex(message);
515
516         //Now, make sure that the message being deleted isn't the root message
517
//of this thread. If it is, the whole thread should just be deleted.
518
if (message.getID() == this.rootMessageID) {
519             forum.deleteThreadRecord(this.id);
520         }
521     }
522
523     public void moveMessage(ForumMessage message, ForumThread newThread,
524             ForumMessage parentMessage)
525             throws UnauthorizedException, IllegalArgumentException JavaDoc
526     {
527         if (message.getForumThread().getID() != this.id ||
528                 parentMessage.getForumThread().getID() != newThread.getID())
529         {
530             throw new IllegalArgumentException JavaDoc(
531                 "The messages and threads did not match."
532             );
533         }
534
535         // Save the mesageID of message to move
536
int messageID = message.getID();
537         // Original message thread rootMessageID
538
int oldRootMessageID = getRootMessage().getID();
539
540         // Move the children of this message to the new thread
541
TreeWalker walker = treeWalker();
542         int childCount = walker.getChildCount(message);
543         for (int i=0; i<childCount; i++) {
544             ForumMessage childMessage = walker.getChild(message, i);
545             changeMessageThread(childMessage, newThread);
546         }
547
548         //Move the message to the new thread.
549
changeMessageThread(message, newThread);
550
551         //Make message a child of parentMessage
552
Connection con = null;
553         PreparedStatement pstmt = null;
554         try {
555             con = DbConnectionManager.getConnection();
556
557             if( oldRootMessageID != messageID ) {
558                 pstmt = con.prepareStatement(MOVE_MESSAGE);
559                 pstmt.setInt(1, parentMessage.getID());
560                 pstmt.setInt(2, messageID);
561             }
562             else {
563                 pstmt = con.prepareStatement(ADD_MESSAGE);
564                 pstmt.setInt(1, parentMessage.getID());
565                 pstmt.setInt(2, messageID);
566             }
567
568             pstmt.executeUpdate();
569             pstmt.close();
570         }
571         catch( SQLException sqle ) {
572             System.err.println("Error in DbForumThread:moveMessage()-" + sqle);
573         }
574         finally {
575             try { pstmt.close(); }
576             catch (Exception JavaDoc e) { e.printStackTrace(); }
577             try { con.close(); }
578             catch (Exception JavaDoc e) { e.printStackTrace(); }
579         }
580
581         //Update the modified date of newThread
582
Date JavaDoc now = new Date JavaDoc();
583         newThread.setModifiedDate(now);
584         //Update the modified date of newThread forum
585
newThread.getForum().setModifiedDate(now);
586
587         //Thread has been modified, invalidate the cache
588
DbCacheManager cacheManager = factory.getCacheManager();
589         Integer JavaDoc key = new Integer JavaDoc(this.id);
590         cacheManager.remove(DbCacheManager.THREAD_CACHE, key);
591
592         //If we moved the root message of this thread, the thread should be
593
//deleted. Normally, deleting a thread will delete all of it's messages.
594
//However, we've already adjusted the thread/message relationship at the
595
//SQL level and removed the thread from cache. That should mean we're safe.
596
if (getRootMessage().getID() == messageID) {
597             //rootMessage = null;
598
this.getForum().deleteThread(this);
599         }
600     }
601
602     public TreeWalker treeWalker() {
603         return new DbTreeWalker(this, factory);
604     }
605
606     public Iterator JavaDoc messages() {
607         return new DbThreadIterator(this);
608     }
609
610     public Iterator JavaDoc messages(int startIndex, int numResults) {
611         return new DbThreadIterator(this, startIndex, numResults);
612     }
613
614     public boolean hasPermission(int type) {
615         return true;
616     }
617
618     //FROM THE CACHEABLE INTERFACE//
619

620     public int getSize() {
621         //Approximate the size of the object in bytes by calculating the size
622
//of each field.
623
int size = 0;
624         size += CacheSizes.sizeOfObject(); //overhead of object
625
size += CacheSizes.sizeOfInt(); //id
626
size += CacheSizes.sizeOfDate(); //creation date
627
size += CacheSizes.sizeOfDate(); //modified date
628
size += CacheSizes.sizeOfBoolean(); //approved
629
size += CacheSizes.sizeOfObject(); //ref to rootMessage
630
size += CacheSizes.sizeOfObject(); //ref to forum
631
size += CacheSizes.sizeOfObject(); //ref to factory
632
size += CacheSizes.sizeOfBoolean(); //ready save var
633
size += CacheSizes.sizeOfBoolean(); //deleting var
634
size += CacheSizes.sizeOfInt(); //read count
635
size += CacheSizes.sizeOfLong(); //timestamp
636

637         return size;
638     }
639
640     //OTHER METHODS//
641

642     /**
643      * Converts the object to a String by returning the name of the thread.
644      * This functionality is primarily for Java applications that might be
645      * accessing Yazd objects through a GUI.
646      */

647     public String JavaDoc toString() {
648         return getName();
649     }
650
651     public int hashCode() {
652         return id;
653     }
654
655     public boolean equals(Object JavaDoc object) {
656         if (this == object) {
657             return true;
658         }
659         if (object != null && object instanceof DbForumThread) {
660             return id == ((DbForumThread)object).getID();
661         }
662         else {
663             return false;
664         }
665     }
666
667     /**
668      * Updates the modified date but doesn't require a security check since
669      * it is a protected method.
670      */

671     protected void updateModifiedDate(java.util.Date JavaDoc modifiedDate) {
672         this.modifiedDate = modifiedDate;
673         Connection con = null;
674         PreparedStatement pstmt = null;
675         try {
676             con = DbConnectionManager.getConnection();
677             pstmt = con.prepareStatement(UPDATE_THREAD_MODIFIED_DATE);
678             pstmt.setString(1, ""+modifiedDate.getTime());
679             pstmt.setInt(2, id);
680             pstmt.executeUpdate();
681         }
682         catch( SQLException sqle ) {
683             System.err.println("Error in DbForumThread:updateModifiedDate()-" + sqle);
684             sqle.printStackTrace();
685         }
686         finally {
687             try { pstmt.close(); }
688             catch (Exception JavaDoc e) { e.printStackTrace(); }
689             try { con.close(); }
690             catch (Exception JavaDoc e) { e.printStackTrace(); }
691         }
692     }
693
694     /**
695      * Moves a message to a new thread by modifying the message table threadID
696      * column.
697      *
698      * @param message the message to move.
699      * @param newThread the thread to move the message to.
700      */

701     private void changeMessageThread(ForumMessage message, ForumThread newThread)
702         throws UnauthorizedException
703     {
704         //Remove message from the search index
705
factory.getSearchIndexer().removeFromIndex(message);
706
707         //Remove message from cache.
708
DbCacheManager cacheManager = factory.getCacheManager();
709         Integer JavaDoc key = new Integer JavaDoc(message.getID());
710         cacheManager.remove(DbCacheManager.MESSAGE_CACHE, key);
711
712         Connection con = null;
713         PreparedStatement pstmt = null;
714         try {
715             con = DbConnectionManager.getConnection();
716             pstmt = con.prepareStatement(CHANGE_MESSAGE_THREAD);
717             pstmt.setInt(1, newThread.getID());
718             pstmt.setInt(2, key.intValue());
719             pstmt.executeUpdate();
720         }
721         catch( SQLException sqle ) {
722             sqle.printStackTrace();
723         }
724
725         // Add message back to search index and update modified date
726
try {
727             ForumMessage movedMessage = newThread.getMessage(key.intValue());
728             factory.getSearchIndexer().addToIndex(movedMessage);
729             movedMessage.setModifiedDate(new Date JavaDoc());
730         }
731         catch(ForumMessageNotFoundException e) {
732             System.err.println("Error in DbForumThread:changeMessageThread()-" +
733             "messageID=" + key.intValue() + "newThreadID=" + newThread.getID());
734         }
735
736         finally {
737             try { pstmt.close(); }
738             catch (Exception JavaDoc e) { e.printStackTrace(); }
739             try { con.close(); }
740             catch (Exception JavaDoc e) { e.printStackTrace(); }
741         }
742     }
743
744     /**
745      * Loads a ForumThread from the database.
746      */

747     private void loadFromDb() throws ForumThreadNotFoundException {
748         Connection con = null;
749         PreparedStatement pstmt = null;
750         try {
751             con = DbConnectionManager.getConnection();
752             pstmt = con.prepareStatement(LOAD_THREAD);
753             pstmt.setInt(1, id);
754             pstmt.setInt(2,forum.getID());
755             ResultSet rs = pstmt.executeQuery();
756             if( !rs.next() ) {
757                 throw new ForumThreadNotFoundException("Thread " + id +
758                     " could not be loaded from the database.");
759             }
760             //try {
761
rootMessageID = rs.getInt("rootMessageID");
762             //}
763
//catch (ForumMessageNotFoundException fmnfe) {
764
// System.err.println("Error: could not load root message of thread "
765
// + id + ". The database record could be corrupt.");
766
// fmnfe.printStackTrace();
767
//}
768
creationDate = new java.util.Date JavaDoc(Long.parseLong(rs.getString("creationDate").trim()));
769             modifiedDate = new java.util.Date JavaDoc(Long.parseLong(rs.getString("modifiedDate").trim()));
770             approved = rs.getInt("approved") == 1 ? true : false;
771             readcount = rs.getInt("readcnt");
772             typeID = rs.getInt("typeID");
773             closed = rs.getInt("closedflag") == 1 ? true : false;
774             sticky = rs.getInt("sticky") == 1 ? true : false;
775             pstmt.close();
776         }
777         catch( SQLException sqle ) {
778             throw new ForumThreadNotFoundException("Thread " + id +
779                 " could not be loaded from the database.");
780         }
781         catch (NumberFormatException JavaDoc nfe) {
782             System.err.println("WARNING: In DbForumThread.loadFromDb() -- there " +
783                 "was an error parsing the dates returned from the database. Ensure " +
784                 "that they're being stored correctly.");
785         }
786         finally {
787             try { con.close(); }
788             catch (Exception JavaDoc e) { e.printStackTrace(); }
789         }
790     }
791
792     /**
793      * Inserts a new forum thread into the database. A connection object must
794      * be passed in. The connection must be open when passed in, and will
795      * remain open when passed back. This method allows us to make insertions
796      * be transactional.
797      *
798      * @param con an open Connection used to insert the thread to the db.
799      */

800     public void insertIntoDb(Connection con) throws SQLException {
801         PreparedStatement pstmt = con.prepareStatement(INSERT_THREAD);
802         pstmt.setInt(1, id);
803         pstmt.setInt(2, forum.getID());
804         pstmt.setInt(3, rootMessageID);
805         pstmt.setString(4, Long.toString(creationDate.getTime()));
806         pstmt.setString(5, Long.toString(modifiedDate.getTime()));
807         pstmt.setInt(6, approved?1:0);
808         pstmt.setInt(7, typeID);
809         pstmt.executeUpdate();
810         pstmt.close();
811
812         //Now, insert the message into the database.
813
((ForumMessageProxy)rootMessage).insertIntoDb(con, this);
814
815         //since we're done inserting the object to the database, it is ready
816
//for future insertions.
817
isReadyToSave = true;
818     }
819
820     /**
821      * Saves the ForumThread to the database.
822      */

823     private synchronized void saveToDb() {
824         Connection con = null;
825         PreparedStatement pstmt = null;
826          try {
827             con = DbConnectionManager.getConnection();
828             pstmt = con.prepareStatement(SAVE_THREAD);
829             pstmt.setInt(1, rootMessageID);
830             pstmt.setString(2, Long.toString(creationDate.getTime()));
831             pstmt.setString(3, Long.toString(modifiedDate.getTime()));
832             pstmt.setInt(4, approved ? 1 : 0);
833             pstmt.setInt(5, sticky ? 1 : 0);
834             pstmt.setInt(6, closed ? 1 : 0);
835             pstmt.setInt(7, id);
836             pstmt.executeUpdate();
837         }
838         catch( SQLException sqle ) {
839             System.err.println("Error in DbForumThread:saveToDb()-" + sqle);
840         }
841         finally {
842             try { pstmt.close(); }
843             catch (Exception JavaDoc e) { e.printStackTrace(); }
844             try { con.close(); }
845             catch (Exception JavaDoc e) { e.printStackTrace(); }
846         }
847     }
848     public ThreadType getThreadType(){
849         return factory.getThreadType(this.typeID);
850     }
851     public boolean isSticky(){
852         return this.sticky;
853     }
854     public void setSticky(boolean param) throws UnauthorizedException{
855         this.sticky=param;
856         saveToDb();
857     }
858     public boolean isClosed(){
859         return this.closed;
860     }
861     public void setClosed(boolean param) throws UnauthorizedException{
862         this.closed=param;
863         saveToDb();
864     }
865
866
867 }
868
Popular Tags