1 25 package org.nemesis.forum.impl; 26 27 import java.sql.Connection ; 28 import java.sql.PreparedStatement ; 29 import java.sql.ResultSet ; 30 import java.sql.SQLException ; 31 import java.util.Collections ; 32 import java.util.HashMap ; 33 import java.util.Iterator ; 34 import java.util.Map ; 35 import java.util.Properties ; 36 import java.util.Vector ; 37 38 import org.apache.commons.logging.Log; 39 import org.apache.commons.logging.LogFactory; 40 import org.nemesis.forum.Forum; 41 import org.nemesis.forum.ForumFactory; 42 import org.nemesis.forum.ForumThread; 43 import org.nemesis.forum.Message; 44 import org.nemesis.forum.User; 45 import org.nemesis.forum.event.ForumEvent; 46 import org.nemesis.forum.event.ForumListener; 47 import org.nemesis.forum.exception.ForumMessageNotFoundException; 48 import org.nemesis.forum.exception.UnauthorizedException; 49 import org.nemesis.forum.exception.UserNotFoundException; 50 import org.nemesis.forum.util.StringUtils; 51 import org.nemesis.forum.util.cache.CacheSizes; 52 import org.nemesis.forum.util.cache.Cacheable; 53 import org.nemesis.forum.util.jdbc.DbConnectionManager; 54 59 public final class DbForumMessage implements Message, Cacheable { 60 static protected Log log = LogFactory.getLog(DbForumMessage.class); 61 62 private static final String LOAD_PROPERTIES = "SELECT name, propValue FROM yazdMessageProp WHERE messageID=?"; 63 private static final String DELETE_PROPERTIES = "DELETE FROM yazdMessageProp WHERE messageID=?"; 64 private static final String INSERT_PROPERTY = "INSERT INTO yazdMessageProp(messageID,name,propValue) VALUES(?,?,?)"; 65 66 private static final String LOAD_MESSAGE = "SELECT userID, creationDate, modifiedDate, subject, body, threadID,approved FROM " + "yazdMessage WHERE messageID=?"; 67 private static final String INSERT_MESSAGE ="INSERT INTO yazdMessage(messageID, threadID,creationDate,modifiedDate,userID," + "subject,body,approved) VALUES(?,?,?,?,?,?,?,?)"; 68 private static final String SAVE_MESSAGE = "UPDATE yazdMessage SET userID=?, subject=?, body=?, creationDate=?, modifiedDate=?,approved=? " + "WHERE messageID=?"; 69 70 private static final String GET_FORUM_BY_THREAD = "SELECT forumID FROM yazdThread where threadID=?"; 71 72 private int id = -1; 73 private java.util.Date creationDate; 74 private java.util.Date modifiedDate; 75 private String subject = ""; 76 private String body = ""; 77 private int userID; 78 private int threadID; 79 private Map properties; 80 private Object propertyLock = new Object (); 81 private ForumFactory factory; 82 private ForumThread thread = null; 83 protected boolean approved; 85 90 private boolean isReadyToSave = false; 91 92 95 protected DbForumMessage(User user,boolean approved,ForumFactory factory) { 96 this.id = DbSequenceManager.nextID("ForumMessage"); 97 long now = System.currentTimeMillis(); 98 creationDate = new java.util.Date (now); 99 modifiedDate = new java.util.Date (now); 100 this.userID = user.getID(); 101 this.factory = factory; 102 this.approved=approved; 103 properties = Collections.synchronizedMap(new HashMap ()); 104 } 105 106 109 protected DbForumMessage(int id ,DbForumFactory factory) throws ForumMessageNotFoundException { 110 this.id = id; 111 this.factory = factory; 112 loadFromDb(); 113 loadProperties(); 114 isReadyToSave = true; 115 } 116 117 public boolean isApproved(){ 119 return approved; 120 } 121 122 public void setApproved(boolean approved) throws UnauthorizedException{ 123 this.approved = approved; 124 if (!isReadyToSave) { 126 return; 127 } 128 saveToDb(); 129 } 130 131 public int getID() { 132 return id; 133 } 134 135 public java.util.Date getCreationDate() { 136 return creationDate; 137 } 138 139 public void setCreationDate(java.util.Date creationDate) throws UnauthorizedException { 140 this.creationDate = creationDate; 141 if (!isReadyToSave) { 143 return; 144 } 145 saveToDb(); 146 } 147 148 public java.util.Date getModifiedDate() { 149 return modifiedDate; 150 } 151 152 public void setModifiedDate(java.util.Date modifiedDate) throws UnauthorizedException { 153 this.modifiedDate = modifiedDate; 154 if (!isReadyToSave) { 156 return; 157 } 158 saveToDb(); 159 } 160 161 public String getSubject() { 162 return subject; 163 } 164 165 public String getUnfilteredSubject() { 166 return subject; 167 } 168 169 public void setSubject(String subject) throws UnauthorizedException { 170 this.subject = subject; 171 if (!isReadyToSave) { 173 return; 174 } 175 modifiedDate.setTime(System.currentTimeMillis()); 177 saveToDb(); 178 } 179 180 public String getBody() { 181 return body; 182 } 183 184 public String getUnfilteredBody() { 185 return body; 186 } 187 188 public void setBody(String body) throws UnauthorizedException { 189 this.body = body; 190 if (!isReadyToSave) { 192 return; 193 } 194 modifiedDate.setTime(System.currentTimeMillis()); 196 saveToDb(); 197 } 198 199 public User getUser() { 200 User user = null; 201 try { 202 if (userID == -1) { 203 user = factory.getProfileManager().getAnonymousUser(); 204 } else { 205 user = factory.getProfileManager().getUser(userID); 206 } 207 } catch (UserNotFoundException unfe) { 208 log.error("",unfe); 209 } 210 return user; 211 } 212 213 public String getProperty(String name) { 214 return StringUtils.escapeHTMLTags((String ) properties.get(name)); 216 } 217 218 public String getUnfilteredProperty(String name) { 219 return (String ) properties.get(name); 220 } 221 222 public void setProperty(String name, String value) { 223 properties.put(name, value); 224 if (!isReadyToSave) { 226 return; 227 } 228 saveProperties(); 229 } 230 231 public Iterator propertyNames() { 232 return Collections.unmodifiableSet(properties.keySet()).iterator(); 233 } 234 235 public boolean isAnonymous() { 236 return (userID == -1); 237 } 238 239 public ForumThread getForumThread() { 240 if (thread != null) { 241 return thread; 242 } 243 else { 246 int forumID = -1; 249 Connection con = null; 250 PreparedStatement pstmt = null; 251 try { 252 con = DbConnectionManager.getConnection(); 253 pstmt = con.prepareStatement(GET_FORUM_BY_THREAD); 254 pstmt.setInt(1, threadID); 255 ResultSet rs = pstmt.executeQuery(); 256 if (rs.next()) { 257 forumID = rs.getInt("forumID"); 258 } 259 } catch (SQLException sqle) { 260 log.error("",sqle); 261 } finally { 262 try { 263 pstmt.close(); 264 } catch (Exception e) { 265 log.error("",e); 266 } 267 try { 268 con.close(); 269 } catch (Exception e) { 270 log.error("",e); 271 } 272 } 273 if (forumID < 1) { 276 log.error( 277 "WARNING: forumID of " 278 + forumID 279 + " found for message " 280 + id 281 + " in DbForumMessage.getForumThread()." 282 + " You may wish to delete the message from your database."); 283 return null; 284 } 285 286 Forum forum = null; 287 ForumThread thread = null; 288 try { 289 forum = factory.getForum(forumID); 290 thread = forum.getThread(threadID); 292 } catch (Exception e) { 293 log.error("",e); 294 return null; 295 } 296 this.thread = thread; 297 return thread; 298 } 299 } 300 301 public boolean hasPermission(int type) { 302 return true; 303 } 304 305 307 public int getSize() { 308 int size = 0; 311 size += CacheSizes.sizeOfObject(); size += CacheSizes.sizeOfInt(); size += CacheSizes.sizeOfString(subject); size += CacheSizes.sizeOfString(body); size += CacheSizes.sizeOfDate(); size += CacheSizes.sizeOfDate(); size += CacheSizes.sizeOfInt(); size += CacheSizes.sizeOfInt(); size += CacheSizes.sizeOfMap(properties); size += CacheSizes.sizeOfObject(); size += CacheSizes.sizeOfObject(); 323 return size; 324 } 325 326 328 333 public String toString() { 334 return subject; 335 } 336 337 338 339 340 public int hashCode() { 341 return id; 342 } 343 344 public boolean equals(Object object) { 345 if (this == object) { 346 return true; 347 } 348 if (object != null && object instanceof DbForumMessage) { 349 return id == ((DbForumMessage) object).getID(); 350 } else { 351 return false; 352 } 353 } 354 355 358 private void loadProperties() { 359 synchronized (propertyLock) { 360 Properties newProps = new Properties (); 361 Connection con = null; 362 PreparedStatement pstmt = null; 363 try { 364 con = DbConnectionManager.getConnection(); 365 pstmt = con.prepareStatement(LOAD_PROPERTIES); 366 pstmt.setInt(1, id); 367 ResultSet rs = pstmt.executeQuery(); 368 while (rs.next()) { 369 String name = rs.getString("name"); 370 String value = rs.getString("propValue"); 371 newProps.put(name, value); 372 } 373 } catch (SQLException sqle) { 374 log.error("Error in DbForumMessage:loadProperties():" , sqle); 375 376 } finally { 377 try { 378 pstmt.close(); 379 } catch (Exception e) { 380 log.error("",e); 381 } 382 try { 383 con.close(); 384 } catch (Exception e) { 385 log.error("",e); 386 } 387 } 388 this.properties = newProps; 389 } 390 } 391 392 395 private void saveProperties() { 396 synchronized (propertyLock) { 397 Connection con = null; 398 PreparedStatement pstmt = null; 399 try { 400 con = DbConnectionManager.getConnection(); 401 pstmt = con.prepareStatement(DELETE_PROPERTIES); 403 pstmt.setInt(1, id); 404 pstmt.execute(); 405 pstmt.close(); 406 pstmt = con.prepareStatement(INSERT_PROPERTY); 408 Iterator iter = properties.keySet().iterator(); 409 while (iter.hasNext()) { 410 String name = (String ) iter.next(); 411 String value = (String ) properties.get(name); 412 pstmt.setInt(1, id); 413 pstmt.setString(2, name); 414 pstmt.setString(3, value); 415 pstmt.executeUpdate(); 416 } 417 } catch (SQLException sqle) { 418 log.error("",sqle); 419 } finally { 420 try { 421 pstmt.close(); 422 } catch (Exception e) { 423 log.error("",e); 424 } 425 try { 426 con.close(); 427 } catch (Exception e) { 428 log.error("",e); 429 } 430 } 431 } 432 } 433 434 437 private void loadFromDb() throws ForumMessageNotFoundException { 438 Connection con = null; 440 PreparedStatement pstmt = null; 441 try { 442 con = DbConnectionManager.getConnection(); 443 pstmt = con.prepareStatement(LOAD_MESSAGE); 444 pstmt.setInt(1, id); 445 ResultSet rs = pstmt.executeQuery(); 446 if (!rs.next()) { 447 throw new ForumMessageNotFoundException("Message " + id + " could not be loaded from the database."); 448 } 449 this.userID = rs.getInt(1); 453 this.creationDate = new java.util.Date (Long.parseLong(rs.getString(2).trim())); 456 this.modifiedDate = new java.util.Date (Long.parseLong(rs.getString(3).trim())); 457 this.subject = rs.getString(4); 458 this.body = rs.getString(5); 459 this.threadID = rs.getInt(6); 460 this.approved= rs.getInt(7)==1; 461 } catch (SQLException sqle) { 462 throw new ForumMessageNotFoundException("Message of id " + id + " was not found in the database."); 463 } catch (NumberFormatException nfe) { 464 log.error( 465 "WARNING: In DbForumMessage.loadFromDb() -- there " 466 + "was an error parsing the dates returned from the database. Ensure " 467 + "that they're being stored correctly."); 468 } finally { 469 try { 470 pstmt.close(); 471 } catch (Exception e) { 472 log.error("",e); 473 } 474 try { 475 con.close(); 476 } catch (Exception e) { 477 log.error("",e); 478 } 479 } 480 } 481 482 491 public void insertIntoDb(Connection con, ForumThread thread) throws SQLException { 492 this.threadID = thread.getID(); 495 PreparedStatement pstmt = con.prepareStatement(INSERT_MESSAGE); 496 pstmt.setInt(1, id); 497 pstmt.setInt(2, threadID); 498 pstmt.setString(3, Long.toString(creationDate.getTime())); 499 pstmt.setString(4, Long.toString(modifiedDate.getTime())); 500 pstmt.setInt(5, userID); 501 pstmt.setString(6, subject); 502 pstmt.setString(7, body); 503 pstmt.setInt(8, approved?1:0 ); 504 pstmt.executeUpdate(); 505 pstmt.close(); 506 507 saveProperties(); 510 511 ForumEvent event = new ForumEvent(this); 512 for (int i = 0; i < listeners.size(); i++) { 513 ((ForumListener) listeners.get(i)).objectCreated(event); 514 } 515 516 517 isReadyToSave = true; 520 } 521 522 525 private synchronized void saveToDb() { 526 Connection con = null; 527 PreparedStatement pstmt = null; 528 try { 529 con = DbConnectionManager.getConnection(); 530 pstmt = con.prepareStatement(SAVE_MESSAGE); 531 pstmt.setInt(1, userID); 532 pstmt.setString(2, subject); 533 pstmt.setString(3, body); 534 pstmt.setString(4, Long.toString(creationDate.getTime())); 535 pstmt.setString(5, Long.toString(modifiedDate.getTime())); 536 pstmt.setInt(6, approved?1:0); 537 pstmt.setInt(7, id); 538 pstmt.executeUpdate(); 539 540 541 ForumEvent event = new ForumEvent(this); 542 for (int i = 0; i < listeners.size(); i++) { 543 ((ForumListener) listeners.get(i)).objectModified(event); 544 } 545 546 547 } catch (SQLException sqle) { 548 log.error("SQLException in DbForumMessage:saveToDb()- " + sqle); 549 550 } finally { 551 try { 552 pstmt.close(); 553 } catch (Exception e) { 554 log.error("",e); 555 } 556 try { 557 con.close(); 558 } catch (Exception e) { 559 log.error("",e); 560 } 561 } 562 } 563 564 565 566 private static Vector listeners = new Vector (); 568 569 public static void addListener(ForumListener listener) { 570 listeners.add(listener); 571 } 572 573 public static void removeListener(ForumListener listener) { 574 listeners.remove(listener); 575 } 576 } 577 | Popular Tags |