1 53 54 106 107 package com.Yasna.forum.database; 108 109 import java.sql.*; 110 import java.util.Date ; 111 import java.util.Iterator ; 112 import java.util.Calendar ; 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 124 public class DbForumThread implements ForumThread, Cacheable { 125 126 127 private static final String MESSAGE_COUNT = 128 "SELECT count(*) FROM yazdMessage WHERE threadID=?"; 129 private static final String ADD_MESSAGE = 130 "INSERT INTO yazdMessageTree(parentID,childID) VALUES(?,?)"; 131 private static final String MOVE_MESSAGE = 132 "UPDATE yazdMessageTree SET parentID=? WHERE childID=?"; 133 private static final String CHANGE_MESSAGE_THREAD = 134 "UPDATE yazdMessage SET threadID=? WHERE messageID=?"; 135 private static final String UPDATE_THREAD_MODIFIED_DATE = 136 "UPDATE yazdThread SET modifiedDate=? WHERE threadID=?"; 137 private static final String DELETE_MESSAGE1 = 138 "DELETE FROM yazdMessageTree WHERE childID=?"; 139 private static final String DELETE_MESSAGE2 = 140 "DELETE FROM yazdMessage WHERE messageID=?"; 141 private static final String DELETE_MESSAGE_PROPERTIES = 142 "DELETE FROM yazdMessageProp WHERE messageID=?"; 143 private static final String LOAD_THREAD = 144 "SELECT rootMessageID, creationDate, modifiedDate, approved, readcnt,typeID,sticky,closedflag FROM yazdThread WHERE threadID=? and forumID=?"; 145 private static final String 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 UPDATE_READ_CNT = 149 "update yazdThread set readcnt=readcnt+1 where threadID=?"; 150 private static final String SAVE_THREAD = 151 "UPDATE yazdThread SET rootMessageID=?, creationDate=?, " + 152 "modifiedDate=?, approved = ?,sticky=?,closedflag=? WHERE threadID=?"; 153 154 private int id = -1; 155 private ForumMessage rootMessage; 157 private int rootMessageID; 158 private int readcount; 159 private java.util.Date creationDate; 160 private java.util.Date 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 172 private boolean isReadyToSave = false; 173 174 177 private DbForum forum; 178 179 182 private DbForumFactory factory; 183 184 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 long rootMessageTime = rootMessage.getCreationDate().getTime(); 202 this.creationDate = new java.util.Date (rootMessageTime); 203 this.modifiedDate = new java.util.Date (rootMessageTime); 204 this.approved = approved; 205 this.typeID=type.getID(); 206 } 207 208 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 227 public int getID() { 228 return id; 229 } 230 231 public String getName() { 232 return getRootMessage().getSubject(); 233 } 234 235 public boolean isApproved() { 236 return approved; 237 } 238 239 public java.util.Date getCreationDate() { 240 return creationDate; 241 } 242 243 public void setCreationDate(java.util.Date creationDate) 244 throws UnauthorizedException 245 { 246 this.creationDate = creationDate; 247 if (!isReadyToSave) { 249 return; 250 } 251 saveToDb(); 252 } 253 254 public java.util.Date getModifiedDate() { 255 return modifiedDate; 256 } 257 258 public void setModifiedDate(java.util.Date modifiedDate) 259 throws UnauthorizedException 260 { 261 this.modifiedDate = modifiedDate; 262 if (!isReadyToSave) { 264 return; 265 } 266 saveToDb(); 267 } 268 269 public void setApprovment(boolean approved) 270 throws UnauthorizedException 271 { 272 this.approved = approved; 273 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 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 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 e) { e.printStackTrace(); } 341 try { con.close(); } 342 catch (Exception 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 } 360 catch( SQLException sqle ) { 361 System.err.println("DbForumThread:addReadCount() failed: "+sqle); 362 } 363 finally { 364 try { pstmt.close(); } 365 catch (Exception e) { e.printStackTrace(); } 366 try { con.close(); } 367 catch (Exception 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 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 ((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 User newUser = newMessage.getUser(); 396 if(newUser.getThreadSubscribe() && newUser.getID() > 1){ 397 newUser.setProperty("WatchThread"+id,"true"); 398 } 399 400 } 401 catch( Exception 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 e) { e.printStackTrace(); } 418 try { 419 if (supportsTransactions) { 420 con.setAutoCommit(true); 421 } 422 con.close(); 423 } 424 catch (Exception e) { e.printStackTrace(); } 425 } 426 427 updateModifiedDate(newMessage.getModifiedDate()); 429 DbForum dbForum = (DbForum)factory.cacheManager.get( 431 DbCacheManager.FORUM_CACHE, 432 new Integer (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 if (message == null) { 447 return; 448 } 449 if (message.getForumThread().getID() != this.id) { 451 throw new IllegalArgumentException ("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 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 e) { e.printStackTrace(); } 471 try { con.close(); } 472 catch (Exception e) { e.printStackTrace(); } 473 } 474 475 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 con = DbConnectionManager.getConnection(); 488 pstmt = con.prepareStatement(DELETE_MESSAGE2); 489 pstmt.setInt(1, message.getID()); 490 pstmt.execute(); 491 pstmt.close(); 492 493 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 e) { e.printStackTrace(); } 504 try { con.close(); } 505 catch (Exception e) { e.printStackTrace(); } 506 } 507 factory.getCacheManager().remove( 509 DbCacheManager.MESSAGE_CACHE, 510 new Integer (message.getID()) 511 ); 512 513 factory.getSearchIndexer().removeFromIndex(message); 515 516 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 526 { 527 if (message.getForumThread().getID() != this.id || 528 parentMessage.getForumThread().getID() != newThread.getID()) 529 { 530 throw new IllegalArgumentException ( 531 "The messages and threads did not match." 532 ); 533 } 534 535 int messageID = message.getID(); 537 int oldRootMessageID = getRootMessage().getID(); 539 540 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 changeMessageThread(message, newThread); 550 551 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 e) { e.printStackTrace(); } 577 try { con.close(); } 578 catch (Exception e) { e.printStackTrace(); } 579 } 580 581 Date now = new Date (); 583 newThread.setModifiedDate(now); 584 newThread.getForum().setModifiedDate(now); 586 587 DbCacheManager cacheManager = factory.getCacheManager(); 589 Integer key = new Integer (this.id); 590 cacheManager.remove(DbCacheManager.THREAD_CACHE, key); 591 592 if (getRootMessage().getID() == messageID) { 597 this.getForum().deleteThread(this); 599 } 600 } 601 602 public TreeWalker treeWalker() { 603 return new DbTreeWalker(this, factory); 604 } 605 606 public Iterator messages() { 607 return new DbThreadIterator(this); 608 } 609 610 public Iterator 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 620 public int getSize() { 621 int size = 0; 624 size += CacheSizes.sizeOfObject(); size += CacheSizes.sizeOfInt(); size += CacheSizes.sizeOfDate(); size += CacheSizes.sizeOfDate(); size += CacheSizes.sizeOfBoolean(); size += CacheSizes.sizeOfObject(); size += CacheSizes.sizeOfObject(); size += CacheSizes.sizeOfObject(); size += CacheSizes.sizeOfBoolean(); size += CacheSizes.sizeOfBoolean(); size += CacheSizes.sizeOfInt(); size += CacheSizes.sizeOfLong(); 637 return size; 638 } 639 640 642 647 public String toString() { 648 return getName(); 649 } 650 651 public int hashCode() { 652 return id; 653 } 654 655 public boolean equals(Object 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 671 protected void updateModifiedDate(java.util.Date 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 e) { e.printStackTrace(); } 689 try { con.close(); } 690 catch (Exception e) { e.printStackTrace(); } 691 } 692 } 693 694 701 private void changeMessageThread(ForumMessage message, ForumThread newThread) 702 throws UnauthorizedException 703 { 704 factory.getSearchIndexer().removeFromIndex(message); 706 707 DbCacheManager cacheManager = factory.getCacheManager(); 709 Integer key = new Integer (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 try { 727 ForumMessage movedMessage = newThread.getMessage(key.intValue()); 728 factory.getSearchIndexer().addToIndex(movedMessage); 729 movedMessage.setModifiedDate(new Date ()); 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 e) { e.printStackTrace(); } 739 try { con.close(); } 740 catch (Exception e) { e.printStackTrace(); } 741 } 742 } 743 744 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 rootMessageID = rs.getInt("rootMessageID"); 762 creationDate = new java.util.Date (Long.parseLong(rs.getString("creationDate").trim())); 769 modifiedDate = new java.util.Date (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 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 e) { e.printStackTrace(); } 789 } 790 } 791 792 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 ((ForumMessageProxy)rootMessage).insertIntoDb(con, this); 814 815 isReadyToSave = true; 818 } 819 820 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 e) { e.printStackTrace(); } 844 try { con.close(); } 845 catch (Exception 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 |