1 package net.suberic.pooka; 2 3 import javax.mail.*; 4 import javax.mail.event.*; 5 import javax.mail.search.*; 6 import javax.swing.event.EventListenerList ; 7 import java.util.*; 8 import java.util.logging.*; 9 import javax.swing.AbstractAction ; 10 import javax.swing.Action ; 11 import java.awt.event.ActionEvent ; 12 import net.suberic.pooka.gui.*; 13 import net.suberic.pooka.thread.*; 14 import net.suberic.pooka.event.*; 15 import net.suberic.util.ValueChangeListener; 16 import net.suberic.util.thread.ActionThread; 17 18 23 24 public class FolderInfo implements MessageCountListener, ValueChangeListener, UserProfileContainer, MessageChangedListener, ConnectionListener { 25 26 Logger mLogger = null; 28 29 public static int CONNECTED = 0; 31 32 public static int LOST_CONNECTION = 5; 35 36 39 public static int PASSIVE = 10; 40 41 public static int DISCONNECTED = 15; 44 45 public static int CACHE_ONLY = 18; 47 48 public static int CLOSED = 20; 50 51 public static int NOT_LOADED = 25; 53 54 public static int INVALID = 30; 56 57 protected int status = NOT_LOADED; 59 60 protected int type = 0; 62 63 protected int preferredStatus = CONNECTED; 66 67 protected static String disconnectedMessage = "error.Folder.disconnected"; 69 70 private Folder folder; 72 73 private String folderID; 75 76 private String mFolderName; 78 79 private EventListenerList eventListeners = new EventListenerList (); 80 81 protected FolderNode folderNode; 83 protected Vector children; 84 85 protected FolderTableModel folderTableModel; 87 protected Hashtable messageToInfoTable = new Hashtable(); 88 private List columnValues; 89 private List <String > columnNames; 90 private List <String > columnSizes; 91 private List <String > columnIds; 92 93 private FolderDisplayUI folderDisplayUI; 95 private Action [] defaultActions; 96 97 protected BackendMessageFilter[] backendFilters = null; 99 protected MessageFilter[] displayFilters = null; 100 101 protected MessageLoader mMessageLoader = null; 103 private FolderTracker folderTracker = null; 104 105 protected boolean loading = false; 106 protected int unreadCount = 0; 107 protected int messageCount = 0; 108 private boolean newMessages = false; 109 110 private FolderInfo parentFolder = null; 111 private StoreInfo parentStore = null; 112 private UserProfile defaultProfile = null; 113 114 private boolean sentFolder = false; 115 private boolean trashFolder = false; 116 117 private boolean notifyNewMessagesMain = true; 118 private boolean notifyNewMessagesNode = true; 119 private boolean tracksUnreadMessages = true; 120 121 protected FetchProfile fetchProfile = null; 122 123 protected OutgoingMailServer mailServer = null; 124 125 protected boolean mNamespace = false; 127 128 131 134 protected FolderInfo() { 135 } 136 137 141 142 public FolderInfo(FolderInfo parent, String fname) { 143 parentFolder = parent; 144 setFolderID(parent.getFolderID() + "." + fname); 145 mFolderName = fname; 146 147 try { 148 if (parent.isLoaded()) 149 loadFolder(); 150 } catch (MessagingException me) { 151 if (getLogger().isLoggable(Level.FINE)) { 154 getLogger().log(Level.FINE, Thread.currentThread() + "loading folder " + getFolderID() + ": caught messaging exception from parentStore getting folder: " + me); 155 me.printStackTrace(); 156 157 } 158 } 159 160 updateChildren(); 161 162 createFilters(); 163 164 resetDefaultActions(); 165 166 if (!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesMain", "").equalsIgnoreCase("false")) 167 setNotifyNewMessagesMain(true); 168 else 169 setNotifyNewMessagesMain(false); 170 171 if (!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesNode", "").equalsIgnoreCase("false")) { 172 setNotifyNewMessagesNode(true); 173 } else { 174 setNotifyNewMessagesNode(false); 175 } 176 } 177 178 179 180 184 185 public FolderInfo(StoreInfo parent, String fname) { 186 parentStore = parent; 187 setFolderID(parent.getStoreID() + "." + fname); 188 mFolderName = fname; 189 190 mNamespace = Pooka.getProperty(getFolderID() + "._namespace", "false").equalsIgnoreCase("true"); 191 192 try { 193 if (parent.isConnected()) 194 loadFolder(); 195 } catch (MessagingException me) { 196 if (getLogger().isLoggable(Level.FINE)) { 199 getLogger().log(Level.FINE, Thread.currentThread() + "loading folder " + getFolderID() + ": caught messaging exception from parentStore getting folder: " + me); 200 me.printStackTrace(); 201 202 } 203 } 204 205 updateChildren(); 206 207 createFilters(); 208 209 resetDefaultActions(); 210 211 if (!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesMain", "").equalsIgnoreCase("false")) 212 setNotifyNewMessagesMain(true); 213 else 214 setNotifyNewMessagesMain(false); 215 216 if (!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesNode", "").equalsIgnoreCase("false")) 217 setNotifyNewMessagesNode(true); 218 else 219 setNotifyNewMessagesNode(false); 220 } 221 222 232 public void loadFolder() throws MessagingException { 233 loadFolder(true); 234 } 235 236 246 public void loadFolder(boolean pConnectStore) throws MessagingException { 247 boolean parentIsConnected = false; 248 249 if (isLoaded() || (loading && children == null)) 250 return; 251 252 Folder[] tmpFolder = null; 253 Folder tmpParentFolder; 254 255 try { 256 loading = true; 257 258 if (parentStore != null) { 259 getLogger().log(Level.FINE, Thread.currentThread() + "loading folder " + getFolderID() + ": checking parent store connection."); 260 261 if (! parentStore.isAvailable()) 262 throw new MessagingException(); 263 264 if (!parentStore.isConnected()) { 265 if (pConnectStore) { 266 parentStore.connectStore(); 267 } else { 268 return; 269 } 270 } 271 272 273 Store store = parentStore.getStore(); 274 275 try { 277 getLogger().log(Level.FINE, "checking to see if " + getFolderID() + " is a shared folder."); 278 279 Folder[] sharedFolders = store.getSharedNamespaces(); 280 281 if (sharedFolders != null && sharedFolders.length > 0) { 282 for (int i = 0; ( tmpFolder == null || tmpFolder.length == 0 ) && i < sharedFolders.length; i++) { 283 if (sharedFolders[i].getName().equalsIgnoreCase(mFolderName)) { 284 if (!mNamespace) { 285 Pooka.setProperty(getFolderID() + "._namespace", "true"); 286 mNamespace = true; 287 } 288 tmpFolder = new Folder[1]; 289 tmpFolder[0] = sharedFolders[i] ; 290 } 291 } 292 } 293 } catch (Exception e) { 294 } 297 298 if (tmpFolder == null || tmpFolder.length == 0) { 299 tmpParentFolder = store.getDefaultFolder(); 301 getLogger().log(Level.FINE, "got " + tmpParentFolder + " as Default Folder for store."); 302 getLogger().log(Level.FINE, "doing a list on default folder " + tmpParentFolder + " for folder " + mFolderName); 303 tmpFolder = tmpParentFolder.list(mFolderName); 304 } 305 306 getLogger().log(Level.FINE, "got " + tmpFolder + " as Folder for folder " + getFolderID() + "."); 307 308 } else { 309 if (!parentFolder.isLoaded()) 310 parentFolder.loadFolder(); 311 if (!parentFolder.isLoaded()) { 312 tmpFolder = null; 313 } else { 314 tmpParentFolder = parentFolder.getFolder(); 315 if (tmpParentFolder != null) { 316 parentIsConnected = true; 317 getLogger().log(Level.FINE, "running list (" + mFolderName + ") on parent folder " + tmpParentFolder); 318 tmpFolder = tmpParentFolder.list(mFolderName); 319 } else { 320 tmpFolder = null; 321 } 322 } 323 } 324 325 if (tmpFolder != null && tmpFolder.length > 0) { 326 setFolder(tmpFolder[0]); 327 if (! getFolder().isSubscribed()) 328 getFolder().setSubscribed(true); 329 330 type = getFolder().getType(); 331 setStatus(CLOSED); 332 } else { 333 getLogger().log(Level.FINE, "folder " + mFolderName + " does not exist; setting as INVALID."); 334 if (parentIsConnected) 335 setStatus(INVALID); 336 setFolder(null); 337 } 338 339 340 346 347 348 } finally { 349 loading = false; 350 } 351 352 initializeFolderInfo(); 353 354 } 355 356 359 protected void addFolderListeners() { 360 if (folder != null) { 361 folder.addMessageChangedListener(this); 362 folder.addMessageCountListener(this); 363 folder.addConnectionListener(this); 364 } 365 } 366 367 370 protected void removeFolderListeners() { 371 if (folder != null) { 372 folder.removeMessageChangedListener(this); 373 folder.removeMessageCountListener(this); 374 folder.removeConnectionListener(this); 375 } 376 } 377 378 382 protected void initializeFolderInfo() { 383 addFolderListeners(); 384 385 Pooka.getResources().addValueChangeListener(this, getFolderProperty()); 386 Pooka.getResources().addValueChangeListener(this, getFolderProperty() + ".folderList"); 387 Pooka.getResources().addValueChangeListener(this, getFolderProperty() + ".defaultProfile"); 388 Pooka.getResources().addValueChangeListener(this, getFolderProperty() + ".displayFilters"); 389 Pooka.getResources().addValueChangeListener(this, getFolderProperty() + ".backendFilters"); 390 Pooka.getResources().addValueChangeListener(this, getFolderProperty() + ".notifyNewMessagesMain"); 391 Pooka.getResources().addValueChangeListener(this, getFolderProperty() + ".notifyNewMessagesNode"); 392 393 Pooka.getLogManager().addLogger(getFolderProperty()); 394 395 String defProfile = Pooka.getProperty(getFolderProperty() + ".defaultProfile", ""); 396 if ((!defProfile.equals("")) && (!defProfile.equals(UserProfile.S_DEFAULT_PROFILE_KEY))) 397 defaultProfile = Pooka.getPookaManager().getUserProfileManager().getProfile(defProfile); 398 399 401 if (getFolderTracker() == null) { 402 FolderTracker tracker = Pooka.getFolderTracker(); 403 if (tracker != null) { 404 tracker.addFolder(this); 405 this.setFolderTracker(tracker); 406 } else { 407 if (Pooka.sStartupManager.isShuttingDown()) { 408 getLogger().fine("No FolderTracker available."); 409 } else { 410 getLogger().warning("Error: No FolderTracker available for folder " + getFolderID()); 411 } 412 } 413 } 414 } 415 416 public void closed(ConnectionEvent e) { 417 418 synchronized(this) { 419 420 getLogger().log(Level.FINE, "Folder " + getFolderID() + " closed: " + e); 421 if (getStatus() != CLOSED && getStatus() != DISCONNECTED) { 423 424 getFolderThread().addToQueue(new javax.swing.AbstractAction () { 425 public void actionPerformed(java.awt.event.ActionEvent e) { 426 428 StoreInfo parentStoreInfo = getParentStore(); 429 if (parentStoreInfo != null) { 430 if (parentStoreInfo.isConnected()) 431 parentStoreInfo.checkConnection(); 432 } 433 } 434 }, new java.awt.event.ActionEvent (this, 0, "folder-closed"), ActionThread.PRIORITY_HIGH); 435 436 if (getFolderDisplayUI() != null) { 437 getFolderDisplayUI().showStatusMessage(Pooka.getProperty(disconnectedMessage, "Lost connection to folder...")); 438 } 439 440 if (status == CONNECTED) { 441 setStatus(LOST_CONNECTION); 442 } 443 } 444 445 } 446 fireConnectionEvent(e); 447 448 } 449 450 public void disconnected(ConnectionEvent e) { 451 synchronized(this) { 452 if (getLogger().isLoggable(Level.FINE)) { 453 getLogger().log(Level.FINE, "Folder " + getFolderID() + " disconnected."); 454 Thread.dumpStack(); 455 } 456 457 if (getStatus() != CLOSED) { 459 getFolderThread().addToQueue(new javax.swing.AbstractAction () { 460 public void actionPerformed(java.awt.event.ActionEvent e) { 461 463 StoreInfo parentStoreInfo = getParentStore(); 464 if (parentStoreInfo != null && parentStoreInfo.isConnected()) { 465 parentStoreInfo.checkConnection(); 466 } 467 } 468 }, new java.awt.event.ActionEvent (this, 0, "folder-closed"), ActionThread.PRIORITY_HIGH); 469 470 if (getFolderDisplayUI() != null) { 471 getFolderDisplayUI().showStatusMessage(Pooka.getProperty("error.UIDFolder.disconnected", "Lost connection to folder...")); 472 } 473 474 if (status == CONNECTED) { 475 setStatus(LOST_CONNECTION); 476 } 477 } 478 479 } 480 481 fireConnectionEvent(e); 482 } 483 484 485 490 public void opened (ConnectionEvent e) { 491 fireConnectionEvent(e); 492 } 493 494 499 public void connected (ConnectionEvent e) { 500 fireConnectionEvent(e); 501 } 502 503 513 public void openFolder(int mode) throws MessagingException { 514 openFolder(mode, true); 515 } 516 517 527 public void openFolder(int mode, boolean pConnectStore) throws MessagingException { 528 531 getLogger().log(Level.FINE, this + ": checking parent store."); 532 533 if (!getParentStore().isConnected() && pConnectStore) { 534 getLogger().log(Level.FINE, this + ": parent store isn't connected. trying connection."); 535 getParentStore().connectStore(); 536 } 537 538 getLogger().log(Level.FINE, this + ": loading folder."); 539 540 if (! isLoaded() && status != CACHE_ONLY) 541 loadFolder(pConnectStore); 542 543 getLogger().log(Level.FINE, this + ": folder loaded. status is " + status); 544 545 getLogger().log(Level.FINE, this + ": checked on parent store. trying isLoaded() and isAvailable()."); 546 547 if (status == CLOSED || status == LOST_CONNECTION || status == DISCONNECTED) { 548 getLogger().log(Level.FINE, this + ": isLoaded() and isAvailable()."); 549 if (folder.isOpen()) { 550 if (folder.getMode() == mode) 551 return; 552 else { 553 folder.close(false); 554 openFolder(mode); 555 updateFolderOpenStatus(true); 556 resetMessageCounts(); 557 } 558 } else { 559 folder.open(mode); 560 updateFolderOpenStatus(true); 561 resetMessageCounts(); 562 } 563 } else if (status == INVALID) { 564 throw new MessagingException(Pooka.getProperty("error.folderInvalid", "Error: folder is invalid. ") + getFolderID()); 565 } 566 567 569 } 570 571 576 protected void updateFolderOpenStatus(boolean isNowOpen) { 577 if (isNowOpen) { 578 setStatus(CONNECTED); 579 } else { 580 setStatus(CLOSED); 581 } 582 } 583 584 592 593 public void openAllFolders(int mode) { 594 try { 595 openFolder(mode, false); 596 } catch (MessagingException me) { 597 } 598 599 if (children != null) { 600 for (int i = 0; i < children.size(); i++) { 601 doOpenFolders((FolderInfo) children.elementAt(i), mode); 602 } 603 } 604 } 605 606 609 private void doOpenFolders(FolderInfo fi, int mode) { 610 if (Pooka.getProperty("Pooka.openFoldersInBackground", "false").equalsIgnoreCase("true")) { 611 final FolderInfo current = fi; 612 final int finalMode = mode; 613 614 javax.swing.AbstractAction openFoldersAction =new javax.swing.AbstractAction () { 615 public void actionPerformed(java.awt.event.ActionEvent e) { 616 current.openAllFolders(finalMode); 617 } 618 }; 619 620 openFoldersAction.putValue(javax.swing.Action.NAME, "file-open"); 621 openFoldersAction.putValue(javax.swing.Action.SHORT_DESCRIPTION, "file-open on folder " + fi.getFolderID()); 622 getFolderThread().addToQueue(openFoldersAction, new java.awt.event.ActionEvent (this, 0, "open-all"), ActionThread.PRIORITY_LOW); 623 } else { 624 fi.openAllFolders(mode); 625 } 626 } 627 628 634 public void closeFolder(boolean expunge, boolean closeDisplay) throws MessagingException { 635 636 if (closeDisplay) { 637 unloadAllMessages(); 638 639 if (getFolderDisplayUI() != null) 640 getFolderDisplayUI().closeFolderDisplay(); 641 642 setFolderDisplayUI(null); 643 } 644 645 if (getFolderTracker() != null) { 646 getFolderTracker().removeFolder(this); 647 setFolderTracker(null); 648 } 649 650 if (isLoaded() && isValid()) { 651 setStatus(CLOSED); 652 try { 653 folder.close(expunge); 654 } catch (java.lang.IllegalStateException ise) { 655 throw new MessagingException(ise.getMessage(), ise); 656 } 657 } 658 659 } 660 661 public void closeFolder(boolean expunge) throws MessagingException { 662 closeFolder(expunge, true); 663 } 664 665 668 public void closeAllFolders(boolean expunge, boolean shuttingDown) throws MessagingException { 669 674 675 if (shuttingDown && mMessageLoader != null) { 676 mMessageLoader.stopLoading(); 677 } 678 679 synchronized(getFolderThread().getRunLock()) { 680 MessagingException otherException = null; 681 Vector folders = getChildren(); 682 if (folders != null) { 683 for (int i = 0; i < folders.size(); i++) { 684 try { 685 ((FolderInfo) folders.elementAt(i)).closeAllFolders(expunge, shuttingDown); 686 } catch (MessagingException me) { 687 if (otherException == null) 688 otherException = me; 689 } catch (Exception e) { 690 MessagingException newMe = new MessagingException (e.getMessage(), e); 691 if (otherException == null) 692 otherException = newMe; 693 } 694 } 695 } 696 697 closeFolder(expunge, false); 698 699 if (otherException != null) 700 throw otherException; 701 } 702 } 703 704 709 public Vector getAllFolders() { 710 Vector returnValue = new Vector(); 711 if (children != null) { 712 for (int i = 0 ; i < children.size(); i++) 713 returnValue.addAll(((FolderInfo) children.elementAt(i)).getAllFolders()); 714 } 715 716 if (isSortaOpen() && (getType() & Folder.HOLDS_MESSAGES) != 0) 717 returnValue.add(this); 718 719 return returnValue; 720 } 721 722 726 public void synchSubscribed() throws MessagingException { 727 728 if (mNamespace) 730 return; 731 732 if (! isLoaded()) 734 loadFolder(); 735 736 if ((getType() & Folder.HOLDS_FOLDERS) != 0) { 737 738 Folder[] subscribedFolders = folder.list(); 739 740 StringBuffer newSubscribed = new StringBuffer (); 741 742 for (int i = 0; subscribedFolders != null && i < subscribedFolders.length; i++) { 743 if (subscribedFolders[i].isSubscribed() || subscribedFolders[i].getName().equalsIgnoreCase("INBOX")) { 745 String folderName = subscribedFolders[i].getName(); 746 newSubscribed.append(folderName).append(':'); 747 } 748 } 749 750 if (newSubscribed.length() > 0) 751 newSubscribed.deleteCharAt(newSubscribed.length() -1); 752 753 Pooka.setProperty(getFolderProperty() + ".folderList", newSubscribed.toString()); 755 756 for (int i = 0; children != null && i < children.size(); i++) { 757 FolderInfo fi = (FolderInfo) children.elementAt(i); 758 fi.synchSubscribed(); 759 } 760 } 761 } 762 763 766 protected FetchProfile createColumnInformation() { 767 String tableType; 768 769 if (isSentFolder()) 770 tableType="SentFolderTable"; 771 else if (isOutboxFolder()) 774 tableType="SentFolderTable"; 775 else 776 tableType="FolderTable"; 777 778 FetchProfile fp = new FetchProfile(); 779 fp.add(FetchProfile.Item.FLAGS); 780 if (columnValues == null) { 781 List <String > colIds = Pooka.getResources().getPropertyAsList(tableType, ""); 782 Vector colvals = new Vector(); 783 Vector<String > colnames = new Vector<String >(); 784 Vector<String > colsizes = new Vector<String >(); 785 786 for (String tmp: colIds) { 787 String type = Pooka.getProperty(tableType + "." + tmp + ".type", ""); 788 if (type.equalsIgnoreCase("Multi")) { 789 SearchTermIconManager stm = new SearchTermIconManager(tableType + "." + tmp); 790 colvals.addElement(stm); 791 Vector toFetch = Pooka.getResources().getPropertyAsVector(tableType + "." + tmp + ".profileItems", ""); 792 if (toFetch != null) { 793 for (int z = 0; z < toFetch.size(); z++) { 794 String profileDef = (String ) toFetch.elementAt(z); 795 if (profileDef.equalsIgnoreCase("Flags")) { 796 getLogger().log(Level.FINE, "adding FLAGS to FetchProfile."); 797 fp.add(FetchProfile.Item.FLAGS); 798 } else if (profileDef.equalsIgnoreCase("Envelope")) { 799 getLogger().log(Level.FINE, "adding ENVELOPE to FetchProfile."); 800 fp.add(FetchProfile.Item.ENVELOPE); 801 } else if (profileDef.equalsIgnoreCase("Content_Info")) { 802 getLogger().log(Level.FINE, "adding CONTENT_INFO to FetchProfile."); 803 fp.add(FetchProfile.Item.CONTENT_INFO); 804 } else { 805 getLogger().log(Level.FINE, "adding " + profileDef + " to FetchProfile."); 806 fp.add(profileDef); 807 } 808 } 809 } 810 } else if (type.equalsIgnoreCase("RowCounter")) { 811 colvals.addElement(RowCounter.getInstance()); 812 } else { 813 String value = Pooka.getProperty(tableType + "." + tmp + ".value", tmp); 814 colvals.addElement(value); 815 String fpValue = Pooka.getProperty(tableType + "." + tmp + ".profileItems", value); 816 fp.add(fpValue); 817 } 818 819 colnames.addElement(Pooka.getProperty(tableType + "." + tmp + ".label", tmp)); 820 String value = Pooka.getProperty(getFolderProperty() + ".columnsize." + tmp + ".value", Pooka.getProperty(tableType + "." + tmp + ".value", tmp)); 821 colsizes.addElement(Pooka.getProperty(getFolderProperty() + ".columnsize." + tmp + ".value", Pooka.getProperty(tableType + "." + tmp + ".size", tmp))); 822 } 823 setColumnNames(colnames); 824 setColumnValues(colvals); 825 setColumnSizes(colsizes); 826 setColumnIds(colIds); 827 } 828 829 if (filterHeaders != null) { 831 for (int i = 0; i < filterHeaders.size(); i++) { 832 fp.add((String ) filterHeaders.get(i)); 833 } 834 } 835 836 if (getLogger().isLoggable(Level.FINE)) { 837 getLogger().log(Level.FINE, "created fetch profile."); 838 String [] headers = fp.getHeaderNames(); 839 if (headers != null) { 840 for (int i = 0; i < headers.length; i++) { 841 getLogger().log(Level.FINE, "headers["+i+"]=" + headers[i]); 842 } 843 } 844 getLogger().log(Level.FINE, "headers done."); 845 } 846 847 return fp; 848 } 849 850 854 protected void updateDisplay(boolean start) { 855 if (getFolderDisplayUI() != null) { 856 if (start) { 857 getFolderDisplayUI().setBusy(true); 858 getFolderDisplayUI().showStatusMessage(Pooka.getProperty("messages.Folder.loading.starting", "Loading messages.")); 859 } else { 860 getFolderDisplayUI().setBusy(false); 861 getFolderDisplayUI().showStatusMessage(Pooka.getProperty("messages.Folder.loading.finished", "Done loading messages.")); 862 } 863 } 864 } 865 866 869 protected void updateFolderStatusForLoading() throws MessagingException { 870 if (! isConnected() ) { 871 openFolder(Folder.READ_WRITE); 872 } 873 } 874 875 878 protected void updateNode() { 879 if (getFolderNode() != null) 880 getFolderNode().updateNode(); 881 } 882 883 887 protected List createInfosAndProxies() throws MessagingException { 888 int fetchBatchSize = 50; 889 try { 890 fetchBatchSize = Integer.parseInt(Pooka.getProperty("Pooka.fetchBatchSize", "50")); 891 } catch (NumberFormatException nfe) { 892 } 893 894 Vector messageProxies = new Vector(); 895 896 Message[] msgs = folder.getMessages(); 897 898 Message[] toFetch = msgs; 899 900 if (msgs.length > fetchBatchSize) { 903 toFetch = new Message[fetchBatchSize]; 904 System.arraycopy(msgs, msgs.length - fetchBatchSize, toFetch, 0, fetchBatchSize); 905 } 906 907 folder.fetch(toFetch, fetchProfile); 908 909 int firstFetched = Math.max(msgs.length - fetchBatchSize, 0); 910 911 MessageInfo mi; 912 913 for (int i = 0; i < msgs.length; i++) { 914 mi = new MessageInfo(msgs[i], this); 915 916 if ( i >= firstFetched) 917 mi.setFetched(true); 918 919 messageProxies.add(new MessageProxy(getColumnValues() , mi)); 920 messageToInfoTable.put(msgs[i], mi); 921 } 922 923 return messageProxies; 924 } 925 926 929 public void runFilters(List proxies) throws MessagingException { 930 if (isConnected()) { 931 Folder current = getFolder(); 932 if (current != null && current.isOpen()) { 933 int newCount = current.getNewMessageCount(); 934 935 if (newCount > 0) { 936 int numProxies = proxies.size(); 937 List newProxies = new ArrayList(); 938 for (int i = 0; i < newCount; i++) { 939 newProxies.add(proxies.get((numProxies - newCount) + i)); 940 } 941 proxies.removeAll(applyFilters(newProxies)); 942 } 943 } 944 } 945 946 } 947 948 951 protected void updateCache() throws MessagingException { 952 } 954 955 961 public synchronized void loadAllMessages() throws MessagingException { 962 if (folderTableModel == null) { 963 updateDisplay(true); 964 965 if (! isLoaded()) 966 loadFolder(); 967 968 fetchProfile = createColumnInformation(); 969 970 974 if (mMessageLoader == null) 975 mMessageLoader = createMessageLoader(); 976 977 try { 978 updateFolderStatusForLoading(); 979 980 List messageProxies = createInfosAndProxies(); 981 982 runFilters(messageProxies); 983 984 FolderTableModel ftm = new FolderTableModel(messageProxies, getColumnNames(), getColumnSizes(), getColumnValues(), getColumnIds()); 985 986 setFolderTableModel(ftm); 987 988 updateCache(); 989 990 Vector loadImmediately = null; 991 992 int loadBatchSize = 25; 993 994 if (messageProxies.size() > loadBatchSize) { 995 int firstUnread = messageProxies.size(); 997 if (Pooka.getProperty("Pooka.autoSelectFirstUnread", "true").equalsIgnoreCase("true")) { 998 firstUnread = getFirstUnreadMessage(); 999 } 1000 1001 int lastLoaded = messageProxies.size() - 1; 1002 int firstLoaded = messageProxies.size() - loadBatchSize - 1; 1003 1004 if (firstUnread > -1) { 1005 if (firstUnread < firstLoaded) { 1006 firstLoaded = Math.max(0, firstUnread - 5); 1007 lastLoaded = firstLoaded + loadBatchSize; 1008 } 1009 } 1010 1011 loadImmediately = new Vector(); 1012 for (int i = lastLoaded; i >= firstLoaded; i--) { 1013 loadImmediately.add(messageProxies.get(i)); 1014 } 1015 } else { 1016 loadImmediately = new Vector(messageProxies); 1017 } 1018 1019 loadMessageTableInfos(loadImmediately); 1020 1021 1027 mMessageLoader.loadMessages(messageProxies); 1028 1029 1030 } finally { 1031 updateDisplay(false); 1032 } 1033 1034 } 1035 } 1036 1037 1040 public void loadMessageTableInfos(Vector messages) { 1041 int numMessages = messages.size(); 1042 MessageProxy mp; 1043 1044 int updateCounter = 0; 1045 1046 if (numMessages > 0) { 1047 1048 int fetchBatchSize = 25; 1049 int loadBatchSize = 25; 1050 try { 1051 fetchBatchSize = Integer.parseInt(Pooka.getProperty("Pooka.fetchBatchSize", "50")); 1052 } catch (NumberFormatException nfe) { 1053 } 1054 1055 FetchProfile fetchProfile = getFetchProfile(); 1056 1057 int i = numMessages - 1; 1058 while ( i >= 0 ) { 1059 for (int batchCount = 0; i >=0 && batchCount < loadBatchSize; batchCount++) { 1060 mp=(MessageProxy)messages.elementAt(i); 1061 1062 if (! mp.getMessageInfo().hasBeenFetched()) { 1063 try { 1064 int fetchCount = 0; 1065 Vector fetchVector = new Vector(); 1066 for (int j = i; fetchCount < fetchBatchSize && j >= 0; j--) { 1067 MessageInfo fetchInfo = ((MessageProxy) messages.elementAt(j)).getMessageInfo(); 1068 if (! fetchInfo.hasBeenFetched()) { 1069 fetchVector.add(fetchInfo); 1070 fetchInfo.setFetched(true); 1071 } 1072 } 1073 1074 MessageInfo[] toFetch = new MessageInfo[fetchVector.size()]; 1075 toFetch = (MessageInfo[]) fetchVector.toArray(toFetch); 1076 this.fetch(toFetch, fetchProfile); 1077 } catch(MessagingException me) { 1078 getLogger().log(Level.FINE, "caught error while fetching for folder " + getFolderID() + ": " + me); 1079 me.printStackTrace(); 1080 } 1081 1082 } 1083 try { 1084 if (! mp.isLoaded()) 1085 mp.loadTableInfo(); 1086 if (mp.needsRefresh()) 1087 mp.refreshMessage(); 1088 else if (! mp.matchedFilters()) { 1089 mp.matchFilters(); 1090 } 1091 } catch (Exception e) { 1092 e.printStackTrace(); 1093 } 1094 i--; 1095 } 1096 1097 } 1098 } 1099 } 1100 1101 1105 public void fetch(MessageInfo[] messages, FetchProfile profile) throws MessagingException { 1106 Message[] realMsgs = new Message[messages.length]; 1107 for (int i = 0; i < realMsgs.length; i++) { 1108 realMsgs[i] = messages[i].getMessage(); 1109 } 1110 getFolder().fetch(realMsgs, profile); 1111 1112 for (int i = 0 ; i < messages.length; i++) { 1113 messages[i].setFetched(true); 1114 } 1115 } 1116 1117 1122 public void unloadAllMessages() { 1123 folderTableModel = null; 1124 } 1125 1126 1127 1132 public void unloadTableInfos() { 1133 if (folderTableModel != null) { 1134 List allProxies = folderTableModel.getAllProxies(); 1135 for (int i = 0; i < allProxies.size(); i++) { 1136 MessageProxy mp = (MessageProxy) allProxies.get(i); 1137 mp.unloadTableInfo(); 1138 } 1139 1140 1144 1145 if (mMessageLoader != null) 1146 mMessageLoader.loadMessages(allProxies); 1147 1148 } 1149 } 1150 1151 1154 public void unloadMatchingFilters() { 1155 if (folderTableModel != null) { 1156 List allProxies = folderTableModel.getAllProxies(); 1157 for (int i = 0; i < allProxies.size(); i++) { 1158 MessageProxy mp = (MessageProxy) allProxies.get(i); 1159 mp.clearMatchedFilters(); 1160 } 1161 1162 1166 1167 if (mMessageLoader != null) 1168 mMessageLoader.loadMessages(allProxies); 1169 1170 } 1171 } 1172 1173 1176 public void refreshHeaders(MessageInfo mi) throws MessagingException { 1177 } 1179 1180 1183 public void refreshFlags(MessageInfo mi) throws MessagingException { 1184 } 1186 1187 1188 1193 public void checkFolder() throws javax.mail.MessagingException { 1194 getLogger().log(Level.FINE, "checking folder " + getFolderID()); 1195 1196 1199 if (isConnected()) { 1200 Folder current = getFolder(); 1201 if (current != null && current.isOpen()) { 1202 current.getNewMessageCount(); 1203 current.getUnreadMessageCount(); 1204 } 1205 resetMessageCounts(); 1206 } 1207 } 1208 1209 1214 public int getFirstUnreadMessage() { 1215 getLogger().log(Level.FINE, "getting first unread message"); 1216 1217 if (! tracksUnreadMessages()) 1218 return -1; 1219 1220 if (getFolderTableModel() == null) 1221 return -1; 1222 1223 try { 1224 int countUnread = 0; 1225 int i; 1226 if (unreadCount > 0) { 1227 1228 1230 Message[] messages = getFolder().getMessages(); 1231 int lastUnreadFound = -1; 1232 for (i = messages.length - 1; ( i >= 0 && countUnread < unreadCount) ; i--) { 1233 if (!(messages[i].isSet(Flags.Flag.SEEN))) { 1234 lastUnreadFound = i; 1235 countUnread++; 1236 } 1237 } 1238 if (lastUnreadFound != -1) { 1239 getLogger().log(Level.FINE, "Returning " + (lastUnreadFound + 1)); 1240 return lastUnreadFound; 1241 } else { 1242 getLogger().log(Level.FINE, "unreads detected, but none found."); 1243 return -1; 1244 } 1245 1246 } else { 1247 getLogger().log(Level.FINE, "Returning -1"); 1248 return -1; 1249 } 1250 } catch (MessagingException me) { 1251 getLogger().log(Level.FINE, "Messaging Exception. Returning -1"); 1252 return -1; 1253 } 1254 } 1255 1256 1262 public void updateChildren() { 1263 Vector newChildren = new Vector(); 1264 1265 String childList = Pooka.getProperty(getFolderProperty() + ".folderList", ""); 1266 if (childList != "") { 1267 StringTokenizer tokens = new StringTokenizer(childList, ":"); 1268 1269 String newFolderName; 1270 1271 for (int i = 0 ; tokens.hasMoreTokens() ; i++) { 1272 newFolderName = (String )tokens.nextToken(); 1273 FolderInfo childFolder = getChild(newFolderName); 1274 if (childFolder == null) { 1275 childFolder = new FolderInfo(this, newFolderName); 1276 newChildren.add(childFolder); 1277 } else { 1278 newChildren.add(childFolder); 1279 } 1280 } 1281 1282 children = newChildren; 1283 1284 if (folderNode != null) 1285 folderNode.loadChildren(); 1286 } 1287 } 1288 1289 1295 public FolderInfo getChild(String childName) { 1296 getLogger().log(Level.FINE, "folder " + getFolderID() + " getting child " + childName); 1297 1298 FolderInfo childFolder = null; 1299 String folderName = null, subFolderName = null; 1300 1301 if (children != null) { 1302 int divider = childName.indexOf('/'); 1303 if (divider > 0) { 1304 folderName = childName.substring(0, divider); 1305 if (divider < childName.length() - 1) 1306 subFolderName = childName.substring(divider + 1); 1307 } else 1308 folderName = childName; 1309 1310 getLogger().log(Level.FINE, "getting direct child " + folderName); 1311 1312 for (int i = 0; i < children.size(); i++) 1313 if (((FolderInfo)children.elementAt(i)).getFolderName().equals(folderName)) 1314 childFolder = (FolderInfo)children.elementAt(i); 1315 } else { 1316 getLogger().log(Level.FINE, "children of " + getFolderID() + " is null."); 1317 } 1318 1319 if (childFolder != null && subFolderName != null) 1320 return childFolder.getChild(subFolderName); 1321 else 1322 return childFolder; 1323 } 1324 1325 1331 public FolderInfo getFolderById(String folderID) { 1332 FolderInfo childFolder = null; 1333 1334 if (getFolderID().equals(folderID)) 1335 return this; 1336 1337 if (children != null) { 1338 for (int i = 0; i < children.size(); i++) { 1339 FolderInfo possibleMatch = ((FolderInfo)children.elementAt(i)).getFolderById(folderID); 1340 if (possibleMatch != null) { 1341 return possibleMatch; 1342 } 1343 } 1344 } 1345 1346 return null; 1347 } 1348 1349 1352 public LoadMessageThread createLoaderThread() { 1353 LoadMessageThread lmt = new LoadMessageThread(this); 1354 return lmt; 1355 } 1356 1357 1360 public MessageLoader createMessageLoader() { 1361 MessageLoader ml = new MessageLoader(this); 1362 return ml; 1363 } 1364 1365 1368 public MessageLoader getMessageLoader() { 1369 return mMessageLoader; 1370 } 1371 1372 1373 1376 public Message getRealMessage(MessageInfo mi) throws MessagingException { 1377 return mi.getMessage(); 1378 } 1379 1380 1383 public void setFlags(MessageInfo[] msgs, Flags flag, boolean value) throws MessagingException { 1384 Message[] m = new Message[msgs.length]; 1385 for (int i = 0; i < msgs.length; i++) { 1386 m[i] = msgs[i].getRealMessage(); 1387 } 1388 1389 getFolder().setFlags(m, flag, value); 1390 } 1391 1392 1395 public void copyMessages(MessageInfo[] msgs, FolderInfo targetFolder) throws MessagingException { 1396 if (targetFolder == null) { 1397 throw new MessagingException(Pooka.getProperty("error.null", "Error: null folder")); 1398 } else if (targetFolder.getStatus() == INVALID) { 1399 throw new MessagingException(Pooka.getProperty("error.folderInvalid", "Error: folder is invalid. ") + targetFolder.getFolderID()); 1400 } 1401 1402 if (! targetFolder.isAvailable()) 1403 targetFolder.loadFolder(); 1404 1405 synchronized(targetFolder.getFolderThread().getRunLock()) { 1406 Folder target = targetFolder.getFolder(); 1407 if (target != null) { 1408 Message[] m = new Message[msgs.length]; 1409 for (int i = 0; i < msgs.length; i++) { 1410 m[i] = msgs[i].getRealMessage(); 1411 } 1412 1413 getFolder().copyMessages(m, target); 1414 1415 1418 targetFolder.checkFolder(); 1419 1420 } else { 1421 targetFolder.appendMessages(msgs); 1422 } 1423 } 1424 } 1425 1426 1429 public void appendMessages(MessageInfo[] msgs) throws MessagingException { 1430 if (! isSortaOpen()) 1431 openFolder(Folder.READ_WRITE); 1432 Message[] m = new Message[msgs.length]; 1433 for (int i = 0; i < msgs.length; i++) { 1434 m[i] = msgs[i].getRealMessage(); 1435 } 1436 1437 getFolder().appendMessages(m); 1438 } 1439 1440 1443 public void expunge() throws MessagingException { 1444 getFolder().expunge(); 1445 } 1446 1447 1452 1453 public void fireMessageChangedEvent(MessageChangedEvent mce) { 1454 1456 Object [] listeners = eventListeners.getListenerList(); 1458 for (int i = listeners.length-2; i>=0; i-=2) { 1461 if (listeners[i]==MessageChangedListener.class) { 1462 ((MessageChangedListener)listeners[i+1]).messageChanged(mce); 1463 } 1464 } 1465 } 1466 1467 public void addConnectionListener(ConnectionListener newListener) { 1468 eventListeners.add(ConnectionListener.class, newListener); 1469 } 1470 1471 public void removeConnectionListener(ConnectionListener oldListener) { 1472 eventListeners.remove(ConnectionListener.class, oldListener); 1473 } 1474 1475 1476 1481 public void fireConnectionEvent(ConnectionEvent e) { 1482 1484 Object [] listeners = eventListeners.getListenerList(); 1486 for (int i = listeners.length-2; i>=0; i-=2) { 1489 if (listeners[i]==ConnectionListener.class) { 1490 ConnectionListener listener = (ConnectionListener) listeners[i+1]; 1491 if (e.getType() == ConnectionEvent.CLOSED) 1492 listener.closed(e); 1493 else if (e.getType() == ConnectionEvent.DISCONNECTED) 1494 listener.disconnected(e); 1495 else if (e.getType() == ConnectionEvent.OPENED) 1496 listener.opened(e); 1497 } 1498 } 1499 } 1500 1501 1506 public void valueChanged(String changedValue) { 1507 if (changedValue.equals(getFolderProperty() + ".folderList")) { 1508 final Runnable runMe = new Runnable () { 1509 public void run() { 1510 ((javax.swing.tree.DefaultTreeModel )(((FolderPanel)folderNode.getParentContainer()).getFolderTree().getModel())).nodeStructureChanged(folderNode); 1511 } 1512 }; 1513 if (Thread.currentThread() != getFolderThread()) { 1516 getFolderThread().addToQueue(new javax.swing.AbstractAction () { 1517 public void actionPerformed(java.awt.event.ActionEvent e) { 1518 updateChildren(); 1519 if (folderNode != null) { 1520 javax.swing.SwingUtilities.invokeLater(runMe); 1521 } 1522 } 1523 } , new java.awt.event.ActionEvent (this, 0, "open-all")); 1524 } else { 1525 updateChildren(); 1526 if (folderNode != null) { 1527 javax.swing.SwingUtilities.invokeLater(runMe); 1528 } 1529 } 1530 } else if (changedValue.equals(getFolderProperty() + ".defaultProfile")) { 1531 String newProfileValue = Pooka.getProperty(changedValue, ""); 1532 if (newProfileValue.length() < 1 || newProfileValue.equals(UserProfile.S_DEFAULT_PROFILE_KEY)) 1533 defaultProfile = null; 1534 else 1535 defaultProfile = Pooka.getPookaManager().getUserProfileManager().getProfile(newProfileValue); 1536 } else if (changedValue.equals(getFolderProperty() + ".backendFilters")) { 1537 createFilters(); 1538 1539 } else if (changedValue.equals(getFolderProperty() + ".displayFilters")) { 1540 createFilters(); 1541 unloadMatchingFilters(); 1542 } else if (changedValue.equals(getFolderProperty() + ".notifyNewMessagesMain") || changedValue.equals(getFolderProperty() + ".notifyNewMessagesNode")) { 1543 setNotifyNewMessagesMain(!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesMain", "").equalsIgnoreCase("false")); 1544 1545 setNotifyNewMessagesNode(!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesNode", "").equalsIgnoreCase("false")); 1546 } 1547 } 1548 1549 1554 public void createSubFolder(String subFolderName, int type) throws MessagingException { 1555 if ( ! isLoaded()) { 1556 loadFolder(); 1557 } 1558 1559 if (folder != null) { 1560 Folder subFolder = folder.getFolder(subFolderName); 1561 1562 if (subFolder == null) { 1563 throw new MessagingException("Store returned null for subfolder " + subFolderName + " of folder " + getFolderName()); 1564 } 1565 1566 if (! subFolder.exists()) 1567 subFolder.create(type); 1568 1569 subscribeFolder(subFolderName); 1570 } else { 1571 throw new MessagingException("Failed to open folder " + getFolderName() + " to create subfolder " + subFolderName); 1572 } 1573 } 1574 1575 1580 public void subscribeFolder(String folderName) { 1581 getLogger().log(Level.FINE, "Folder " + getFolderID() + " subscribing subfolder " + folderName); 1582 1583 String subFolderName = null; 1584 String childFolderName = null; 1585 int firstSlash = folderName.indexOf('/'); 1586 while (firstSlash == 0) { 1587 folderName = folderName.substring(1); 1588 firstSlash = folderName.indexOf('/'); 1589 } 1590 1591 if (firstSlash > 0) { 1592 childFolderName = folderName.substring(0, firstSlash); 1593 if (firstSlash < folderName.length() -1) 1594 subFolderName = folderName.substring(firstSlash +1); 1595 } else 1596 childFolderName = folderName; 1597 1598 getLogger().log(Level.FINE, "Folder " + getFolderID() + " subscribing folder " + childFolderName + ", plus subfolder " + subFolderName); 1599 1600 this.addToFolderList(childFolderName); 1601 1602 FolderInfo childFolder = getChild(childFolderName); 1603 1604 getLogger().log(Level.FINE, "got child folder " + childFolder + " from childFolderName " + childFolderName); 1605 1606 1607 if (childFolder != null && subFolderName != null) { 1608 childFolder.subscribeFolder(subFolderName); 1609 } 1610 1611 try { 1612 if (childFolder != null && childFolder.isLoaded() == false) 1613 childFolder.loadFolder(); 1614 } catch (MessagingException me) { 1615 getLogger().log(Level.FINE, Thread.currentThread() + "loading folder " + getFolderID() + ": caught messaging exception from parentStore getting folder: " + me); 1618 if (getLogger().isLoggable(Level.FINE)) 1619 me.printStackTrace(); 1620 1621 } 1622 1623 updateChildren(); 1624 } 1625 1626 1630 void addToFolderList(String addFolderName) { 1631 Vector folderNames = Pooka.getResources().getPropertyAsVector(getFolderProperty() + ".folderList", ""); 1632 1633 boolean found = false; 1634 1635 for (int i = 0; i < folderNames.size(); i++) { 1636 String folderName = (String ) folderNames.elementAt(i); 1637 1638 if (folderName.equals(addFolderName)) { 1639 found=true; 1640 } 1641 1642 } 1643 1644 if (!found) { 1645 String currentValue = Pooka.getProperty(getFolderProperty() + ".folderList", ""); 1646 if (currentValue.equals("")) 1647 Pooka.setProperty(getFolderProperty() + ".folderList", addFolderName); 1648 else 1649 Pooka.setProperty(getFolderProperty() + ".folderList", currentValue + ":" + addFolderName); 1650 } 1651 1652 } 1653 1654 1661 void removeFromFolderList(String removeFolderName) { 1662 Vector folderNames = Pooka.getResources().getPropertyAsVector(getFolderProperty() + ".folderList", ""); 1663 1664 boolean first = true; 1665 StringBuffer newValue = new StringBuffer (); 1666 String folderName; 1667 1668 for (int i = 0; i < folderNames.size(); i++) { 1669 folderName = (String ) folderNames.elementAt(i); 1670 1671 if (! folderName.equals(removeFolderName)) { 1672 if (!first) 1673 newValue.append(":"); 1674 1675 newValue.append(folderName); 1676 first = false; 1677 } 1678 1679 } 1680 1681 Pooka.setProperty(getFolderProperty() + ".folderList", newValue.toString()); 1682 } 1683 1684 1691 public void unsubscribe() { 1692 1693 cleanup(); 1694 1695 if (parentFolder != null) 1696 parentFolder.removeFromFolderList(getFolderName()); 1697 else if (parentStore != null) 1698 parentStore.removeFromFolderList(getFolderName()); 1699 1700 try { 1701 if (folder != null) 1702 folder.setSubscribed(false); 1703 } catch (MessagingException me) { 1704 Pooka.getUIFactory().showError(Pooka.getProperty("error.folder.unsubscribe", "Error unsubscribing on server from folder ") + getFolderID(), me); 1705 } 1706 } 1707 1708 1711 public void delete() throws MessagingException { 1712 if (! isLoaded()) 1713 loadFolder(); 1714 1715 Folder f = getFolder(); 1716 if (f == null) 1717 throw new MessagingException("No folder."); 1718 1719 unsubscribe(); 1720 1721 if (f.isOpen()) 1722 f.close(true); 1723 f.delete(true); 1724 } 1725 1726 1729 protected void cleanup() { 1730 1731 Pooka.getResources().removeValueChangeListener(this); 1732 Folder f = getFolder(); 1733 if (f != null) { 1734 removeFolderListeners(); 1735 } 1736 1737 if (children != null && children.size() > 0) { 1738 for (int i = 0; i < children.size(); i++) 1739 ((FolderInfo)children.elementAt(i)).cleanup(); 1740 } 1741 1742 Pooka.getLogManager().removeLogger(getFolderProperty()); 1743 1744 if (getFolderDisplayUI() != null) 1745 getFolderDisplayUI().closeFolderDisplay(); 1746 1747 } 1748 1749 1756 public boolean useTrashFolder() { 1757 if (isTrashFolder()) 1758 return false; 1759 1760 String prop = Pooka.getProperty(getFolderProperty() + ".useTrashFolder", ""); 1761 if (!prop.equals("")) 1762 return (! prop.equalsIgnoreCase("false")); 1763 1764 if (getParentFolder() != null) 1765 return getParentFolder().useTrashFolder(); 1766 else if (getParentStore() != null) 1767 return getParentStore().useTrashFolder(); 1768 else 1769 return (! Pooka.getProperty("Pooka.useTrashFolder", "true").equalsIgnoreCase("true")); 1770 } 1771 1772 1776 public void emptyTrash() { 1777 if (isTrashFolder()) { 1778 try { 1779 Message[] allMessages = getFolder().getMessages(); 1780 getFolder().setFlags(allMessages, new Flags(Flags.Flag.DELETED), true); 1781 getFolder().expunge(); 1782 } catch (MessagingException me) { 1783 String m = Pooka.getProperty("error.trashFolder.EmptyTrashError", "Error emptying Trash:") +"\n" + me.getMessage(); 1784 if (getFolderDisplayUI() != null) 1785 getFolderDisplayUI().showError(m); 1786 else 1787 getLogger().log(Level.FINE, m); 1788 } 1789 } 1790 } 1791 1792 1797 public void resetDefaultActions() { 1798 if (isTrashFolder()) { 1799 defaultActions = new Action [] { 1800 new net.suberic.util.thread.ActionWrapper(new UpdateCountAction(), getFolderThread()), 1801 new net.suberic.util.thread.ActionWrapper(new EmptyTrashAction(), getFolderThread()), 1802 new EditPropertiesAction() 1803 }; 1804 } else if (isOutboxFolder()) { 1805 defaultActions = new Action [] { 1806 new net.suberic.util.thread.ActionWrapper(new UpdateCountAction(), getFolderThread()), 1807 new net.suberic.util.thread.ActionWrapper(new SendAllAction(), getFolderThread()), 1808 new EditPropertiesAction() 1809 }; 1810 1811 } else { 1812 defaultActions = new Action [] { 1813 new net.suberic.util.thread.ActionWrapper(new UpdateCountAction(), getFolderThread()), 1814 new EditPropertiesAction() 1815 }; 1816 } 1817 } 1818 1819 1821 public MessageProxy getMessageProxy(int rowNumber) { 1822 return getFolderTableModel().getMessageProxy(rowNumber); 1823 } 1824 1825 public MessageInfo getMessageInfo(Message m) { 1826 return (MessageInfo)messageToInfoTable.get(m); 1827 } 1828 1829 public void addMessageCountListener(MessageCountListener newListener) { 1830 eventListeners.add(MessageCountListener.class, newListener); 1831 } 1832 1833 public void removeMessageCountListener(MessageCountListener oldListener) { 1834 eventListeners.remove(MessageCountListener.class, oldListener); 1835 } 1836 1837 public void fireMessageCountEvent(MessageCountEvent mce) { 1838 1839 1841 Object [] listeners = eventListeners.getListenerList(); 1843 1846 if (mce.getType() == MessageCountEvent.ADDED) { 1847 for (int i = listeners.length-2; i>=0; i-=2) { 1848 if (listeners[i]==MessageCountListener.class) { 1849 ((MessageCountListener)listeners[i+1]).messagesAdded(mce); 1850 } 1851 } 1852 } else if (mce.getType() == MessageCountEvent.REMOVED) { 1853 for (int i = listeners.length-2; i>=0; i-=2) { 1854 if (listeners[i]==MessageCountListener.class) { 1855 1856 ((MessageCountListener)listeners[i+1]).messagesRemoved(mce); 1857 } 1858 } 1859 1860 } 1861 } 1862 1863 public void addMessageChangedListener(MessageChangedListener newListener) { 1864 eventListeners.add(MessageChangedListener.class, newListener); 1865 } 1866 1867 public void removeMessageChangedListener(MessageChangedListener oldListener) { 1868 eventListeners.remove(MessageChangedListener.class, oldListener); 1869 } 1870 1871 1873 public void messagesAdded(MessageCountEvent e) { 1874 getLogger().log(Level.FINE, "Messages added."); 1875 1876 if (Thread.currentThread() == getFolderThread() ) 1877 runMessagesAdded(e); 1878 else 1879 getFolderThread().addToQueue(new net.suberic.util.thread.ActionWrapper(new javax.swing.AbstractAction () { 1880 1881 public void actionPerformed(java.awt.event.ActionEvent actionEvent) { 1882 runMessagesAdded((MessageCountEvent)actionEvent.getSource()); 1883 } 1884 }, getFolderThread()), new java.awt.event.ActionEvent (e, 1, "message-count-changed")); 1885 1886 } 1887 1888 protected void runMessagesAdded(MessageCountEvent mce) { 1889 getLogger().log(Level.FINE, "running messagesAdded on FolderInfo."); 1890 1891 if (folderTableModel != null) { 1892 Message[] addedMessages = mce.getMessages(); 1893 1894 MessageInfo mp; 1895 Vector addedProxies = new Vector(); 1896 getLogger().log(Level.FINE, "running messagesAdded: creating " + addedMessages.length + " proxies/MessageInfos."); 1897 1898 for (int i = 0; i < addedMessages.length; i++) { 1899 mp = new MessageInfo(addedMessages[i], FolderInfo.this); 1900 addedProxies.add(new MessageProxy(getColumnValues(), mp)); 1901 messageToInfoTable.put(addedMessages[i], mp); 1902 } 1903 getLogger().log(Level.FINE, "filtering proxies."); 1904 1905 addedProxies.removeAll(applyFilters(addedProxies)); 1906 if (addedProxies.size() > 0) { 1907 getLogger().log(Level.FINE, "filters run; adding " + addedProxies.size() + " messages."); 1908 1909 getFolderTableModel().addRows(addedProxies); 1910 setNewMessages(true); 1911 resetMessageCounts(); 1912 1913 MessageProxy[] addedArray = (MessageProxy[]) addedProxies.toArray(new MessageProxy[0]); 1915 mMessageLoader.loadMessages(addedArray, MessageLoader.HIGH); 1916 1917 fireMessageCountEvent(mce); 1918 } 1919 } 1920 1921 } 1922 1923 1932 public void messagesRemoved(MessageCountEvent e) { 1933 getLogger().log(Level.FINE, "Messages Removed."); 1934 1935 if (Thread.currentThread() == getFolderThread() ) { 1936 runMessagesRemoved(e); 1937 } else { 1938 getFolderThread().addToQueue(new net.suberic.util.thread.ActionWrapper(new javax.swing.AbstractAction () { 1939 public void actionPerformed(java.awt.event.ActionEvent actionEvent) { 1940 runMessagesRemoved((MessageCountEvent)actionEvent.getSource()); 1941 } 1942 }, getFolderThread()), new java.awt.event.ActionEvent (e, 1, "messages-removed")); 1943 } 1944 } 1945 1946 1950 protected void runMessagesRemoved(MessageCountEvent mce) { 1951 getLogger().log(Level.FINE, "running MessagesRemoved on " + getFolderID()); 1952 1953 if (folderTableModel != null) { 1954 Message[] removedMessages = mce.getMessages(); 1955 getLogger().log(Level.FINE, "removedMessages was of size " + removedMessages.length); 1956 MessageInfo mi; 1957 Vector removedProxies=new Vector(); 1958 1959 if (getLogger().isLoggable(Level.FINE)) { 1960 getLogger().log(Level.FINE, "message in info table:"); 1961 Enumeration keys = messageToInfoTable.keys(); 1962 while (keys.hasMoreElements()) 1963 getLogger().log(Level.FINE, (String )keys.nextElement()); 1964 } 1965 1966 for (int i = 0; i < removedMessages.length; i++) { 1967 getLogger().log(Level.FINE, "checking for existence of message " + removedMessages[i]); 1968 mi = getMessageInfo(removedMessages[i]); 1969 if (mi != null) { 1970 if (mi.getMessageProxy() != null) 1971 mi.getMessageProxy().close(); 1972 1973 getLogger().log(Level.FINE, "message exists--removing"); 1974 removedProxies.add(mi.getMessageProxy()); 1975 messageToInfoTable.remove(removedMessages[i]); 1976 } 1977 } 1978 if (getFolderDisplayUI() != null) { 1979 if (removedProxies.size() > 0) 1980 getFolderDisplayUI().removeRows(removedProxies); 1981 resetMessageCounts(); 1982 fireMessageCountEvent(mce); 1983 } else { 1984 resetMessageCounts(); 1985 fireMessageCountEvent(mce); 1986 if (removedProxies.size() > 0) 1987 getFolderTableModel().removeRows(removedProxies); 1988 } 1989 } else { 1990 resetMessageCounts(); 1991 fireMessageCountEvent(mce); 1992 } 1993 } 1994 1995 2000 public void messageChanged(MessageChangedEvent e) { 2001 2003 if (Thread.currentThread() == getFolderThread() ) 2004 runMessageChanged(e); 2005 else 2006 getFolderThread().addToQueue(new net.suberic.util.thread.ActionWrapper(new javax.swing.AbstractAction () { 2007 public void actionPerformed(java.awt.event.ActionEvent actionEvent) { 2008 runMessageChanged((MessageChangedEvent)actionEvent.getSource()); 2009 } 2010 }, getFolderThread()), new java.awt.event.ActionEvent (e, 1, "message-changed")); 2011 } 2012 2013 2014 protected void runMessageChanged(MessageChangedEvent mce) { 2015 boolean updateInfo = false; 2020 try { 2021 updateInfo = (!mce.getMessage().isSet(Flags.Flag.DELETED) || ! Pooka.getProperty("Pooka.autoExpunge", "true").equalsIgnoreCase("true")); 2022 } catch (MessagingException me) { 2023 } 2028 2029 if (updateInfo) { 2030 try { 2031 MessageInfo mi = getMessageInfo(mce.getMessage()); 2032 MessageProxy mp = mi.getMessageProxy(); 2033 if (mp != null) { 2034 mp.unloadTableInfo(); 2035 mp.loadTableInfo(); 2036 if (mce.getMessageChangeType() == MessageChangedEvent.FLAGS_CHANGED) 2037 mi.refreshFlags(); 2038 else if (mce.getMessageChangeType() == MessageChangedEvent.ENVELOPE_CHANGED) 2039 mi.refreshHeaders(); 2040 } 2041 } catch (MessagingException me) { 2042 } 2045 2046 if (! (mce instanceof net.suberic.pooka.event.MessageTableInfoChangedEvent)) { 2049 resetMessageCounts(); 2050 } 2051 } 2052 2053 fireMessageChangedEvent(mce); 2054 } 2055 2056 2059 public void showSearchFolder() { 2060 Pooka.getUIFactory().showSearchForm(new FolderInfo[] { this }); 2061 } 2062 2063 2068 public static void searchFolders(Vector folderList, javax.mail.search.SearchTerm term) { 2069 final javax.mail.search.SearchTerm searchTerm = term; 2070 final Vector selectedFolders = folderList; 2071 2072 Pooka.getSearchThread().addToQueue(new net.suberic.util.thread.ActionWrapper(new javax.swing.AbstractAction () { 2073 public void actionPerformed(ActionEvent e) { 2074 Vector matchingValues = new Vector(); 2075 Logger.getLogger("Pooka.debug").log(Level.FINE, "init: matchingValues.size() = " + matchingValues.size()); 2076 2077 net.suberic.util.swing.ProgressDialog dialog = Pooka.getUIFactory().createProgressDialog(0,100,0,"Search","Searching"); 2078 dialog.show(); 2079 boolean cancelled = dialog.isCancelled(); 2080 2081 for (int i = 0; ! cancelled && i < selectedFolders.size(); i++) { 2082 Logger.getLogger("Pooka.debug").log(Level.FINE, "trying selected folder number " + i); 2083 try { 2084 net.suberic.pooka.MessageInfo[] matches = ((FolderInfo) selectedFolders.elementAt(i)).search(searchTerm); 2085 Logger.getLogger("Pooka.debug").log(Level.FINE, "matches.length = " + matches.length); 2086 for (int j = 0; j < matches.length; j++) { 2087 matchingValues.add(matches[j]); 2088 Logger.getLogger("Pooka.debug").log(Level.FINE, "adding " + matches[j] + " to matchingValues."); 2089 } 2090 2091 } catch (MessagingException me) { 2092 Logger.getLogger("Pooka.debug").log(Level.FINE, "caught exception " + me); 2093 } 2094 cancelled = dialog.isCancelled(); 2095 } 2096 2097 Logger.getLogger("Pooka.debug").log(Level.FINE, "got " + matchingValues.size() + " matches."); 2098 2099 if (! cancelled) { 2100 FolderInfo[] parentFolders = new FolderInfo[selectedFolders.size()]; 2101 for (int i = 0; i < selectedFolders.size(); i++) { 2102 parentFolders[i] = (FolderInfo) selectedFolders.elementAt(i); 2103 } 2104 2105 MessageInfo[] matchingMessages = new MessageInfo[matchingValues.size()]; 2106 for (int i = 0; i < matchingValues.size(); i++) { 2107 Logger.getLogger("Pooka.debug").log(Level.FINE, "matchingValues.elementAt(" + i + ") = " + matchingValues.elementAt(i)); 2108 matchingMessages[i] = (MessageInfo) matchingValues.elementAt(i); 2109 } 2110 2111 final VirtualFolderInfo sfi = new VirtualFolderInfo(matchingMessages, parentFolders); 2112 2113 Runnable runMe = new Runnable () { 2114 public void run() { 2115 FolderDisplayUI fdui = Pooka.getUIFactory().createFolderDisplayUI(sfi); 2116 fdui.openFolderDisplay(); 2117 } 2118 }; 2119 2120 javax.swing.SwingUtilities.invokeLater(runMe); 2121 } 2122 2123 dialog.dispose(); 2124 } 2125 }, Pooka.getSearchThread()), new java.awt.event.ActionEvent (FolderInfo.class, 1, "search")); 2126 2127 } 2128 2129 2136 public MessageInfo[] search(javax.mail.search.SearchTerm term) 2137 throws MessagingException { 2138 if (folderTableModel == null) 2139 loadAllMessages(); 2140 2141 Message[] matchingMessages = folder.search(term); 2142 MessageInfo returnValue[] = new MessageInfo[matchingMessages.length]; 2143 for (int i = 0; i < matchingMessages.length; i++) { 2144 getLogger().log(Level.FINE, "match " + i + " = " + matchingMessages[i]); 2145 MessageInfo info = getMessageInfo(matchingMessages[i]); 2146 getLogger().log(Level.FINE, "messageInfo " + i + " = " + info); 2147 returnValue[i] = info; 2148 } 2149 getLogger().log(Level.FINE, "got " + returnValue.length + " results."); 2150 return returnValue; 2151 } 2152 2153 2156 protected String getDefaultDisplayFiltersResource() { 2157 if (isSentFolder()) 2158 return "FolderInfo.sentFolderDefaultDisplayFilters"; 2159 else 2160 return "FolderInfo.defaultDisplayFilters"; 2161 } 2162 2163 List filterHeaders = null; 2164 2165 2170 public void createFilters() { 2171 BackendMessageFilter[] tmpBackendFilters = null; 2172 MessageFilter[] tmpDisplayFilters = null; 2173 Vector backendFilterNames=Pooka.getResources().getPropertyAsVector(getFolderProperty() + ".backendFilters", ""); 2174 2175 if (backendFilterNames != null && backendFilterNames.size() > 0) { 2176 2177 tmpBackendFilters = new BackendMessageFilter[backendFilterNames.size()]; 2178 for (int i = 0; i < backendFilterNames.size(); i++) { 2179 tmpBackendFilters[i] = new BackendMessageFilter(getFolderProperty() + ".backendFilters." + (String ) backendFilterNames.elementAt(i)); 2180 } 2181 2182 backendFilters = tmpBackendFilters; 2183 } 2184 2185 Vector foundFilters = new Vector(); 2186 Vector defaultFilterNames = Pooka.getResources().getPropertyAsVector(getDefaultDisplayFiltersResource(), ""); 2187 2188 for (int i = 0; i < defaultFilterNames.size(); i++) { 2189 foundFilters.add(new MessageFilter("FolderInfo.defaultDisplayFilters." + (String ) defaultFilterNames.elementAt(i))); 2190 } 2191 2192 Vector displayFilterNames=Pooka.getResources().getPropertyAsVector(getFolderProperty() + ".displayFilters", ""); 2193 for (int i = 0; i < displayFilterNames.size(); i++) { 2194 foundFilters.add(new MessageFilter(getFolderProperty() + ".displayFilters." + (String ) displayFilterNames.elementAt(i))); 2195 } 2196 2197 tmpDisplayFilters = new MessageFilter[foundFilters.size()]; 2198 for (int i = 0; i < foundFilters.size(); i++) 2199 tmpDisplayFilters[i] = (MessageFilter) foundFilters.elementAt(i); 2200 2201 displayFilters = tmpDisplayFilters; 2202 2203 filterHeaders = new LinkedList(); 2204 for (int i = 0; i < tmpDisplayFilters.length; i++) { 2206 javax.mail.search.SearchTerm filterTerm = tmpDisplayFilters[i].getSearchTerm(); 2207 if (filterTerm != null) { 2208 List headers = getHeaders(filterTerm); 2209 filterHeaders.addAll(headers); 2210 } 2211 } 2212 2213 if (fetchProfile != null) { 2214 for (int i = 0; i < filterHeaders.size(); i++) { 2215 fetchProfile.add((String ) filterHeaders.get(i)); 2216 } 2217 } 2218 } 2219 2220 2223 private List getHeaders(SearchTerm term) { 2224 List returnValue = new LinkedList(); 2225 if (term instanceof HeaderTerm) { 2226 String headerName = ((HeaderTerm) term).getHeaderName(); 2227 returnValue.add(headerName); 2228 } else if (term instanceof AndTerm) { 2229 SearchTerm[] terms = ((AndTerm)term).getTerms(); 2230 for (int i = 0; i < terms.length; i++) { 2231 returnValue.addAll(getHeaders(terms[i])); 2232 } 2233 } else if (term instanceof OrTerm) { 2234 SearchTerm[] terms = ((OrTerm)term).getTerms(); 2235 for (int i = 0; i < terms.length; i++) { 2236 returnValue.addAll(getHeaders(terms[i])); 2237 } 2238 } else if (term instanceof NotTerm) { 2239 SearchTerm otherTerm = ((NotTerm)term).getTerm(); 2240 returnValue.addAll(getHeaders(otherTerm)); 2241 } else if (term instanceof FromTerm || term instanceof FromStringTerm) { 2242 returnValue.add("From"); 2243 } else if (term instanceof RecipientTerm || term instanceof RecipientStringTerm) { 2244 Message.RecipientType type; 2245 if (term instanceof RecipientTerm) 2246 type = ((RecipientTerm) term).getRecipientType(); 2247 else 2248 type = ((RecipientStringTerm) term).getRecipientType(); 2249 if (type == Message.RecipientType.TO) 2250 returnValue.add("To"); 2251 else if (type == Message.RecipientType.CC) 2252 returnValue.add("Cc"); 2253 else if (type == Message.RecipientType.BCC) 2254 returnValue.add("Bcc"); 2255 } 2256 2257 return returnValue; 2258 } 2259 2260 2266 public Vector applyFilters(List messages) { 2267 return applyFilters(messages, null); 2268 } 2269 2270 2276 public Vector applyFilters(List messages, net.suberic.util.swing.ProgressDialog pd) { 2277 Vector notRemovedYet = new Vector(messages); 2278 Vector removed = new Vector(); 2279 if (backendFilters != null) 2280 for (int i = 0; i < backendFilters.length; i++) { 2281 if (backendFilters[i] != null) { 2282 List justRemoved = backendFilters[i].filterMessages(notRemovedYet, pd); 2283 removed.addAll(justRemoved); 2284 notRemovedYet.removeAll(justRemoved); 2285 } 2286 } 2287 2288 if (removed.size() > 0) { 2289 try { 2290 expunge(); 2291 } catch (MessagingException me) { 2292 me.printStackTrace(); 2293 } 2294 } 2295 2296 return removed; 2297 } 2298 2299 2301 2304 public BackendMessageFilter[] getBackendFilters() { 2305 return backendFilters; 2306 } 2307 2308 public Action [] getActions() { 2309 return defaultActions; 2310 } 2311 2312 public Folder getFolder() { 2313 return folder; 2314 } 2315 2316 protected void setFolder(Folder newValue) { 2317 folder=newValue; 2318 } 2319 2320 2323 public String getFolderID() { 2324 return folderID; 2325 } 2326 2327 2330 private void setFolderID(String newValue) { 2331 folderID=newValue; 2332 } 2333 2334 2337 public String getFolderName() { 2338 return mFolderName; 2339 } 2340 2341 2345 public String getFolderDisplayName() { 2346 return mFolderName + " - " + getParentStore().getStoreID(); 2347 } 2348 2349 2353 public String getFolderProperty() { 2354 return "Store." + getFolderID(); 2355 } 2356 2357 public Vector getChildren() { 2358 return children; 2359 } 2360 2361 public FolderNode getFolderNode() { 2362 return folderNode; 2363 } 2364 2365 public void setFolderNode(FolderNode newValue) { 2366 folderNode = newValue; 2367 } 2368 2369 public FolderTableModel getFolderTableModel() { 2370 return folderTableModel; 2371 } 2372 2373 public void setFolderTableModel(FolderTableModel newValue) { 2374 folderTableModel = newValue; 2375 } 2376 2377 public List getColumnValues() { 2378 return columnValues; 2379 } 2380 2381 public void setColumnValues(List newValue) { 2382 columnValues = newValue; 2383 } 2384 2385 public List <String > getColumnIds() { 2386 return columnIds; 2387 } 2388 2389 public void setColumnIds(List <String > newColumnIds) { 2390 columnIds = newColumnIds; 2391 } 2392 2393 public List <String > getColumnNames() { 2394 return columnNames; 2395 } 2396 2397 public void setColumnNames(List <String > newValue) { 2398 columnNames = newValue; 2399 } 2400 2401 public List <String > getColumnSizes() { 2402 return columnSizes; 2403 } 2404 2405 public void setColumnSizes(List <String > newValue) { 2406 columnSizes = newValue; 2407 } 2408 2409 public FolderDisplayUI getFolderDisplayUI() { 2410 return folderDisplayUI; 2411 } 2412 2413 protected void removeFromListeners(FolderDisplayUI display) { 2414 if (display != null) { 2415 removeMessageChangedListener(display); 2416 removeMessageCountListener(display); 2417 } 2419 } 2420 2421 protected void addToListeners(FolderDisplayUI display) { 2422 if (display != null) { 2423 addMessageChangedListener(display); 2424 addMessageCountListener(display); 2425 } 2427 } 2428 2429 2436 public void setFolderDisplayUI(FolderDisplayUI newValue) { 2437 removeFromListeners(folderDisplayUI); 2438 folderDisplayUI = newValue; 2439 addToListeners(folderDisplayUI); 2440 } 2441 2442 public int getType() { 2443 return type; 2444 } 2445 2446 public boolean isConnected() { 2447 return (status == CONNECTED); 2448 } 2449 2450 public boolean shouldBeConnected() { 2451 return (status < PASSIVE); 2452 } 2453 2454 public boolean isSortaOpen() { 2455 return (status < CLOSED); 2456 } 2457 2458 public boolean isAvailable() { 2459 return (status < NOT_LOADED); 2460 } 2461 2462 public boolean isLoaded() { 2463 return (folder != null); 2464 } 2465 2466 public boolean isValid() { 2467 return (status != INVALID); 2468 } 2469 2470 public boolean hasUnread() { 2471 return (tracksUnreadMessages() && unreadCount > 0); 2472 } 2473 2474 public int getUnreadCount() { 2475 if (!tracksUnreadMessages()) 2476 return 0; 2477 else 2478 return unreadCount; 2479 } 2480 2481 public int getMessageCount() { 2482 return messageCount; 2483 } 2484 2485 public boolean hasNewMessages() { 2486 return newMessages; 2487 } 2488 2489 public void setNewMessages(boolean newValue) { 2490 newMessages = newValue; 2491 } 2492 2493 public FolderTracker getFolderTracker() { 2494 return folderTracker; 2495 } 2496 2497 public void setFolderTracker(FolderTracker newTracker) { 2498 folderTracker = newTracker; 2499 } 2500 2501 public boolean isTrashFolder() { 2502 return trashFolder; 2503 } 2504 2505 2509 public void setTrashFolder(boolean newValue) { 2510 trashFolder = newValue; 2511 if (newValue) { 2512 setNotifyNewMessagesMain(false); 2513 setNotifyNewMessagesNode(false); 2514 } else { 2515 if (!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesMain", "").equalsIgnoreCase("false")) 2516 setNotifyNewMessagesMain(true); 2517 else 2518 setNotifyNewMessagesMain(false); 2519 2520 if (!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesNode", "").equalsIgnoreCase("false")) 2521 setNotifyNewMessagesNode(true); 2522 else 2523 setNotifyNewMessagesNode(false); 2524 } 2525 2526 resetDefaultActions(); 2527 if (getFolderNode() != null) 2528 getFolderNode().popupMenu = null; 2529 } 2530 2531 2532 public boolean isSentFolder() { 2533 return sentFolder; 2534 } 2535 2536 2537 public void setSentFolder(boolean newValue) { 2538 sentFolder = newValue; 2539 if (newValue) { 2540 setNotifyNewMessagesMain(false); 2541 setNotifyNewMessagesNode(false); 2542 } else { 2543 if (!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesMain", "").equalsIgnoreCase("false")) 2544 setNotifyNewMessagesMain(true); 2545 else 2546 setNotifyNewMessagesMain(false); 2547 2548 if (!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesNode", "").equalsIgnoreCase("false")) 2549 setNotifyNewMessagesNode(true); 2550 else 2551 setNotifyNewMessagesNode(false); 2552 } 2553 setTracksUnreadMessages (! newValue); 2554 createFilters(); 2555 } 2556 2557 2560 public boolean isOutboxFolder() { 2561 return (mailServer != null); 2562 } 2563 2564 2568 public void setOutboxFolder(OutgoingMailServer newServer) { 2569 mailServer = newServer; 2570 if (newServer != null) { 2571 setNotifyNewMessagesMain(false); 2572 setNotifyNewMessagesNode(false); 2573 } else { 2574 if (!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesMain", "").equalsIgnoreCase("false")) 2575 setNotifyNewMessagesMain(true); 2576 else 2577 setNotifyNewMessagesMain(false); 2578 2579 if (!Pooka.getProperty(getFolderProperty() + ".notifyNewMessagesNode", "").equalsIgnoreCase("false")) 2580 setNotifyNewMessagesNode(true); 2581 else 2582 setNotifyNewMessagesNode(false); 2583 } 2584 2585 resetDefaultActions(); 2586 } 2587 2588 public boolean notifyNewMessagesMain() { 2589 return notifyNewMessagesMain; 2590 } 2591 2592 public void setNotifyNewMessagesMain(boolean newValue) { 2593 notifyNewMessagesMain = newValue; 2594 } 2595 2596 public boolean notifyNewMessagesNode() { 2597 return notifyNewMessagesNode; 2598 } 2599 2600 public void setNotifyNewMessagesNode(boolean newValue) { 2601 notifyNewMessagesNode = newValue; 2602 } 2603 2604 public void setTracksUnreadMessages(boolean newValue) { 2605 tracksUnreadMessages = newValue; 2606 } 2607 2608 public boolean tracksUnreadMessages() { 2609 return tracksUnreadMessages; 2610 } 2611 2612 public MessageFilter[] getDisplayFilters() { 2613 return displayFilters; 2614 } 2615 2616 2619 public void resetMessageCounts() { 2620 try { 2621 if (getFolder() != null) 2622 getLogger().log(Level.FINE, "running resetMessageCounts. unread message count is " + getFolder().getUnreadMessageCount()); 2623 else 2624 getLogger().log(Level.FINE, "running resetMessageCounts. getFolder() is null."); 2625 2626 if (tracksUnreadMessages()) { 2627 unreadCount = getFolder().getUnreadMessageCount(); 2628 } 2629 2630 messageCount = getFolder().getMessageCount(); 2631 } catch (MessagingException me) { 2632 unreadCount = 0; 2635 } 2636 updateNode(); 2637 } 2638 2639 2643 public FolderInfo getParentFolder() { 2644 return parentFolder; 2645 } 2646 2647 2652 public StoreInfo getParentStore() { 2653 if (parentStore == null) 2654 return parentFolder.getParentStore(); 2655 else 2656 return parentStore; 2657 } 2658 2659 public UserProfile getDefaultProfile() { 2660 if (defaultProfile != null) { 2661 return defaultProfile; 2662 } else if (parentFolder != null) { 2663 return parentFolder.getDefaultProfile(); 2664 } else if (parentStore != null) { 2665 return parentStore.getDefaultProfile(); 2666 } else { 2667 return null; 2668 } 2669 } 2670 2671 2674 public void setStatus(int newStatus) { 2675 synchronized(this) { 2676 status = newStatus; 2677 } 2678 } 2679 2680 2683 public int getStatus() { 2684 return status; 2685 } 2686 2687 public ActionThread getFolderThread() { 2688 return getParentStore().getStoreThread(); 2689 } 2690 2691 public FolderInfo getTrashFolder() { 2692 return getParentStore().getTrashFolder(); 2693 } 2694 2695 public FetchProfile getFetchProfile() { 2696 return fetchProfile; 2697 } 2698 2699 2702 public boolean isNamespace() { 2703 return mNamespace; 2704 } 2705 2706 2709 public void showStatusMessage(net.suberic.pooka.gui.FolderDisplayUI pUI, String message) { 2710 if (pUI != null) 2711 pUI.showStatusMessage(message); 2712 else 2713 Pooka.getUIFactory().showStatusMessage(message); 2714 } 2715 2716 2719 public void clearStatusMessage(net.suberic.pooka.gui.FolderDisplayUI pUI) { 2720 if (pUI != null) 2721 pUI.clearStatusMessage(); 2722 else 2723 Pooka.getUIFactory().clearStatus(); 2724 } 2725 2726 2729 public Logger getLogger() { 2730 if (mLogger == null) { 2731 mLogger = Logger.getLogger(getFolderProperty()); 2732 } 2733 return mLogger; 2734 } 2735 2736 class EditPropertiesAction extends AbstractAction { 2737 2738 EditPropertiesAction() { 2739 super("file-edit"); 2740 } 2741 2742 public void actionPerformed(ActionEvent e) { 2743 Pooka.getUIFactory().showEditorWindow(getFolderProperty(), getFolderProperty(), "Folder.editor"); 2744 } 2745 } 2746 2747 class UpdateCountAction extends AbstractAction { 2748 2749 UpdateCountAction() { 2750 super("folder-update"); 2751 } 2752 2753 public void actionPerformed(ActionEvent e) { 2754 try { 2756 checkFolder(); 2757 } catch (MessagingException me) { 2758 final MessagingException me2 = me; 2759 2760 javax.swing.SwingUtilities.invokeLater(new Runnable () { 2761 public void run() { 2762 if (getFolderDisplayUI() != null) 2763 getFolderDisplayUI().showError(Pooka.getProperty("error.updatingFolder", "Error updating Folder ") + getFolderID(), me2); 2764 else 2765 Pooka.getUIFactory().showError(Pooka.getProperty("error.updatingFolder", "Error updating Folder ") + getFolderID(), me2); 2766 2767 } 2768 }); 2769 2770 } 2771 } 2772 } 2773 2774 class EmptyTrashAction extends AbstractAction { 2775 2776 EmptyTrashAction() { 2777 super("folder-empty"); 2778 } 2779 2780 public void actionPerformed(ActionEvent e) { 2781 emptyTrash(); 2782 } 2783 } 2784 2785 2786 class SendAllAction extends AbstractAction { 2787 2788 SendAllAction() { 2789 super("folder-send"); 2790 } 2791 2792 public void actionPerformed(ActionEvent e) { 2793 if (isOutboxFolder()) 2794 mailServer.sendAll(); 2795 } 2796 } 2797 2798} 2799 | Popular Tags |