1 package net.suberic.pooka; 2 3 import javax.mail.*; 4 import javax.mail.event.*; 5 import javax.swing.event.EventListenerList ; 6 import java.util.*; 7 import java.util.logging.Logger ; 8 import java.util.logging.Level ; 9 10 import net.suberic.pooka.gui.*; 11 import net.suberic.util.ValueChangeListener; 12 import net.suberic.util.thread.ActionThread; 13 import net.suberic.util.VariableBundle; 14 import net.suberic.util.Item; 15 16 21 22 public class StoreInfo implements ValueChangeListener, Item, NetworkConnectionListener { 23 24 Logger mLogger = null; 26 27 private Store store; 29 private Session mSession; 30 31 private String storeID; 33 34 private StoreNode storeNode; 36 private Vector children; 37 38 private boolean connected = false; 40 private boolean authorized = false; 41 private boolean available = false; 42 43 private boolean popStore = false; 45 46 private UserProfile defaultProfile; 47 48 private NetworkConnection connection; 49 50 private String user; 52 private String password; 53 private String server; 54 private String protocol; 55 private int port; 56 private URLName url; 57 58 private String sslSetting = "none"; 59 60 private ActionThread storeThread; 62 63 private FolderInfo trashFolder; 65 66 private boolean useSubscribed = false; 69 70 private ConnectionListener connectionListener; 72 73 76 public StoreInfo(String sid) { 77 setStoreID(sid); 78 79 configureStore(); 80 } 81 82 85 public void configureStore() { 86 connected = false; 87 authorized = false; 88 available = false; 89 90 protocol = Pooka.getProperty("Store." + storeID + ".protocol", ""); 91 92 if (protocol.equalsIgnoreCase("pop3")) { 93 user = ""; 94 password = ""; 95 server = "localhost"; 96 if (Pooka.getProperty(getStoreProperty() + ".useMaildir", "unset").equalsIgnoreCase("true")) 97 protocol = "maildir"; 98 else 99 protocol = "mbox"; 100 port = -1; 101 popStore = true; 102 } else { 103 popStore = false; 104 user = Pooka.getProperty("Store." + storeID + ".user", ""); 105 password = Pooka.getProperty("Store." + storeID + ".password", ""); 106 String portValue = Pooka.getProperty("Store." + storeID + ".port", ""); 107 port = -1; 108 if (!portValue.equals("")) { 109 try { 110 port = Integer.parseInt(portValue); 111 } catch (Exception e) { 112 } 113 } 114 if (!password.equals("")) 115 password = net.suberic.util.gui.propedit.PasswordEditorPane.descrambleString(password); 116 server = Pooka.getProperty("Store." + storeID + ".server", ""); 117 118 sslSetting = Pooka.getProperty(getStoreProperty() + ".SSL", "none"); 119 if (sslSetting.equalsIgnoreCase("true")) { 120 Pooka.setProperty(getStoreProperty() + ".SSL", "ssl"); 121 sslSetting = "ssl"; 122 } else if (sslSetting.equalsIgnoreCase("false")) { 123 Pooka.setProperty(getStoreProperty() + ".SSL", "none"); 124 sslSetting = "none"; 125 } 126 127 if (sslSetting.equals("ssl")) { 128 if (protocol.equals("imap")) 129 protocol = "imaps"; 130 } 131 } 132 133 134 Properties p = loadProperties(); 135 136 if (protocol.equalsIgnoreCase("maildir")) { 137 url = new URLName(protocol, server, port, p.getProperty("mail.store.maildir.baseDir"), user, password); 138 } else { 139 url = new URLName(protocol, server, port, "", user, password); 140 } 141 142 try { 143 mSession = Session.getInstance(p, Pooka.getDefaultAuthenticator()); 144 145 updateSessionDebug(); 146 147 store = mSession.getStore(url); 148 available=true; 149 } catch (NoSuchProviderException nspe) { 150 Pooka.getUIFactory().showError(Pooka.getProperty("error.loadingStore", "Unable to load Store ") + getStoreID(), nspe); 151 available=false; 152 } 153 154 156 if (Pooka.getProperty("Store." + storeID + ".folderList", "").equals("")) 157 Pooka.setProperty("Store." + storeID + ".folderList", "INBOX"); 158 159 useSubscribed = Pooka.getProperty(getStoreProperty() + ".useSubscribed", "false").equalsIgnoreCase("true"); 161 162 Pooka.getResources().addValueChangeListener(this, getStoreProperty()); 163 Pooka.getResources().addValueChangeListener(this, getStoreProperty() + ".folderList"); 164 Pooka.getResources().addValueChangeListener(this, getStoreProperty() + ".defaultProfile"); 165 Pooka.getResources().addValueChangeListener(this, getStoreProperty() + ".protocol"); 166 Pooka.getResources().addValueChangeListener(this, getStoreProperty() + ".user"); 167 Pooka.getResources().addValueChangeListener(this, getStoreProperty() + ".password"); 168 Pooka.getResources().addValueChangeListener(this, getStoreProperty() + ".server"); 169 Pooka.getResources().addValueChangeListener(this, getStoreProperty() + ".port"); 170 Pooka.getResources().addValueChangeListener(this, getStoreProperty() + ".connection"); 171 Pooka.getResources().addValueChangeListener(this, getStoreProperty() + ".SSL"); 172 Pooka.getResources().addValueChangeListener(this, getStoreProperty() + ".useSubscribed"); 173 Pooka.getResources().addValueChangeListener(this, getStoreProperty() + ".sessionDebug.level"); 174 175 Pooka.getLogManager().addLogger(getStoreProperty()); 177 Pooka.getLogManager().addLogger(getStoreProperty() + ".sessionDebug"); 178 179 if (available) { 180 connectionListener = new ConnectionListener() { 181 182 public void disconnected(ConnectionEvent e) { 183 getLogger().log(Level.FINE, "Store " + getStoreID() + " disconnected."); 184 if (isConnected()) { 186 try { 187 if (Pooka.getUIFactory().getMessageNotificationManager() != null) { 188 Pooka.getUIFactory().getMessageNotificationManager().displayMessage("Disconnected", "Disconnected from store " + getStoreID(), net.suberic.pooka.gui.MessageNotificationManager.WARNING_MESSAGE_TYPE); 189 } 190 disconnectStore(); 191 } catch (MessagingException me) { 192 getLogger().log(Level.FINE, "error disconnecting Store: " + me.getMessage()); 193 } 194 } 195 196 } 197 198 public void closed(ConnectionEvent e) { 199 getLogger().log(Level.FINE, "Store " + getStoreID() + " closed."); 200 201 if (isConnected()) { 203 if (Pooka.getUIFactory().getMessageNotificationManager() != null) { 204 Pooka.getUIFactory().getMessageNotificationManager().displayMessage("Disconnected", "Disconnected from store " + getStoreID(), net.suberic.pooka.gui.MessageNotificationManager.WARNING_MESSAGE_TYPE); 205 } 206 try { 207 disconnectStore(); 208 } catch (MessagingException me) { 209 getLogger().log(Level.FINE, "error disconnecting Store: " + me.getMessage()); 210 } 211 } 212 213 } 214 215 public void opened(ConnectionEvent e) { 216 getLogger().log(Level.FINE, "Store " + getStoreID() + " opened."); 217 } 218 }; 219 220 store.addConnectionListener(connectionListener); 221 222 } 223 224 if (storeThread == null) { 225 storeThread = new ActionThread(this.getStoreID() + " - ActionThread"); 226 storeThread.start(); 227 } 228 229 String defProfileString = Pooka.getProperty(getStoreProperty() + ".defaultProfile", ""); 230 if (defProfileString.length() < 1 || defProfileString.equalsIgnoreCase(UserProfile.S_DEFAULT_PROFILE_KEY)) { 231 defaultProfile = null; 232 } else { 233 defaultProfile = Pooka.getPookaManager().getUserProfileManager().getProfile(defProfileString); 234 } 235 236 connection = Pooka.getConnectionManager().getConnection(Pooka.getProperty(getStoreProperty() + ".connection", "")); 237 if (connection == null) { 238 connection = Pooka.getConnectionManager().getDefaultConnection(); 239 } 240 241 if (connection != null) { 242 connection.addConnectionListener(this); 243 } 244 245 updateChildren(); 246 247 String trashFolderName = Pooka.getProperty(getStoreProperty() + ".trashFolder", ""); 248 if (trashFolderName.length() > 0) { 249 trashFolder = getChild(trashFolderName); 250 if (trashFolder != null) 251 trashFolder.setTrashFolder(true); 252 } 253 } 254 255 259 public Properties loadProperties() { 260 Properties p = new Properties(System.getProperties()); 261 262 String realProtocol = Pooka.getProperty("Store." + storeID + ".protocol", ""); 263 264 if (realProtocol.equalsIgnoreCase("imap")) { 265 loadImapProperties(p); 266 } else if (realProtocol.equalsIgnoreCase("pop3")) { 267 loadPop3Properties(p); 268 String useMaildir = Pooka.getProperty(getStoreProperty() + ".useMaildir", "unset"); 269 270 if (useMaildir.equals("unset")) { 271 Pooka.setProperty(getStoreProperty() + ".useMaildir", "false"); 272 useMaildir="false"; 273 } 274 275 if ( useMaildir.equalsIgnoreCase("false")) { 276 loadMboxProperties(p); 277 } else { 278 loadMaildirProperties(p); 279 } 280 } else if (realProtocol.equalsIgnoreCase("maildir")) { 281 loadMaildirProperties(p); 282 } else if (realProtocol.equalsIgnoreCase("mbox")) { 283 loadMboxProperties(p); 284 } 285 return p; 286 } 287 288 291 void loadImapProperties(Properties p) { 292 p.setProperty("mail.imap.timeout", Pooka.getProperty(getStoreProperty() + ".timeout", Pooka.getProperty("Pooka.timeout", "-1"))); 293 p.setProperty("mail.imap.connectiontimeout", Pooka.getProperty(getStoreProperty() + ".connectionTimeout", Pooka.getProperty("Pooka.connectionTimeout", "-1"))); 294 295 p.setProperty("mail.imaps.timeout", Pooka.getProperty(getStoreProperty() + ".timeout", Pooka.getProperty("Pooka.timeout", "-1"))); 296 p.setProperty("mail.imaps.connectiontimeout", Pooka.getProperty(getStoreProperty() + ".connectionTimeout", Pooka.getProperty("Pooka.connectionTimeout", "-1"))); 297 298 if (sslSetting.equals("ssl")) { 300 p.setProperty("mail.imaps.socketFactory.fallback", Pooka.getProperty(getStoreProperty() + ".SSL.fallback", "false")); 301 } else if (sslSetting.equals("tlsrequired")) { 302 p.setProperty("mail.imap.starttls.enable", "true"); 303 } else if (sslSetting.equals("tls")) { 304 p.setProperty("mail.imap.starttls.enable", "true"); 306 } 307 308 p.setProperty("mail.imap.separatestoreconnection", "true"); 310 p.setProperty("mail.imaps.separatestoreconnection", "true"); 311 } 312 313 316 void loadPop3Properties(Properties p) { 317 if (Pooka.getProperty(getStoreProperty() + ".SSL", "false").equalsIgnoreCase("true")) { 318 p.setProperty("mail.pop3s.socketFactory.fallback", Pooka.getProperty(getStoreProperty() + ".SSL.fallback", "false")); 320 } 322 } 323 324 327 void loadMaildirProperties(Properties p) { 328 329 String mailHome = Pooka.getProperty(getStoreProperty() + ".mailDir", ""); 330 if (mailHome.equals("")) { 331 mailHome = Pooka.getProperty("Pooka.defaultMailSubDir", ""); 332 if (mailHome.equals("")) 333 mailHome = System.getProperty("user.home") + java.io.File.separator + ".pooka"; 334 335 mailHome = mailHome + java.io.File.separator + storeID; 336 } 337 338 String userHomeName = mailHome + java.io.File.separator + Pooka.getProperty("Pooka.subFolderName", "folders"); 339 340 p.setProperty("mail.store.maildir.baseDir", userHomeName); 342 p.setProperty("mail.store.maildir.autocreatedir", "true"); 343 } 344 345 348 void loadMboxProperties(Properties p) { 349 358 String mailHome = Pooka.getProperty(getStoreProperty() + ".mailDir", ""); 359 if (mailHome.equals("")) { 360 mailHome = Pooka.getProperty("Pooka.defaultMailSubDir", ""); 361 if (mailHome.equals("")) 362 mailHome = System.getProperty("user.home") + java.io.File.separator + ".pooka"; 363 364 mailHome = mailHome + java.io.File.separator + storeID; 365 } 366 367 String inboxFileName; 368 if (Pooka.getProperty(getStoreProperty() + ".protocol", "imap").equalsIgnoreCase("pop3")) { 369 inboxFileName = mailHome + java.io.File.separator + Pooka.getProperty("Pooka.inboxName", "INBOX"); 370 } else { 371 inboxFileName = Pooka.getProperty(getStoreProperty() + ".inboxLocation", "/var/spool/mail/" + System.getProperty("user.name")); 372 } 373 374 String userHomeName = mailHome + java.io.File.separator + Pooka.getProperty("Pooka.subFolderName", "folders"); 375 376 getLogger().log(Level.FINE, "for store " + getStoreID() + ", inboxFileName = " + inboxFileName + "; userhome = " + userHomeName); 377 378 p.setProperty("mail.mbox.inbox", inboxFileName); 379 p.setProperty("mail.mbox.userhome", userHomeName); 380 } 381 382 386 387 public void updateChildren() { 388 389 Vector newChildren = new Vector(); 390 391 StringTokenizer tokens = new StringTokenizer(Pooka.getProperty(getStoreProperty() + ".folderList", "INBOX"), ":"); 392 393 getLogger().log(Level.FINE, "Pooka.getProperty(" + getStoreProperty() + ".folderList = " + Pooka.getProperty(getStoreProperty() + ".folderList")); 394 395 String newFolderName; 396 397 for (int i = 0 ; tokens.hasMoreTokens() ; i++) { 398 newFolderName = (String )tokens.nextToken(); 399 FolderInfo childFolder = getChild(newFolderName); 400 if (childFolder == null) { 401 childFolder = Pooka.getResourceManager().createFolderInfo(this, newFolderName); 402 } 403 404 newChildren.add(childFolder); 405 } 406 children = newChildren; 407 getLogger().log(Level.FINE, getStoreID() + ": in configureStore. children.size() = " + children.size()); 408 409 if (storeNode != null) 410 storeNode.loadChildren(); 411 } 412 413 419 public FolderInfo getChild(String childName) { 420 FolderInfo childFolder = null; 421 String folderName = null, subFolderName = null; 422 423 if (children != null) { 424 int divider = childName.indexOf('/'); 425 if (divider > 0) { 426 folderName = childName.substring(0, divider); 427 if (divider < childName.length() - 1) 428 subFolderName = childName.substring(divider + 1); 429 } else 430 folderName = childName; 431 432 for (int i = 0; i < children.size(); i++) 433 if (((FolderInfo)children.elementAt(i)).getFolderName().equals(folderName)) 434 childFolder = (FolderInfo)children.elementAt(i); 435 } 436 437 if (childFolder != null && subFolderName != null) 438 return childFolder.getChild(subFolderName); 439 else 440 return childFolder; 441 } 442 443 444 450 public FolderInfo getFolderById(String folderID) { 451 FolderInfo childFolder = null; 452 453 if (children != null) { 454 for (int i = 0; i < children.size(); i++) { 455 FolderInfo possibleMatch = ((FolderInfo)children.elementAt(i)).getFolderById(folderID); 456 if (possibleMatch != null) { 457 return possibleMatch; 458 } 459 } 460 } 461 462 return null; 463 } 464 465 468 public void remove() { 469 try { 471 disconnectStore(); 472 } catch (Exception e) { 473 } 474 cleanup(); 475 478 } 479 480 483 public void cleanup() { 484 Pooka.getResources().removeValueChangeListener(this); 485 Pooka.getLogManager().removeLogger(getStoreProperty()); 486 487 if (children != null && children.size() > 0) { 488 for (int i = 0; i < children.size(); i++) 489 ((FolderInfo)children.elementAt(i)).cleanup(); 490 } 491 492 if (store != null) { 493 store.removeConnectionListener(connectionListener); 494 } 495 if (getStoreThread() != null) { 496 getStoreThread().setStop(true); 497 } 498 } 499 500 505 506 public void valueChanged(String pChangedValue) { 507 final String changedValue = pChangedValue; 508 javax.swing.AbstractAction valueChangedAction = new javax.swing.AbstractAction () { 509 public void actionPerformed(java.awt.event.ActionEvent ae) { 510 List <String > storeList = Pooka.getResources().getPropertyAsList("Store", ""); 512 if (storeList.contains(getStoreID())) { 513 if (changedValue.equals(getStoreProperty() + ".folderList")) { 514 updateChildren(); 515 } else if (changedValue.equals(getStoreProperty() + ".defaultProfile")) { 516 String defProfileString = Pooka.getProperty(getStoreProperty() + ".defaultProfile", ""); 517 if (defProfileString.length() < 1 || defProfileString.equalsIgnoreCase(UserProfile.S_DEFAULT_PROFILE_KEY)) { 518 defaultProfile = null; 519 } else { 520 defaultProfile = Pooka.getPookaManager().getUserProfileManager().getProfile(defProfileString); 521 } 522 } else if (changedValue.equals(getStoreProperty() + ".protocol") || changedValue.equals(getStoreProperty() + ".user") || changedValue.equals(getStoreProperty() + ".password") || changedValue.equals(getStoreProperty() + ".server") || changedValue.equals(getStoreProperty() + ".port") || changedValue.equals(getStoreProperty() + ".SSL") ) { 523 524 if (storeNode != null) { 525 Enumeration childEnum = storeNode.children(); 526 Vector v = new Vector(); 527 while (childEnum.hasMoreElements()) 528 v.add(childEnum.nextElement()); 529 530 storeNode.removeChildren(v); 531 } 532 533 children = null; 534 535 try { 536 disconnectStore(); 537 } catch (Exception e) { } 538 539 getLogger().log(Level.FINE, "calling configureStore()"); 540 541 configureStore(); 542 } else if (changedValue.equals(getStoreProperty() + ".connection")) { 543 connection.removeConnectionListener(StoreInfo.this); 544 545 connection = Pooka.getConnectionManager().getConnection(Pooka.getProperty(getStoreProperty() + ".connection", "")); 546 if (connection == null) { 547 connection = Pooka.getConnectionManager().getDefaultConnection(); 548 } 549 550 if (connection != null) { 551 connection.addConnectionListener(StoreInfo.this); 552 } 553 } else if (changedValue.equals(getStoreProperty() + ".useSubscribed")) { 554 useSubscribed = Pooka.getProperty(getStoreProperty() + ".useSubscribed", "false").equalsIgnoreCase("true"); 555 } else if (changedValue.equals(getStoreProperty() + ".sessionDebug.level")) { 556 updateSessionDebug(); 557 } 558 } 559 } 560 }; 561 562 java.awt.event.ActionEvent actionEvent = new java.awt.event.ActionEvent (this, 0, "value-changed"); 565 if (Thread.currentThread() == getStoreThread()) { 566 valueChangedAction.actionPerformed(actionEvent); 567 } else { 568 getStoreThread().addToQueue(valueChangedAction, actionEvent); 569 } 570 571 } 572 573 574 577 public void connectionStatusChanged(NetworkConnection connection, int newStatus) { 578 if (! (protocol.equalsIgnoreCase("mbox") || protocol.equalsIgnoreCase("maildir"))) { 580 if (newStatus == NetworkConnection.CONNECTED) { 581 584 } else if (newStatus == NetworkConnection.DISCONNECTED) { 585 try { 587 disconnectStore(); 588 } catch (MessagingException me) { 589 getLogger().log(Level.FINE, "Caught exception disconnecting Store " + getStoreID() + ": " + me); 590 if (getLogger().isLoggable(Level.FINE)) 591 me.printStackTrace(); 592 } 594 595 } else { 596 try { 598 disconnectStore(); 599 } catch (MessagingException me) { 600 getLogger().log(Level.FINE, "Caught exception disconnecting Store " + getStoreID() + ": " + me); 601 if (getLogger().isLoggable(Level.FINE)) 602 me.printStackTrace(); 603 } 605 } 606 } 607 } 608 615 void removeFromFolderList(String removeFolderName) { 616 Vector folderNames = Pooka.getResources().getPropertyAsVector(getStoreProperty() + ".folderList", ""); 617 618 boolean first = true; 619 StringBuffer newValue = new StringBuffer (); 620 String folderName; 621 622 for (int i = 0; i < folderNames.size(); i++) { 623 folderName = (String ) folderNames.elementAt(i); 624 625 if (! folderName.equals(removeFolderName)) { 626 if (!first) 627 newValue.append(":"); 628 629 newValue.append(folderName); 630 first = false; 631 } 632 633 } 634 635 Pooka.setProperty(getStoreProperty() + ".folderList", newValue.toString()); 636 } 637 638 641 void addToFolderList(String addFolderName) { 642 String folderName; 643 Vector folderNames = Pooka.getResources().getPropertyAsVector(getStoreProperty() + ".folderList", ""); 644 645 boolean found = false; 646 647 for (int i = 0; i < folderNames.size(); i++) { 648 folderName = (String ) folderNames.elementAt(i); 649 650 if (folderName.equals(addFolderName)) { 651 found=true; 652 } 653 654 } 655 656 if (!found) { 657 String currentValue = Pooka.getProperty(getStoreProperty() + ".folderList"); 658 if (currentValue.equals("")) 659 Pooka.setProperty(getStoreProperty() + ".folderList", addFolderName); 660 else 661 Pooka.setProperty(getStoreProperty() + ".folderList", currentValue + ":" + addFolderName); 662 } 663 664 } 665 666 671 public void createSubFolder(String subFolderName, int type) throws MessagingException { 672 Folder folder = store.getDefaultFolder(); 673 674 if (folder != null) { 675 Folder subFolder = folder.getFolder(subFolderName); 676 677 if (subFolder == null) { 678 throw new MessagingException("Store returned null for subfolder " + subFolderName); 679 } 680 681 if (! subFolder.exists()) 682 subFolder.create(type); 683 684 subscribeFolder(subFolderName); 685 } else { 686 throw new MessagingException("Failed to open store " + getStoreID() + " to create subfolder " + subFolderName); 687 688 } 689 } 690 691 695 public void subscribeFolder(String folderName) { 696 getLogger().log(Level.FINE, "subscribing folder " + folderName); 697 698 String subFolderName = null; 699 String childFolderName = null; 700 int firstSlash = folderName.indexOf('/'); 701 while (firstSlash == 0) { 702 folderName = folderName.substring(1); 703 firstSlash = folderName.indexOf('/'); 704 } 705 706 if (firstSlash > 0) { 707 childFolderName = folderName.substring(0, firstSlash); 708 if (firstSlash < folderName.length() -1) 709 subFolderName = folderName.substring(firstSlash +1); 710 } else 711 childFolderName = folderName; 712 713 getLogger().log(Level.FINE, "store " + getStoreID() + " subscribing folder " + childFolderName + "; sending " + subFolderName + " to child for subscription."); 714 715 this.addToFolderList(childFolderName); 716 717 FolderInfo childFolder = getChild(childFolderName); 718 719 getLogger().log(Level.FINE, "got child folder '" + childFolder + "' for " + childFolderName); 720 721 if (childFolder != null && subFolderName != null) { 722 childFolder.subscribeFolder(subFolderName); 723 } 724 } 725 726 737 public void connectStore() throws MessagingException { 738 getLogger().log(Level.FINE, "trying to connect store " + getStoreID()); 739 740 if (store.isConnected()) { 741 getLogger().log(Level.FINE, "store " + getStoreID() + " is already connected."); 742 743 connected=true; 744 return; 745 } else { 746 try { 747 if (! (protocol.equalsIgnoreCase("mbox") || protocol.equalsIgnoreCase("maildir"))) { 749 NetworkConnection currentConnection = getConnection(); 750 getLogger().log(Level.FINE, "connect store " + getStoreID() + ": checking connection."); 751 752 if (currentConnection != null) { 753 if (currentConnection.getStatus() == NetworkConnection.DISCONNECTED) { 754 getLogger().log(Level.FINE, "connect store " + getStoreID() + ": connection not up. trying to connect it.."); 755 756 currentConnection.connect(true, true); 757 } 758 759 if (connection.getStatus() != NetworkConnection.CONNECTED) { 760 throw new MessagingException(Pooka.getProperty("error.connectionDown", "Connection down for Store: ") + getItemID()); 761 } else { 762 getLogger().log(Level.FINE, "connect store " + getStoreID() + ": successfully opened connection."); 763 764 } 765 } 766 } 767 768 String preCommand = Pooka.getProperty(getStoreProperty() + ".precommand", ""); 770 if (preCommand.length() > 0) { 771 getLogger().log(Level.FINE, "connect store " + getStoreID() + ": executing precommand."); 772 773 try { 774 Process p = Runtime.getRuntime().exec(preCommand); 775 p.waitFor(); 776 } catch (Exception ex) { 777 getLogger().log(Level.FINE, "Could not run precommand:"); 778 ex.printStackTrace(); 779 } 780 } 781 782 getLogger().log(Level.FINE, "connect store " + getStoreID() + ": doing store.connect()"); 783 store.connect(); 784 } catch (MessagingException me) { 785 Exception e = me.getNextException(); 786 787 if (e != null && e instanceof java.io.InterruptedIOException ) 788 store.connect(); 789 else { 790 if (e != null && e.toString().contains("SunCertPathBuilderException") && "tls".equalsIgnoreCase(sslSetting)) { 791 Properties p = mSession.getProperties(); 793 p.setProperty("mail.imap.starttls.enable", "false"); 794 795 store = mSession.getStore(url); 796 797 store.connect(); 798 } else { 799 throw me; 800 } 801 } 802 } 803 804 getLogger().log(Level.FINE, "connect store " + getStoreID() + ": connection succeeded; connected = true."); 805 connected=true; 806 807 if (useSubscribed && protocol.equalsIgnoreCase("imap")) { 808 synchSubscribed(); 809 } 810 811 if (Pooka.getProperty("Pooka.openFoldersOnConnect", "true").equalsIgnoreCase("true")) { 812 for (int i = 0; i < children.size(); i++) { 813 doOpenFolders((FolderInfo) children.elementAt(i)); 814 } 815 } 816 } 817 } 818 819 private void doOpenFolders(FolderInfo fi) { 820 if (Pooka.getProperty("Pooka.openFoldersInBackground", "false").equalsIgnoreCase("true")) { 821 822 final FolderInfo current = fi; 823 javax.swing.AbstractAction openFoldersAction = new javax.swing.AbstractAction () { 824 public void actionPerformed(java.awt.event.ActionEvent e) { 825 current.openAllFolders(Folder.READ_WRITE); 826 } 827 }; 828 829 openFoldersAction.putValue(javax.swing.Action.NAME, "file-open"); 830 openFoldersAction.putValue(javax.swing.Action.SHORT_DESCRIPTION, "file-open on folder " + fi.getFolderID()); 831 getStoreThread().addToQueue(openFoldersAction, new java.awt.event.ActionEvent (this, 0, "open-all"), ActionThread.PRIORITY_LOW); 832 } 833 else { 834 fi.openAllFolders(Folder.READ_WRITE); 835 } 836 } 837 838 844 public void disconnectStore() throws MessagingException { 845 getLogger().log(Level.FINE, "disconnecting store " + getStoreID()); 846 847 MessagingException storeException = null; 848 if (!(store.isConnected())) { 849 connected=false; 850 closeAllFolders(false, false); 851 return; 852 } else { 853 try { 854 try { 855 closeAllFolders(false, false); 856 } catch (MessagingException folderMe) { 857 storeException = folderMe; 858 } 859 store.close(); 860 } catch (MessagingException me) { 861 if (storeException != null) { 862 me.setNextException(storeException); 863 } 864 storeException = me; 865 throw storeException; 866 } finally { 867 connected=false; 868 } 869 870 if (storeException != null) 871 throw storeException; 872 } 873 } 874 875 878 public void closeAllFolders(boolean expunge, boolean shuttingDown) throws MessagingException { 879 if (getStoreThread() != null && ! getStoreThread().getStopped()) { 880 synchronized(getStoreThread().getRunLock()) { 882 getLogger().log(Level.FINE, "closing all folders of store " + getStoreID()); 883 Vector folders = getChildren(); 884 if (folders != null) { 885 for (int i = 0; i < folders.size(); i++) { 886 ((FolderInfo) folders.elementAt(i)).closeAllFolders(expunge, shuttingDown); 887 } 888 } 889 } 890 } 891 } 892 893 896 public void stopStoreThread() { 897 if (storeThread != null) { 898 storeThread.setStop(true); 899 } 901 } 902 903 907 public Vector getAllFolders() { 908 Vector returnValue = new Vector(); 909 Vector subFolders = getChildren(); 910 for (int i = 0; i < subFolders.size(); i++) { 911 returnValue.addAll(((FolderInfo) subFolders.elementAt(i)).getAllFolders()); 912 } 913 return returnValue; 914 } 915 916 920 public void synchSubscribed() throws MessagingException { 921 924 boolean foundInbox=false; 925 926 Folder[] subscribedFolders = store.getDefaultFolder().list(); 927 928 StringBuffer newSubscribed = new StringBuffer (); 929 930 ArrayList subscribedNames = new ArrayList(); 931 932 for (int i = 0; subscribedFolders != null && i < subscribedFolders.length; i++) { 933 String folderName = subscribedFolders[i].getName(); 936 if (folderName.equalsIgnoreCase("inbox")) { 937 if (!foundInbox) { 938 foundInbox=true; 939 subscribedNames.add(folderName); 940 } 941 } else if (subscribedFolders[i].isSubscribed()) { 942 if (! subscribedNames.contains(folderName)) 943 subscribedNames.add(folderName); 944 } 945 } 946 947 List tmpChildren = getChildren(); 949 if (tmpChildren != null) { 950 953 Iterator it = tmpChildren.iterator(); 954 while (it.hasNext()) { 955 FolderInfo fi = (FolderInfo) it.next(); 956 String folderName = fi.getFolderName(); 957 if (fi.isNamespace() && ! subscribedNames.contains(folderName)) 958 subscribedNames.add(folderName); 959 } 960 } 961 962 for (int i = 0; i < subscribedNames.size(); i++) { 963 newSubscribed.append((String )subscribedNames.get(i)).append(':'); 964 } 965 966 if (newSubscribed.length() > 0) 967 newSubscribed.deleteCharAt(newSubscribed.length() -1); 968 969 Pooka.setProperty(getStoreProperty() + ".folderList", newSubscribed.toString()); 971 972 for (int i = 0; children != null && i < children.size(); i++) { 973 FolderInfo fi = (FolderInfo) children.get(i); 974 fi.synchSubscribed(); 975 } 976 } 977 978 long lastConnectionCheck = 0; 980 981 984 public boolean checkConnection() { 985 if (! isConnected()) 987 return false; 988 989 if (System.currentTimeMillis() - lastConnectionCheck > 20000) { 991 getLogger().log(Level.FINER, "Checking connection for store " + getStoreID()); 992 Store realStore = getStore(); 993 994 if (realStore != null) { 995 if (! realStore.isConnected()) { 996 getLogger().log(Level.FINER, getStoreID() + ": isConnected() returns false. returning false."); 997 998 return false; 999 } else { 1000 return true; 1001 } 1002 } else { 1003 return false; 1004 } 1005 } else { 1006 return isConnected(); 1007 } 1008 } 1009 1010 1013 public void showStatus() { 1014 StringBuffer statusBuffer = new StringBuffer (); 1015 getLogger().log(Level.INFO, "Status for store " + getStoreID()); 1016 statusBuffer.append("Status for store " + getStoreID() + "\r\n"); 1017 boolean infoIsConnected = isConnected(); 1018 getLogger().log(Level.INFO, "Connected: " + infoIsConnected); 1019 statusBuffer.append("Connected: " + infoIsConnected + "\r\n"); 1020 1029 1030 if (storeThread != null) { 1031 String currentAction = storeThread.getCurrentActionName(); 1032 getLogger().log(Level.INFO, "Current Action: " + currentAction); 1033 statusBuffer.append("Current Action: " + currentAction + "\r\n"); 1034 int queueSize = storeThread.getQueueSize(); 1035 getLogger().log(Level.INFO, "Action Queue Size: " + queueSize); 1036 statusBuffer.append("Action Queue Size: " + queueSize +"\r\n"); 1037 if (storeThread.getQueueSize() > 0) { 1038 System.out.println("Queue:"); 1039 java.util.List queue = storeThread.getQueue(); 1040 for (int i = 0; i < queue.size(); i++) { 1041 net.suberic.util.thread.ActionThread.ActionEventPair current = (net.suberic.util.thread.ActionThread.ActionEventPair) queue.get(i); 1042 String queueString = " queue[" + i + "]: "; 1043 String entryDescription = (String ) current.action.getValue(javax.swing.Action.SHORT_DESCRIPTION); 1044 if (entryDescription == null) 1045 entryDescription = (String ) current.action.getValue(javax.swing.Action.NAME); 1046 if (entryDescription == null) 1047 entryDescription = "Unknown action"; 1048 1049 queueString = queueString + entryDescription; 1050 System.out.println(queueString); 1051 statusBuffer.append(queueString + "\r\n"); 1052 } 1053 } 1054 statusBuffer.append("Stack Trace:\r\n"); 1055 StackTraceElement [] stackTrace = storeThread.getStackTrace(); 1056 for (StackTraceElement stackLine: stackTrace) { 1057 statusBuffer.append(" " + stackLine + "\r\n"); 1059 } 1060 1061 } else { 1062 getLogger().log(Level.INFO, "No Action Thread."); 1063 StackTraceElement [] stackTrace = Thread.currentThread().getStackTrace(); 1064 for (StackTraceElement stackLine: stackTrace) { 1065 statusBuffer.append(" " + stackLine + "\r\n"); 1067 } 1068 } 1069 1070 Pooka.getUIFactory().showMessage(statusBuffer.toString(), "Status for " + getStoreID()); 1071 } 1072 1073 1075 public Store getStore() { 1076 return store; 1077 } 1078 1079 private void setStore(Store newValue) { 1080 store=newValue; 1081 } 1082 1083 1086 public String getStoreID() { 1087 return storeID; 1088 } 1089 1090 1093 public String getItemID() { 1094 return getStoreID(); 1095 } 1096 1097 1100 private void setStoreID(String newValue) { 1101 storeID=newValue; 1102 } 1103 1104 1108 public String getStoreProperty() { 1109 return "Store." + getStoreID(); 1110 } 1111 1112 1116 public String getItemProperty() { 1117 return getStoreProperty(); 1118 } 1119 1120 1123 public String getProtocol() { 1124 return protocol; 1125 } 1126 1127 1130 public boolean isPopStore() { 1131 return popStore; 1132 } 1133 1134 public Vector getChildren() { 1135 return children; 1136 } 1137 1138 public StoreNode getStoreNode() { 1139 return storeNode; 1140 } 1141 1142 public void setStoreNode(StoreNode newValue) { 1143 storeNode = newValue; 1144 } 1145 1146 public boolean isConnected() { 1147 return connected; 1148 } 1149 1150 public boolean isAvailable() { 1151 return available; 1152 } 1153 1154 public boolean isAuthorized() { 1155 return authorized; 1156 } 1157 1158 public UserProfile getDefaultProfile() { 1159 return defaultProfile; 1160 } 1161 1162 public NetworkConnection getConnection() { 1163 return connection; 1164 } 1165 1166 public ActionThread getStoreThread() { 1167 return storeThread; 1168 } 1169 1170 public void setStoreThread(ActionThread newValue) { 1171 storeThread=newValue; 1172 } 1173 1174 public FolderInfo getTrashFolder() { 1175 return trashFolder; 1176 } 1177 1178 1183 public boolean useTrashFolder() { 1184 if (getTrashFolder() == null) 1185 return false; 1186 1187 String prop = Pooka.getProperty(getStoreProperty() + ".useTrashFolder", ""); 1188 if (!prop.equals("")) 1189 return (! prop.equalsIgnoreCase("false")); 1190 else 1191 return (! Pooka.getProperty("Pooka.useTrashFolder", "true").equalsIgnoreCase("true")); 1192 1193 } 1194 1195 1196 public void setTrashFolder(FolderInfo newValue) { 1197 trashFolder = newValue; 1198 } 1199 1200 1203 public Logger getLogger() { 1204 if (mLogger == null) { 1205 mLogger = Logger.getLogger(getStoreProperty()); 1206 } 1207 return mLogger; 1208 } 1209 1210 1213 void updateSessionDebug() { 1214 if (Pooka.getProperty("Pooka.sessionDebug", "false").equalsIgnoreCase("true") || (! Pooka.getProperty(getStoreProperty() + ".sessionDebug.logLevel", "OFF").equalsIgnoreCase("OFF"))) { 1215 mSession.setDebug(true); 1216 } else { 1217 mSession.setDebug(false); 1218 } 1219 } 1220} 1221 | Popular Tags |