Changeset 585
- Timestamp:
- 12/30/09 17:21:21 (2 years ago)
- Location:
- trunk
- Files:
-
- 12 edited
-
LogicMail/src/org/logicprobe/LogicMail/mail/AbstractMailStore.java (modified) (3 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/mail/FolderListener.java (modified) (1 diff)
-
LogicMail/src/org/logicprobe/LogicMail/mail/LocalMailStore.java (modified) (1 diff)
-
LogicMail/src/org/logicprobe/LogicMail/mail/NetworkMailStore.java (modified) (1 diff)
-
LogicMail/src/org/logicprobe/LogicMail/model/AccountNode.java (modified) (5 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/model/MailFileManager.java (modified) (8 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/model/MailboxNode.java (modified) (5 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/model/MailboxNodeEvent.java (modified) (1 diff)
-
LogicMail/src/org/logicprobe/LogicMail/model/MessageNode.java (modified) (3 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/ui/MailboxMessageField.java (modified) (1 diff)
-
LogicMail/src/org/logicprobe/LogicMail/ui/MailboxScreen.java (modified) (3 diffs)
-
LogicMailTests/src/org/logicprobe/LogicMail/mail/NetworkMailStoreTest.java (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/AbstractMailStore.java
r582 r585 141 141 * 142 142 * <p>Successful completion is indicated by a call to 143 * {@link FolderListener#folder StatusChanged(FolderEvent)}.143 * {@link FolderListener#folderExpunged(FolderEvent)}. 144 144 * 145 145 * @param folder The folder to expunge … … 420 420 /** 421 421 * Notifies all registered <tt>FolderListener</tt>s that 422 * the thestatus of a folder has changed.422 * the status of a folder has changed. 423 423 * 424 424 * @param root The root node of the updated folder tree … … 451 451 } 452 452 ((FolderListener)listeners[i]).folderMessagesAvailable(e); 453 } 454 } 455 456 /** 457 * Notifies all registered <tt>FolderListener</tt>s that 458 * the folder has been expunged. 459 * 460 * @param root The root node of the updated folder tree 461 */ 462 protected void fireFolderExpunged(FolderTreeItem root) { 463 Object[] listeners = listenerList.getListeners(FolderListener.class); 464 FolderEvent e = null; 465 for(int i=0; i<listeners.length; i++) { 466 if(e == null) { 467 e = new FolderEvent(this, root); 468 } 469 ((FolderListener)listeners[i]).folderExpunged(e); 453 470 } 454 471 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/FolderListener.java
r220 r585 51 51 */ 52 52 public void folderMessagesAvailable(FolderMessagesEvent e); 53 54 /** 55 * Invoked when a folder has been expunged. 56 * 57 * @param e Folder event data 58 */ 59 public void folderExpunged(FolderEvent e); 53 60 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/LocalMailStore.java
r582 r585 148 148 149 149 if(folderMessages != null) { 150 fireFolder StatusChanged(requestFolder);150 fireFolderExpunged(requestFolder); 151 151 } 152 152 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/NetworkMailStore.java
r582 r585 195 195 break; 196 196 case IncomingMailConnectionHandler.REQUEST_FOLDER_EXPUNGE: 197 fireFolder StatusChanged((FolderTreeItem)result);197 fireFolderExpunged((FolderTreeItem)result); 198 198 break; 199 199 case IncomingMailConnectionHandler.REQUEST_FOLDER_STATUS: -
trunk/LogicMail/src/org/logicprobe/LogicMail/model/AccountNode.java
r582 r585 136 136 mailStore_FolderMessagesAvailable(e); 137 137 } 138 139 public void folderExpunged(FolderEvent e) { 140 mailStore_FolderExpunged(e); 141 } 138 142 }); 139 143 … … 603 607 // information, such as POP message indices 604 608 messageNode.getMessageToken().updateToken(folderMessages[i].getMessageToken()); 609 messageNode.setExistsOnServer(true); 605 610 } 606 611 else { … … 621 626 622 627 for (int i = 0; i < folderMessages.length; i++) { 623 addedMessages.addElement(new MessageNode(folderMessages[i])); 628 MessageNode messageNode = new MessageNode(folderMessages[i]); 629 messageNode.setExistsOnServer(true); 630 addedMessages.addElement(messageNode); 624 631 } 625 632 … … 631 638 else { 632 639 synchronized(folderMessagesToFetch) { 633 Vector messagesToFetch = (Vector)folderMessagesToFetch.remove(e.getFolder()); 640 FolderTreeItem fetchFolder = e.getFolder(); 641 642 // Clean out all messages that couldn't be verified against the server 643 MailboxNode mailboxNode = (MailboxNode) pathMailboxMap.get(fetchFolder.getPath()); 644 mailboxNode.removeMessagesNotOnServer(); 645 646 // Queue a fetch for messages that do exist 647 Vector messagesToFetch = (Vector)folderMessagesToFetch.remove(fetchFolder); 634 648 if(messagesToFetch != null) { 635 649 MessageToken[] fetchArray = new MessageToken[messagesToFetch.size()]; … … 639 653 } 640 654 } 655 } 656 657 /** 658 * Handles a folder being expunged. 659 * 660 * @param e Event data. 661 */ 662 private void mailStore_FolderExpunged(FolderEvent e) { 663 FolderTreeItem fetchFolder = e.getFolder(); 664 MailboxNode mailboxNode = (MailboxNode) pathMailboxMap.get(fetchFolder.getPath()); 665 mailboxNode.handleExpungeNotification(); 641 666 } 642 667 -
trunk/LogicMail/src/org/logicprobe/LogicMail/model/MailFileManager.java
r568 r585 94 94 * Refreshes the configuration based on any system configuration changes. 95 95 */ 96 void refreshConfiguration() {96 synchronized void refreshConfiguration() { 97 97 String localDataLocation = mailSettings.getGlobalConfig().getLocalDataLocation(); 98 98 String newCacheUrl = localDataLocation + CACHE_PREFIX; … … 131 131 * @throws IOException Signals that an I/O exception has occurred. 132 132 */ 133 public void writeMessage(MessageNode messageNode) throws IOException {133 public synchronized void writeMessage(MessageNode messageNode) throws IOException { 134 134 if(cacheUrl == null) { return; } 135 135 … … 171 171 * @throws IOException Signals that an I/O exception has occurred. 172 172 */ 173 public MessageToken[] readMessageTokens(MailboxNode mailboxNode) throws IOException {173 public synchronized MessageToken[] readMessageTokens(MailboxNode mailboxNode) throws IOException { 174 174 if(cacheUrl == null) { return new MessageToken[0]; } 175 175 … … 192 192 } 193 193 194 public MessageNode[] readMessageNodes(MailboxNode mailboxNode) throws IOException {194 public synchronized MessageNode[] readMessageNodes(MailboxNode mailboxNode) throws IOException { 195 195 if(cacheUrl == null) { return new MessageNode[0]; } 196 196 … … 210 210 } 211 211 212 public void readMessageNodes(MailboxNode mailboxNode, MessageNodeCallback callback) throws IOException {212 public synchronized void readMessageNodes(MailboxNode mailboxNode, MessageNodeCallback callback) throws IOException { 213 213 if(cacheUrl == null) { callback.messageNodeUpdated(null); } 214 214 … … 250 250 } 251 251 252 public MessageNode readMessageNode(MailboxNode mailboxNode, MessageToken messageToken, boolean loadContent) throws IOException {252 public synchronized MessageNode readMessageNode(MailboxNode mailboxNode, MessageToken messageToken, boolean loadContent) throws IOException { 253 253 if(cacheUrl == null) { return null; } 254 254 … … 270 270 } 271 271 272 public MimeMessageContent[] readMessageContent(MailboxNode mailboxNode, MessageToken messageToken) throws IOException {272 public synchronized MimeMessageContent[] readMessageContent(MailboxNode mailboxNode, MessageToken messageToken) throws IOException { 273 273 if(cacheUrl == null) { return null; } 274 274 … … 391 391 return result; 392 392 } 393 394 public synchronized void removeMessageNodes(MailboxNode mailboxNode, MessageToken[] messageTokens) throws IOException { 395 if(cacheUrl == null) { return; } 396 397 FileConnection fileConnection = getMailboxFileConnection(mailboxNode); 398 String mailboxUrl = fileConnection.getURL(); 399 fileConnection.close(); 400 401 for(int i=0; i<messageTokens.length; i++) { 402 try { 403 FileConnection mailFileConnection = 404 (FileConnection)Connector.open(mailboxUrl + messageTokens[i].getMessageUid() + MSG_SUFFIX); 405 if(mailFileConnection.exists() && !mailFileConnection.isDirectory() && mailFileConnection.canRead()) { 406 mailFileConnection.delete(); 407 } 408 mailFileConnection.close(); 409 } catch (IOException exp) { 410 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 411 EventLogger.logEvent(AppInfo.GUID, 412 ("Error deleting message from cache: " + exp.toString()).getBytes(), 413 EventLogger.DEBUG_INFO); 414 } 415 } 416 } 417 } 393 418 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/model/MailboxNode.java
r582 r585 34 34 import java.io.DataOutput; 35 35 import java.io.IOException; 36 import java.util.Enumeration; 36 37 import java.util.Hashtable; 37 38 import java.util.Vector; … … 72 73 private boolean hasAppend; 73 74 private int unseenMessageCount; 75 private Vector pendingExpungeMessages = new Vector(); 74 76 75 77 private Object fetchLock = new Object(); … … 540 542 } 541 543 updateUnseenMessages(false); 542 fireMailboxStatusChanged(MailboxNodeEvent.TYPE_STATUS, null); 543 } 544 544 fireMailboxStatusChanged(MailboxNodeEvent.TYPE_DELETED_MESSAGES, new MessageNode[] { message }); 545 } 546 547 548 /** 549 * Removes all messages not marked as existing on the server. 550 */ 551 void removeMessagesNotOnServer() { 552 synchronized(messages) { 553 Vector messagesToRemove = new Vector(); 554 555 // Populate a list of the messages to remove 556 int size = messages.size(); 557 for(int i=0; i<size; i++) { 558 MessageNode messageNode = (MessageNode)messages.elementAt(i); 559 if(!messageNode.existsOnServer()) { 560 messagesToRemove.addElement(messageNode); 561 } 562 } 563 564 size = messagesToRemove.size(); 565 if(size == 0) { return; } 566 567 MessageNode[] removedMessageNodes = new MessageNode[size]; 568 MessageToken[] tokensToRemove = new MessageToken[size]; 569 for(int i=0; i<size; i++) { 570 MessageNode messageNode = (MessageNode)messagesToRemove.elementAt(i); 571 messages.removeElement(messageNode); 572 messageNode.setParent(null); 573 messageMap.remove(messageNode); 574 messageTokenMap.remove(messageNode.getMessageToken()); 575 tokensToRemove[i] = messageNode.getMessageToken(); 576 removedMessageNodes[i] = messageNode; 577 } 578 579 (new RemoveFromCacheThread(tokensToRemove)).start(); 580 updateUnseenMessages(false); 581 fireMailboxStatusChanged(MailboxNodeEvent.TYPE_DELETED_MESSAGES, removedMessageNodes); 582 } 583 } 584 585 private class RemoveFromCacheThread extends Thread { 586 private MessageToken[] messageTokens; 587 588 public RemoveFromCacheThread(MessageToken[] messageTokens) { 589 this.messageTokens = messageTokens; 590 } 591 592 public void run() { 593 yield(); 594 try { 595 MailFileManager.getInstance().removeMessageNodes(MailboxNode.this, messageTokens); 596 } catch (IOException e) { 597 EventLogger.logEvent(AppInfo.GUID, 598 ("Unable to remove messages from the cache\r\n" 599 + e.getMessage()).getBytes(), 600 EventLogger.ERROR); 601 } 602 } 603 } 604 605 /** 606 * Called when the mail store notifies of a completed expunge operation on 607 * this folder, so anything we expected to be expunged can be cleaned out. 608 */ 609 void handleExpungeNotification() { 610 synchronized(messages) { 611 Enumeration e = pendingExpungeMessages.elements(); 612 while(e.hasMoreElements()) { 613 ((MessageNode)e.nextElement()).setExistsOnServer(false); 614 } 615 pendingExpungeMessages.removeAllElements(); 616 removeMessagesNotOnServer(); 617 } 618 } 619 545 620 /** 546 621 * Removes all messages from this mailbox. … … 710 785 return hasDeleted; 711 786 } 712 787 713 788 /** 714 789 * Tells the underlying mail store to expunge any deleted messages … … 716 791 */ 717 792 public void expungeDeletedMessages() { 793 synchronized(messages) { 794 int size = messages.size(); 795 for(int i=0; i<size; i++) { 796 MessageNode messageNode = (MessageNode)messages.elementAt(i); 797 int flags = messageNode.getFlags(); 798 if((flags & MessageNode.Flag.DELETED) != 0) { 799 pendingExpungeMessages.addElement(messageNode); 800 } 801 } 802 } 718 803 parentAccount.getMailStore().requestFolderExpunge(this.folderTreeItem); 719 804 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/model/MailboxNodeEvent.java
r232 r585 53 53 public final static int TYPE_NEW_MESSAGES = 1; 54 54 55 /** 56 * Messages have been deleted. 57 * The <tt>getAffectedMessages()</tt> method will return 58 * a list of deleted messages. 59 */ 60 public final static int TYPE_DELETED_MESSAGES = 2; 61 55 62 /** Creates a new instance of MailboxNodeEvent */ 56 63 public MailboxNodeEvent(Object source, int type, MessageNode[] affectedMessages) { -
trunk/LogicMail/src/org/logicprobe/LogicMail/model/MessageNode.java
r579 r585 130 130 /** True if the message has cached content available for loading */ 131 131 private boolean hasCachedContent; 132 /** True if the message has been verified to exist on a mail server */ 133 private boolean existsOnServer; 132 134 /** Bit-field set of message flags. */ 133 135 private int flags; … … 287 289 } 288 290 291 /** 292 * Sets whether this message has been verified to exist on a server. 293 * 294 * @param existsOnServer true if the message has been verified to exist on a server 295 */ 296 void setExistsOnServer(boolean existsOnServer) { 297 this.existsOnServer = existsOnServer; 298 } 299 300 /** 301 * Gets whether this message has been verified to exist on a server. 302 * 303 * @return true if the message has been verified to exist on a server or is on a local account 304 */ 305 public boolean existsOnServer() { 306 return existsOnServer; 307 } 308 289 309 /* (non-Javadoc) 290 310 * @see org.logicprobe.LogicMail.model.Node#accept(org.logicprobe.LogicMail.model.NodeVisitor) … … 301 321 void setParent(MailboxNode parent) { 302 322 this.parent = parent; 323 if(!isCachable()) { existsOnServer = true; } 303 324 } 304 325 -
trunk/LogicMail/src/org/logicprobe/LogicMail/ui/MailboxMessageField.java
r576 r585 155 155 // Draw the message icon 156 156 Bitmap messageIcon = NodeIcons.getIcon(messageNode); 157 int iconY = (lineHeight / 2) - (messageIcon.getHeight() / 2); 157 158 graphics.drawBitmap( 158 159 1, 159 (lineHeight / 2) - (messageIcon.getHeight() / 2),160 iconY, 160 161 messageIcon.getWidth(), 161 162 messageIcon.getHeight(), 162 163 messageIcon, 0, 0); 164 if(!messageNode.existsOnServer()) { 165 graphics.setColor(Color.DARKGRAY); 166 graphics.drawRect(1, iconY, messageIcon.getWidth(), messageIcon.getHeight()); 167 graphics.setColor(originalColor); 168 } 163 169 164 170 if(attachmentIcon != null) { -
trunk/LogicMail/src/org/logicprobe/LogicMail/ui/MailboxScreen.java
r582 r585 323 323 */ 324 324 private void mailboxNode_MailboxStatusChanged(MailboxNodeEvent e) { 325 if(e.getType() == MailboxNodeEvent.TYPE_NEW_MESSAGES) { 325 int type = e.getType(); 326 if(type == MailboxNodeEvent.TYPE_NEW_MESSAGES) { 326 327 MessageNode[] messageNodes = e.getAffectedMessages(); 327 328 for(int i=0; i<messageNodes.length; i++) { … … 337 338 } 338 339 } 340 } 341 else if(type == MailboxNodeEvent.TYPE_DELETED_MESSAGES) { 342 MessageNode[] messageNodes = e.getAffectedMessages(); 343 for(int i=0; i<messageNodes.length; i++) { 344 if(screen != null && screen.isDisplayed()) { 345 messageNodes[i].removeMessageNodeListener(messageNodeListener); 346 } 347 removeDisplayableMessage(messageNodes[i]) ; 348 knownMessages.removeElement(messageNodes[i]); 349 } 339 350 } 340 351 } … … 407 418 } 408 419 420 /** 421 * Remove a message from the list and associated data structures, 422 * if that message exists in the list. 423 * 424 * @param messageNode Message to insert. 425 */ 426 private void removeDisplayableMessage(MessageNode messageNode) { 427 MailboxMessageField mailboxMessageField = (MailboxMessageField)messageFieldMap.remove(messageNode); 428 if(mailboxMessageField == null) { return; } 429 430 messageFieldManager.delete(mailboxMessageField); 431 } 432 409 433 /** 410 434 * Gets the last displayed message. -
trunk/LogicMailTests/src/org/logicprobe/LogicMail/mail/NetworkMailStoreTest.java
r584 r585 96 96 eventFolderStatusChanged = e; 97 97 } 98 public void folderExpunged(FolderEvent e) { 99 } 98 100 }); 99 101
Note: See TracChangeset
for help on using the changeset viewer.
