1 package net.suberic.pooka.gui; 2 3 import net.suberic.pooka.Pooka; 4 import net.suberic.util.*; 5 import net.suberic.util.thread.*; 6 import net.suberic.util.gui.propedit.*; 7 import javax.swing.*; 8 import java.util.*; 9 import java.io.File ; 10 import java.net.*; 11 12 import javax.mail.MessagingException ; 13 14 18 19 public class NewAccountPooka { 20 21 23 private MessagePanel messagePanel = null; 24 private PropertyEditorManager manager = null; 25 private PropertyEditorFactory factory = null; 26 private String accountName = null; 27 private boolean useLocalFiles = true; 28 29 public NewAccountPooka() { 30 }; 31 32 public NewAccountPooka(MessagePanel newMP) { 33 setMessagePanel(newMP); 34 } 35 36 public void start() { 37 38 41 42 useLocalFiles = Pooka.getProperty("Pooka.useLocalFiles", "true").equalsIgnoreCase("true"); 43 44 setupDefaultConnection(); 46 47 if (JOptionPane.showInternalConfirmDialog(getMessagePanel(), Pooka.getProperty("NewAccountPooka.introMessage", "Welcome to Pooka.\nIt seems that you don't yet have an Email account configured.\n\nWould you like to configure one now?"), Pooka.getProperty("NewAccountPooka.introMessage.title", "New Account Pooka"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { 48 49 PropertyEditorFactory factory = Pooka.getUIFactory().getEditorFactory(); 50 setFactory(factory); 51 52 manager = new PropertyEditorManager(Pooka.getResources(), factory, factory.getIconManager()); 53 manager.setWriteChanges(false); 54 55 showFirstEntryWindow(); 56 } 57 } 58 59 62 public void showFirstEntryWindow() { 63 67 68 JInternalFrame firstEntryWindow = new JInternalFrame(Pooka.getProperty("NewAccountPooka.entryWindowMessage.title", "Enter Email Account Information"), true, false, false, false); 69 JComponent contentPane = (JComponent) firstEntryWindow.getContentPane(); 70 contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); 71 72 JTextArea jta = new JTextArea(Pooka.getProperty("NewAccountPooka.entryWindowMessage", "Please enter the following \ninformation in order\nto configure your client.")); 75 jta.setMargin(new java.awt.Insets (5, 15, 5, 15)); 76 jta.setEditable(false); 77 78 JLabel jl = new JLabel("test"); 79 jta.setBackground(jl.getBackground()); 80 jta.setFont(jl.getFont()); 82 83 contentPane.add(jta); 84 85 contentPane.add(new PropertyEditorPane(manager, (SwingPropertyEditor) factory.createEditor("NewAccountPooka", "NewAccountPooka", manager), firstEntryWindow)); 86 87 firstEntryWindow.pack(); 88 firstEntryWindow.show(); 89 90 firstEntryWindow.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter () { 91 92 public void internalFrameClosed(javax.swing.event.InternalFrameEvent e) { 93 SwingUtilities.invokeLater( new Runnable () { 94 public void run() { 95 handleFirstEntry(); 96 } 97 }); 98 } 99 }); 100 101 102 java.awt.Point p = getMessagePanel().getNewWindowLocation(firstEntryWindow, true); 103 firstEntryWindow.setLocation(p); 104 getMessagePanel().add(firstEntryWindow); 105 firstEntryWindow.setVisible(true); 106 try { 107 firstEntryWindow.setSelected(true); 108 } catch (java.beans.PropertyVetoException pve) { 109 } 110 } 111 112 115 public void handleFirstEntry() { 116 Properties props = new java.util.Properties (); 117 118 int continueHandling = javax.swing.JOptionPane.NO_OPTION; 119 120 String smtpName = ""; 121 String accountName = ""; 122 123 if (continueHandling == javax.swing.JOptionPane.NO_OPTION) 124 try { 125 smtpName = configureSMTP(manager, props); 126 } catch (Exception e) { 127 e.printStackTrace(); 128 continueHandling = handleInvalidEntry(e.getMessage()); 129 } 130 131 if (continueHandling == javax.swing.JOptionPane.NO_OPTION) 132 try { 133 accountName = configureUserStore(manager, props, smtpName); 134 } catch (Exception e) { 135 e.printStackTrace(); 136 continueHandling = handleInvalidEntry(e.getMessage()); 137 } 138 139 if (continueHandling == javax.swing.JOptionPane.NO_OPTION) 140 try { 141 testConnections(props); 142 } catch (Exception e) { 143 e.printStackTrace(); 144 continueHandling = handleInvalidEntry(e.getMessage()); 145 } 146 147 if (continueHandling == javax.swing.JOptionPane.NO_OPTION ) 148 try { 149 createFiles(props); 150 } catch (Exception e) { 151 e.printStackTrace(); 152 continueHandling = handleInvalidEntry(e.getMessage()); 153 } 154 155 if (continueHandling == javax.swing.JOptionPane.NO_OPTION ) 156 try { 157 setupFolders(props); 158 } catch (Exception e) { 159 e.printStackTrace(); 160 continueHandling = handleInvalidEntry(e.getMessage()); 161 } 162 163 if (continueHandling == javax.swing.JOptionPane.NO_OPTION ) 164 try { 165 setupAddressBook(props); 166 } catch (Exception e) { 167 e.printStackTrace(); 168 continueHandling = handleInvalidEntry(e.getMessage()); 169 } 170 171 if (continueHandling == javax.swing.JOptionPane.NO_OPTION ) 172 try { 173 saveProperties(props); 174 } catch (Exception e) { 175 e.printStackTrace(); 176 continueHandling = handleInvalidEntry(e.getMessage()); 177 } 178 179 if (continueHandling == javax.swing.JOptionPane.NO_OPTION ) 180 try { 181 Pooka.getStoreManager().loadAllSentFolders(); 182 } catch (Exception e) { 183 e.printStackTrace(); 184 continueHandling = handleInvalidEntry(e.getMessage()); 185 } 186 187 if (continueHandling == javax.swing.JOptionPane.NO_OPTION ) 188 try { 189 Pooka.getOutgoingMailManager().loadOutboxFolders(); 190 } catch (Exception e) { 191 e.printStackTrace(); 192 continueHandling = handleInvalidEntry(e.getMessage()); 193 } 194 195 if (continueHandling == javax.swing.JOptionPane.NO_OPTION ) 196 try { 197 openInbox(); 198 } catch (Exception e) { 199 e.printStackTrace(); 200 continueHandling = handleInvalidEntry(e.getMessage()); 201 } 202 203 if (continueHandling == javax.swing.JOptionPane.YES_OPTION ) 204 showFirstEntryWindow(); 205 } 206 207 210 public String configureSMTP(PropertyEditorManager mgr, Properties props) throws Exception { 211 212 String smtpServerName = mgr.getProperty("NewAccountPooka.smtpServer", ""); 213 214 if (smtpServerName.equals("")) { 215 throw new Exception ("Must have an Outgoing mail server set."); 216 } 217 218 220 props.setProperty("OutgoingServer", smtpServerName); 221 props.setProperty("OutgoingServer." + smtpServerName + ".server", smtpServerName); 222 props.setProperty("OutgoingServer." + smtpServerName + ".connection", Pooka.getProperty("Pooka.connection.defaultName", "default")); 223 224 props.setProperty("OutgoingServer._default", smtpServerName); 225 226 return smtpServerName; 227 } 228 229 232 public String configureUserStore(PropertyEditorManager mgr, Properties props, String smtpServerName) throws Exception { 233 String localUser = System.getProperty("user.name"); 234 235 239 String protocol = manager.getProperty("NewAccountPooka.protocol", ""); 240 String fullName = manager.getProperty("NewAccountPooka.fullName", ""); 241 String userName; 242 String accountName; 243 244 if (! protocol.equalsIgnoreCase("mbox")) { 245 userName = manager.getProperty("NewAccountPooka.userName", ""); 246 String password = manager.getProperty("NewAccountPooka.password", ""); 247 String serverName = manager.getProperty("NewAccountPooka.serverName", ""); 248 249 if (userName.equals("")) { 250 throw new Exception ("Must have a username."); 251 } else if (serverName.equals("")) { 252 throw new Exception ("Must have a servername."); 253 } else if (protocol.equals("")) { 254 throw new Exception ("Must have a valid protocol."); 255 } 256 257 accountName = userName + "@" + serverName; 258 259 props.setProperty("Store." + accountName + ".server", serverName); 260 props.setProperty("Store." + accountName + ".user", userName); 261 props.setProperty("Store." + accountName + ".password", password); 262 props.setProperty("Store." + accountName + ".defaultProfile", accountName); 263 props.setProperty("Store." + accountName + ".connection", Pooka.getProperty("Pooka.connection.defaultName", "default")); 264 } else { 265 userName = localUser; 266 accountName = userName + "_local"; 267 } 268 269 271 props.setProperty("UserProfile", accountName); 272 props.setProperty("UserProfile." + accountName + ".mailHeaders.From", accountName); 273 props.setProperty("UserProfile." + accountName + ".mailHeaders.FromPersonal", fullName); 274 props.setProperty("UserProfile." + accountName + ".mailServer", smtpServerName); 275 276 props.setProperty("UserProfile.default", accountName); 277 278 280 props.setProperty("Store", accountName); 281 props.setProperty("Store." + accountName + ".protocol", protocol); 282 283 if (protocol.equalsIgnoreCase("imap")) { 284 props.setProperty("Store." + accountName + ".useSubscribed", "true"); 285 props.setProperty("Store." + accountName + ".SSL", manager.getProperty("NewAccountPooka.useSSL", "false")); 286 props.setProperty("Store." + accountName + ".cachingEnabled", manager.getProperty("NewAccountPooka.enableDisconnected", "false")); 287 } else if (protocol.equalsIgnoreCase("pop3")) { 288 props.setProperty("OutgoingServer." + smtpServerName + ".sendOnConnect", "true"); 289 props.setProperty("Store." + accountName + ".SSL", manager.getProperty("NewAccountPooka.useSSL", "false")); 290 props.setProperty("Store." + accountName + ".leaveMessagesOnServer", manager.getProperty("NewAccountPooka.leaveOnServer", "true")); 291 props.setProperty("Store." + accountName + ".useMaildir", "true"); 292 if (manager.getProperty("NewAccountPooka.leaveOnServer", "true").equalsIgnoreCase("true")) { 293 props.setProperty("Store." + accountName + ".deleteOnServerOnLocalDelete", "true"); 294 } 295 } else if (protocol.equalsIgnoreCase("mbox")) { 296 props.setProperty("Store." + accountName + ".inboxLocation", manager.getProperty("NewAccountPooka.inboxLocation", "/var/spool/mail/" + System.getProperty("user.name"))); 297 } 298 299 return accountName; 300 } 301 302 305 public void testConnections(Properties props) throws Exception { 306 String smtpServer = props.getProperty("OutgoingServer"); 307 308 Pooka.getUIFactory().showStatusMessage("Creating mail store " + smtpServer + "..."); 309 310 Pooka.getUIFactory().showStatusMessage("Connecting to mailserver " + smtpServer + "..."); 311 312 try { 313 testConnection(smtpServer, 25); 314 } catch (Exception smtpException) { 315 throw new Exception ("Error connection to SMTP server:\n" + smtpException.getMessage(), smtpException); 316 } 317 318 String mailServerId = props.getProperty("Store"); 319 String protocol = props.getProperty("Store." + mailServerId + ".protocol"); 320 if (! protocol.equalsIgnoreCase("mbox")) { 321 String mailServerName = props.getProperty("Store." + mailServerId + ".server"); 322 String useSSL = props.getProperty("Store." + mailServerId + ".SSL"); 323 int port = 0; 324 if (protocol.equalsIgnoreCase("pop3")) { 325 if (useSSL.equalsIgnoreCase("true")) 326 port = 995; 327 else 328 port = 110; 329 330 } else if (protocol.equalsIgnoreCase("imap")) { 331 if (useSSL.equalsIgnoreCase("true")) 332 port = 993; 333 else 334 port = 143; 335 } 336 try { 337 testConnection(mailServerName, port); 338 } catch (Exception mailServerException) { 339 throw new Exception ("Error connecting to mail server:\n" + mailServerException.getMessage(), mailServerException); 340 } 341 } else { 342 } 344 } 345 346 349 public void testConnection(String serverName, int port) throws Exception { 350 try { 351 InetAddress addr = InetAddress.getByName(serverName); 352 Socket testSocket = new Socket(addr, port); 353 testSocket.close(); 354 } catch (UnknownHostException uhe) { 355 throw new Exception ("Unknown host: " + serverName); 356 } 357 } 358 359 362 public void setupFolders(Properties props) throws Exception { 363 String storeName = props.getProperty("Store"); 364 String protocol = props.getProperty("Store." + storeName + ".protocol"); 365 String localStoreName = storeName; 366 367 if (protocol.equalsIgnoreCase("imap") && useLocalFiles) { 368 localStoreName = "local"; 371 props.setProperty("Store", storeName + ":local"); 372 props.setProperty("Store.local.useInbox", "false"); 373 props.setProperty("Store.local.folderList", "sent:outbox"); 374 props.setProperty("Store.local.protocol", "maildir"); 375 } else { 376 props.setProperty("Store." + localStoreName + ".folderList", "INBOX:sent:outbox"); 378 } 379 String pookaDirName = props.getProperty("Pooka.cacheDirectory"); 380 String mailDirName = pookaDirName + File.separator + localStoreName; 381 String subFolderDirName = mailDirName + File.separator + manager.getProperty("Pooka.subFolderName", "folders"); 382 383 if (useLocalFiles) { 384 File mailDir = new File (mailDirName); 385 if (! mailDir.exists()) 386 mailDir.mkdirs(); 387 388 File subFolderDir = new File (subFolderDirName); 389 if (! subFolderDir.exists()) 390 subFolderDir.mkdirs(); 391 392 File sentFile = new File (subFolderDirName + File.separator + ".sent"); 393 if (! sentFile.exists()) { 394 sentFile.mkdir(); 395 396 new File (sentFile, "cur").mkdir(); 398 new File (sentFile, "new").mkdir(); 399 new File (sentFile, "tmp").mkdir(); 400 } 401 } 402 403 if (useLocalFiles) { 404 File outboxFile = new File (subFolderDirName + File.separator + ".outbox"); 405 if (! outboxFile.exists()) { 406 outboxFile.mkdir(); 407 408 new File (outboxFile, "cur").mkdir(); 409 new File (outboxFile, "new").mkdir(); 410 new File (outboxFile, "tmp").mkdir(); 411 } 412 413 props.setProperty("Store.local.mailDir", mailDirName); 414 415 } 416 417 418 420 String outgoingServer = props.getProperty("OutgoingServer"); 421 props.setProperty("OutgoingServer." + outgoingServer + ".outbox", localStoreName + "/outbox"); 422 423 String userName = props.getProperty("UserProfile"); 424 props.setProperty("UserProfile." + userName + ".sentFolder", localStoreName + "/sent"); 425 } 426 427 430 public void createFiles(Properties props) throws Exception { 431 if (useLocalFiles) { 432 String pookaDirName = manager.getProperty("NewAccountPooka.pookaDirectory", System.getProperty("user.home") + File.separator + ".pooka"); 433 434 File pookaDir = new File (pookaDirName); 435 if (! pookaDir.exists()) 436 pookaDir.mkdirs(); 437 438 String sslFileName = pookaDirName + File.separator + "sslCertificates"; 439 440 File sslFile = new File (sslFileName); 441 if (!sslFile.exists()) 442 sslFile.createNewFile(); 443 444 props.setProperty("Pooka.cacheDirectory", pookaDirName); 445 props.setProperty("Pooka.defaultMailSubDir", pookaDirName); 446 447 props.setProperty("Pooka.sslCertFile", sslFileName); 448 } 449 450 } 451 452 455 public void setupAddressBook(Properties props) throws java.io.IOException { 456 if (useLocalFiles) { 457 String pookaDirName = manager.getProperty("NewAccountPooka.pookaDirectory", System.getProperty("user.home") + File.separator + ".pooka"); 458 459 String addressBookFileName = pookaDirName + File.separatorChar + "defaultAddressBook"; 460 461 File addressBookFile = new File (addressBookFileName); 462 addressBookFile.createNewFile(); 463 464 props.setProperty("AddressBook", "defaultBook"); 465 props.setProperty("AddressBook.defaultBook.type", "file"); 466 props.setProperty("AddressBook.defaultBook.filename", addressBookFileName); 467 } 468 469 } 470 471 Exception mOpenInboxException = null; 472 boolean mOpenInboxSuccessful = false; 473 476 public void openInbox() throws Exception { 477 java.util.Vector allStores = Pooka.getStoreManager().getStoreList(); 478 net.suberic.pooka.StoreInfo si = null; 479 if (allStores.size() > 0) { 480 si = (net.suberic.pooka.StoreInfo) allStores.get(0); 481 } 482 483 if (si != null) { 484 ActionThread thread = si.getStoreThread(); 485 final net.suberic.pooka.StoreInfo storeInfo = si; 486 487 mOpenInboxException = null; 489 mOpenInboxSuccessful = false; 490 491 javax.swing.Action connectionAction = new javax.swing.AbstractAction () { 492 public void actionPerformed(java.awt.event.ActionEvent ae) { 493 try { 494 storeInfo.connectStore(); 495 javax.swing.SwingUtilities.invokeLater( new Runnable () { 496 497 public void run() { 498 MailTreeNode mtn = null; 499 net.suberic.pooka.FolderInfo fi = storeInfo.getChild("INBOX"); 500 if (fi != null) { 501 FolderNode fn = fi.getFolderNode(); 502 Action openAction = fn.getAction("file-open"); 503 openAction.actionPerformed(new java.awt.event.ActionEvent (this, 0, "file-open")); 504 mtn = fn; 505 } else { 506 mtn = storeInfo.getStoreNode(); 507 } 508 if (mtn != null) { 509 javax.swing.JTree folderTree = ((FolderPanel)mtn.getParentContainer()).getFolderTree(); 510 folderTree.scrollPathToVisible(new javax.swing.tree.TreePath (mtn.getPath())); 511 } 512 513 SwingUtilities.invokeLater(new Runnable () { 514 public void run() { 515 Pooka.getUIFactory().clearStatus(); 516 517 showConfirmation(); 518 } 519 }); 520 } 521 }); 522 } catch (MessagingException me) { 523 final MessagingException error = me; 524 me.printStackTrace(); 525 javax.swing.SwingUtilities.invokeLater( new Runnable () { 526 527 public void run() { 528 Pooka.getUIFactory().clearStatus(); 529 StringBuffer errorMessage = new StringBuffer (Pooka.getProperty("error.NewAccountPooka.connectingToStore", "Failed to connect to store. \nReceived the following error:\n")); 530 errorMessage.append(error.getMessage()); 531 errorMessage.append("\n\n"); 532 errorMessage.append(Pooka.getProperty("error.NewAccountPooka.continueMessage.noCancel", "Would you like to re-enter your information?")); 533 534 JLabel jta = new JLabel(errorMessage.toString()); 535 int continueResponse = JOptionPane.showOptionDialog(Pooka.getMainPanel().getContentPanel().getUIComponent(), errorMessage.toString(), "Failed to connect to Store.", javax.swing.JOptionPane.YES_NO_OPTION, javax.swing.JOptionPane.WARNING_MESSAGE, null, new Object [] { "Re-enter", "Continue" }, "Re-enter"); 536 if (continueResponse == 0) { 537 showFirstEntryWindow(); 538 } 539 } 540 }); 541 } 542 } 543 }; 544 545 thread.addToQueue(connectionAction, new java.awt.event.ActionEvent (this, 0, "connectStore")); 546 } 547 548 } 549 550 public void showConfirmation() { 551 JOptionPane.showInternalMessageDialog(getMessagePanel(), Pooka.getProperty("NewAccountPooka.finishedMessage", "Email account configured! If you need to make changes,\nor to add new accounts, go to the Configuration menu."), Pooka.getProperty("NewAccountPooka.finishedMessage.title", "Done!"), JOptionPane.INFORMATION_MESSAGE); 552 553 } 554 555 public int handleInvalidEntry(String message) { 556 StringBuffer errorMessage = new StringBuffer (Pooka.getProperty("error.NewAccountPooka.invalidEntry", "invalid first entry.")); 557 if (message != null && message.length() > 0) { 558 errorMessage.append("\n"); 559 errorMessage.append(message); 560 } 561 errorMessage.append("\n\n"); 562 errorMessage.append(Pooka.getProperty("error.NewAccountPooka.continueMessage", "Would you like to re-enter your information?")); 563 571 JLabel jta = new JLabel(errorMessage.toString()); 572 int continueResponse = JOptionPane.showOptionDialog(Pooka.getMainPanel().getContentPanel().getUIComponent(), errorMessage.toString(), "Failed to connect to Store.", javax.swing.JOptionPane.YES_NO_OPTION, javax.swing.JOptionPane.WARNING_MESSAGE, null, new Object [] { "Re-enter", "Continue", "Cancel" }, "Re-enter"); 573 if (continueResponse == 0) { 574 return JOptionPane.YES_OPTION; 575 } else if (continueResponse == 1) { 576 return JOptionPane.NO_OPTION; 577 } else { 578 return JOptionPane.CANCEL_OPTION; 579 } 580 581 } 582 583 587 public void saveProperties(Properties props) { 588 Enumeration names = props.propertyNames(); 589 while (names.hasMoreElements()) { 590 String propertyName = (String ) names.nextElement(); 591 if (propertyName.equals("UserProfile") || propertyName.equals("Store") || propertyName.equals("OutgoingServer") || propertyName.equals("AddressBook")) { 592 } else { 594 transferProperty(props, propertyName); 595 } 596 } 597 598 transferProperty(props, "UserProfile"); 599 600 transferProperty(props, "Store"); 601 602 transferProperty(props, "OutgoingServer"); 603 604 if (useLocalFiles) { 605 transferProperty(props, "AddressBook"); 606 } 607 } 608 609 613 public void transferProperty(Properties props, String propertyName) { 614 if (!(props.getProperty(propertyName, "").equals(""))) { 615 Pooka.setProperty(propertyName, props.getProperty(propertyName, "")); 616 } 617 } 618 619 622 private void setupDefaultConnection() { 623 String defaultName = Pooka.getProperty("Pooka.connection.defaultName", "default"); 624 Pooka.setProperty("Connection." + defaultName + ".valueOnStartup", "Connected"); 625 Pooka.setProperty("Connection", defaultName); 626 Pooka.setProperty("Connection._default", defaultName); 627 } 628 629 630 public MessagePanel getMessagePanel() { 631 return messagePanel; 632 } 633 634 public void setMessagePanel(MessagePanel newValue) { 635 messagePanel=newValue; 636 } 637 638 public PropertyEditorFactory getFactory() { 639 return factory; 640 } 641 642 public void setFactory(PropertyEditorFactory newValue) { 643 factory=newValue; 644 } 645 646 } 647 | Popular Tags |