1 package net.suberic.pooka; 2 import net.suberic.pooka.filter.FilterAction; 3 import net.suberic.pooka.gui.MessageProxy; 4 import net.suberic.util.thread.*; 5 import javax.mail.*; 6 import javax.mail.internet.MimeBodyPart ; 7 import javax.mail.internet.MimeMessage ; 8 import javax.mail.event.*; 9 import javax.swing.*; 10 import java.util.Hashtable ; 11 import java.util.Vector ; 12 import java.util.logging.Logger ; 13 import java.util.logging.Level ; 14 import java.io.*; 15 16 public class MessageInfo { 17 Message message; 19 20 FolderInfo folderInfo; 22 23 boolean loaded = false; 25 26 boolean seen = false; 28 29 boolean attachmentsLoaded = false; 31 32 MessageProxy messageProxy; 34 35 AttachmentBundle attachments; 37 38 MessageCryptoInfo cryptoInfo = new MessageCryptoInfo(this); 40 41 boolean fetched = false; 43 44 public static int FORWARD_AS_ATTACHMENT = 0; 45 public static int FORWARD_QUOTED = 1; 46 public static int FORWARD_AS_INLINE = 2; 47 48 protected MessageInfo() { 49 } 50 51 54 public MessageInfo(Message newMessage, FolderInfo newFolderInfo) { 55 folderInfo = newFolderInfo; 56 message = newMessage; 57 } 58 59 62 public void loadAttachmentInfo() throws MessagingException { 63 try { 64 attachments = MailUtilities.parseAttachments(getMessage()); 66 attachmentsLoaded = true; 67 if (Pooka.getProperty("EncryptionManager.autoDecrypt", "false").equalsIgnoreCase("true") && cryptoInfo.isEncrypted()) { 68 UserProfile p = getDefaultProfile(); 69 if (p == null) 70 p = Pooka.getPookaManager().getUserProfileManager().getDefaultProfile(); 71 72 if (cryptoInfo.autoDecrypt(p)) { 73 } 75 } 76 77 if (Pooka.getProperty("EncryptionManager.autoCheckSig", "false").equalsIgnoreCase("true") && cryptoInfo.isSigned()) { 78 if (cryptoInfo.autoCheckSignature((javax.mail.internet.InternetAddress ) getMessage().getFrom()[0])) { 79 } 81 } 82 83 } catch (MessagingException me) { 84 try { 87 javax.mail.internet.MimeMessage mimeMessage = (javax.mail.internet.MimeMessage )getMessage(); 88 AttachmentBundle bundle = new AttachmentBundle(mimeMessage); 89 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 90 java.util.List headerList = new java.util.ArrayList (); 91 java.util.Enumeration headerEnum = mimeMessage.getAllHeaders(); 92 while (headerEnum.hasMoreElements()) { 93 Header hdr = (Header) headerEnum.nextElement(); 94 headerList.add(hdr.getName()); 95 } 96 String [] excludeList = (String []) headerList.toArray(new String [0]); 97 mimeMessage.writeTo(baos, excludeList); 98 String content = baos.toString("ISO-8859-1"); 99 MimeBodyPart mbp = new MimeBodyPart (); 100 mbp.setText(content); 101 Attachment textPart = new Attachment(mbp); 102 bundle.addAttachment(textPart); 103 104 attachments = bundle; 105 } catch (Exception e) { 106 throw me; 107 } 108 } catch (java.io.IOException ioe) { 109 throw new MessagingException("Error loading Message: " + ioe.toString(), ioe); 110 } 111 112 } 113 114 117 public boolean flagIsSet(String flagName) throws MessagingException { 118 if (Thread.currentThread() != getFolderInfo().getFolderThread() && ! (Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread)) { 119 Logger folderLogger = getFolderInfo().getLogger(); 120 if (folderLogger.isLoggable(Level.WARNING)) { 121 folderLogger.log(Level.WARNING, "Accessing Message Flags not on Folder Thread."); 122 Thread.currentThread().dumpStack(); 123 } 124 } 125 126 if (flagName.equals("FLAG.ANSWERED") ) 127 return getMessage().isSet(Flags.Flag.ANSWERED); 128 else if (flagName.equals("FLAG.DELETED")) 129 return getMessage().isSet(Flags.Flag.DELETED); 130 else if (flagName.equals("FLAG.DRAFT")) 131 return getMessage().isSet(Flags.Flag.DRAFT); 132 else if (flagName.equals("FLAG.FLAGGED")) 133 return getMessage().isSet(Flags.Flag.FLAGGED); 134 else if (flagName.equals("FLAG.RECENT")) 135 return getMessage().isSet(Flags.Flag.RECENT); 136 else if (flagName.equals("FLAG.SEEN")) { 137 if (folderInfo != null && ! folderInfo.tracksUnreadMessages()) 138 return true; 139 else 140 return getMessage().isSet(Flags.Flag.SEEN); 141 } 142 143 return false; 144 } 145 146 149 public Flags getFlags() throws MessagingException { 150 if (Thread.currentThread() != getFolderInfo().getFolderThread() && ! (Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread)) { 151 Logger folderLogger = getFolderInfo().getLogger(); 152 if (folderLogger.isLoggable(Level.WARNING)) { 153 folderLogger.log(Level.WARNING, "Accessing Message Flags not on Folder Thread."); 154 Thread.currentThread().dumpStack(); 155 156 } 157 } 158 return getMessage().getFlags(); 159 } 160 161 164 public void refreshFlags() throws MessagingException { 165 if (Thread.currentThread() != getFolderInfo().getFolderThread() && ! (Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread)) { 166 Logger folderLogger = getFolderInfo().getLogger(); 167 if (folderLogger.isLoggable(Level.WARNING)) { 168 folderLogger.log(Level.WARNING, "Accessing Message Flags not on Folder Thread."); 169 Thread.currentThread().dumpStack(); 170 171 } 172 } 173 getFolderInfo().refreshFlags(this); 174 } 175 176 179 public void refreshHeaders() throws MessagingException { 180 if (Thread.currentThread() != getFolderInfo().getFolderThread() && ! (Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread)) { 181 Logger folderLogger = getFolderInfo().getLogger(); 182 if (folderLogger.isLoggable(Level.WARNING)) { 183 folderLogger.log(Level.WARNING, "Accessing Message Headers not on Folder Thread."); 184 Thread.currentThread().dumpStack(); 185 186 } 187 } 188 getFolderInfo().refreshHeaders(this); 189 } 190 191 195 public Object getMessageProperty(String prop) throws MessagingException { 196 if (getFolderInfo() != null && Thread.currentThread() != getFolderInfo().getFolderThread() && ! (Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread)) { 197 Logger folderLogger = getFolderInfo().getLogger(); 198 if (folderLogger.isLoggable(Level.WARNING)) { 199 folderLogger.log(Level.WARNING, "Getting Message Property not on Folder Thread."); 200 Thread.currentThread().dumpStack(); 201 202 } 203 } 204 Message msg = getMessage(); 205 if (prop.equals("From")) { 206 try { 207 Address[] fromAddr = msg.getFrom(); 208 return MailUtilities.decodeAddressString(fromAddr); 209 } catch (javax.mail.internet.AddressException ae) { 210 return ((MimeMessage ) msg).getHeader("From", ","); 211 } 212 } else if (prop.equalsIgnoreCase("receivedDate")) { 213 return msg.getReceivedDate(); 214 } else if (prop.equalsIgnoreCase("recipients")) { 215 return msg.getAllRecipients(); 216 } else if (prop.equalsIgnoreCase("to")) { 217 return MailUtilities.decodeAddressString(msg.getRecipients(Message.RecipientType.TO)); 218 } else if (prop.equalsIgnoreCase("cc")) { 219 return MailUtilities.decodeAddressString(msg.getRecipients(Message.RecipientType.CC)); 220 } else if (prop.equalsIgnoreCase("bcc")) { 221 return MailUtilities.decodeAddressString(msg.getRecipients(Message.RecipientType.BCC)); 222 } else if (prop.equalsIgnoreCase("Date")) { 223 return msg.getSentDate(); 224 } else if (prop.equalsIgnoreCase("Subject")) { 225 return MailUtilities.decodeText(msg.getSubject()); 226 } 227 228 if (msg instanceof MimeMessage ) { 229 String hdrVal = ((MimeMessage )msg).getHeader(prop, ","); 230 if (hdrVal != null && hdrVal.length() > 0) 231 return MailUtilities.decodeText(hdrVal); 232 } 233 return ""; 234 } 235 236 239 public String getTextAndTextInlines(String attachmentSeparator, boolean withHeaders, boolean showFullHeaders, int maxLength, String truncationMessage) throws MessagingException { 240 try { 241 if (!hasLoadedAttachments()) 242 loadAttachmentInfo(); 243 return attachments.getTextAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, maxLength, truncationMessage); 244 } catch (FolderClosedException fce) { 245 try { 246 if (getFolderInfo().shouldBeConnected()) { 247 getFolderInfo().openFolder(Folder.READ_WRITE); 248 loadAttachmentInfo(); 249 return attachments.getTextAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, maxLength, truncationMessage); 250 } else { 251 throw fce; 252 } 253 } catch (java.io.IOException ioe) { 254 throw new MessagingException(ioe.getMessage()); 255 } 256 } catch (java.io.IOException ioe) { 257 ioe.printStackTrace(); 258 throw new MessagingException(ioe.getMessage()); 259 } 260 } 261 262 265 public String getTextAndTextInlines(String attachmentSeparator, boolean withHeaders, boolean showFullHeaders) throws MessagingException { 266 return getTextAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getTruncationMessage()); 267 } 268 269 272 public String getTextAndTextInlines(boolean withHeaders, boolean showFullHeaders) throws MessagingException { 273 return getTextAndTextInlines(getAttachmentSeparator(), withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getTruncationMessage()); 274 } 275 276 281 public String getTextPart(boolean withHeaders, boolean showFullHeaders, int maxLength, String truncationMessage) throws MessagingException { 282 try { 283 if (!hasLoadedAttachments()) 284 loadAttachmentInfo(); 285 String returnValue = attachments.getTextPart(withHeaders, showFullHeaders, maxLength, truncationMessage); 286 if (returnValue != null) 287 return returnValue; 288 else 289 return getHtmlPart(withHeaders, showFullHeaders, maxLength, getHtmlTruncationMessage()); 290 } catch (FolderClosedException fce) { 291 try { 292 if (getFolderInfo().shouldBeConnected()) { 293 getFolderInfo().openFolder(Folder.READ_WRITE); 294 loadAttachmentInfo(); 295 String returnValue = attachments.getTextPart(withHeaders, showFullHeaders, maxLength, truncationMessage); 296 if (returnValue != null) 297 return returnValue; 298 else 299 return getHtmlPart(withHeaders, showFullHeaders, maxLength, getHtmlTruncationMessage()); 300 } else { 301 throw fce; 302 } 303 } catch (java.io.IOException ioe) { 304 throw new MessagingException(ioe.getMessage()); 305 } 306 } catch (java.io.IOException ioe) { 307 throw new MessagingException(ioe.getMessage()); 308 } 309 } 310 311 316 public String getTextPart(boolean withHeaders, boolean showFullHeaders) throws MessagingException { 317 return getTextPart(withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getTruncationMessage()); 318 } 319 320 323 public String getHtmlPart(boolean withHeaders, boolean showFullHeaders, int maxLength, String truncationMessage) throws MessagingException { 324 try { 325 if (!hasLoadedAttachments()) 326 loadAttachmentInfo(); 327 return attachments.getHtmlPart(withHeaders, showFullHeaders, maxLength, truncationMessage); 328 } catch (FolderClosedException fce) { 329 try { 330 if (getFolderInfo().shouldBeConnected()) { 331 getFolderInfo().openFolder(Folder.READ_WRITE); 332 loadAttachmentInfo(); 333 return attachments.getHtmlPart(withHeaders, showFullHeaders, maxLength, truncationMessage); 334 } else { 335 throw fce; 336 } 337 } catch (java.io.IOException ioe) { 338 throw new MessagingException(ioe.getMessage()); 339 } 340 } catch (java.io.IOException ioe) { 341 throw new MessagingException(ioe.getMessage()); 342 } 343 } 344 345 348 public String getHtmlPart(boolean withHeaders, boolean showFullHeaders) throws MessagingException { 349 return getHtmlPart(withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getTruncationMessage()); 350 } 351 352 355 public String getHtmlAndTextInlines(String attachmentSeparator, boolean withHeaders, boolean showFullHeaders, int maxLength, String truncationMessage) throws MessagingException { 356 try { 357 if (!hasLoadedAttachments()) 358 loadAttachmentInfo(); 359 return attachments.getHtmlAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, maxLength, truncationMessage); 360 } catch (FolderClosedException fce) { 361 try { 362 if (getFolderInfo().shouldBeConnected()) { 363 getFolderInfo().openFolder(Folder.READ_WRITE); 364 loadAttachmentInfo(); 365 return attachments.getHtmlAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, maxLength, truncationMessage); 366 } else { 367 throw fce; 368 } 369 } catch (java.io.IOException ioe) { 370 throw new MessagingException(ioe.getMessage()); 371 } 372 } catch (java.io.IOException ioe) { 373 throw new MessagingException(ioe.getMessage()); 374 } 375 } 376 377 380 public String getHtmlAndTextInlines(String attachmentSeparator, boolean withHeaders, boolean showFullHeaders) throws MessagingException { 381 return getHtmlAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getHtmlTruncationMessage()); 382 } 383 384 387 public String getHtmlAndTextInlines(boolean withHeaders, boolean showFullHeaders) throws MessagingException { 388 return getHtmlAndTextInlines(getHtmlAttachmentSeparator(), withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getHtmlTruncationMessage()); 389 } 390 391 394 public String getRawText() throws MessagingException { 395 try { 396 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 397 MimeMessage mm = (MimeMessage ) getMessage(); 398 mm.writeTo(baos); 399 return baos.toString(); 400 } catch (IOException ioe) { 401 MessagingException returnValue = new MessagingException("Error reading Message Stream", ioe); 402 throw returnValue; 403 } 404 } 405 406 409 public void moveMessage(FolderInfo targetFolder, boolean expunge) throws MessagingException { 410 try { 411 folderInfo.copyMessages(new MessageInfo[] { this }, targetFolder); 412 } catch (MessagingException me) { 413 MessagingException returnValue = new MessagingException (Pooka.getProperty("error.Message.CopyErrorMessage", "Error: could not copy messages to folder: ") + targetFolder.toString() +"\n", me); 414 throw returnValue; 415 } 416 417 try { 418 remove(expunge); 419 } catch (MessagingException me) { 420 MessagingException returnValue = new MessagingException(Pooka.getProperty("error.Message.RemoveErrorMessage", "Error: could not remove messages from folder: ") + targetFolder.toString() +"\n", me); 421 throw returnValue; 422 } 423 } 424 425 428 public void copyMessage(FolderInfo targetFolder) throws MessagingException { 429 try { 430 folderInfo.copyMessages(new MessageInfo[] { this }, targetFolder); 431 } catch (MessagingException me) { 432 MessagingException returnValue = new MessagingException (Pooka.getProperty("error.Message.CopyErrorMessage", "Error: could not copy messages to folder: ") + targetFolder.toString() +"\n", me); 433 throw returnValue; 434 } 435 436 } 437 438 443 public void moveMessage(FolderInfo targetFolder) throws MessagingException { 444 moveMessage(targetFolder, Pooka.getProperty("Pooka.autoExpunge", "true").equals("true")); 445 } 446 447 450 public void bounceMessage(Address[] recipientList) throws javax.mail.MessagingException { 451 452 MimeMessage mm = (MimeMessage )getMessage(); 453 MimeMessage mmClone = new MimeMessage (mm); 454 455 NewMessageInfo nmi = new NewMessageInfo(mmClone); 456 net.suberic.pooka.gui.NewMessageProxy nmp = new net.suberic.pooka.gui.NewMessageProxy(nmi); 457 java.util.HashMap messageMap = new java.util.HashMap (); 458 messageMap.put(mmClone, recipientList); 459 460 nmi.setSendMessageMap(messageMap); 461 462 final NewMessageInfo final_nmi = nmi; 463 464 UserProfile p = getDefaultProfile(); 465 if (p == null) 466 p = Pooka.getPookaManager().getUserProfileManager().getDefaultProfile(); 467 468 if (p != null && p.getMailServer() != null) { 469 final OutgoingMailServer mailServer = p.getMailServer(); 470 mailServer.mailServerThread.addToQueue(new javax.swing.AbstractAction () { 471 public void actionPerformed(java.awt.event.ActionEvent ae) { 472 mailServer.sendMessage(final_nmi); 473 } 474 }, new java.awt.event.ActionEvent (this, 0, "message-send")); 475 } 476 } 477 478 485 public void deleteMessage(boolean autoExpunge) throws MessagingException { 486 FolderInfo trashFolder = getFolderInfo().getTrashFolder(); 487 if ((getFolderInfo().useTrashFolder()) && (trashFolder != null) && (trashFolder != getFolderInfo())) { 488 try { 489 moveMessage(trashFolder, autoExpunge); 490 } catch (MessagingException me) { 491 throw new MessagingException(Pooka.getProperty("error.Messsage.DeleteNoTrashFolder", "No trash folder available."), me); 492 } 493 } else { 494 495 497 try { 498 remove(autoExpunge); 499 } catch (MessagingException me) { 500 me.printStackTrace(); 501 throw new MessagingException(Pooka.getProperty("error.Message.DeleteErrorMessage", "Error: could not delete message.") +"\n", me); 502 } 503 } 504 505 if (getMessageProxy() != null) 506 getMessageProxy().close(); 507 } 508 509 514 public void deleteMessage() throws MessagingException { 515 deleteMessage(Pooka.getProperty("Pooka.autoExpunge", "true").equals("true")); 516 } 517 518 528 public void remove(boolean autoExpunge) throws MessagingException { 529 Message m = getMessage(); 530 if (m != null) { 531 m.setFlag(Flags.Flag.DELETED, true); 532 if ( autoExpunge ) { 533 folderInfo.expunge(); 534 } 535 } 536 } 537 538 542 public String prefixMessage(String originalMessage, String prefix, String intro) { 543 StringBuffer newValue = new StringBuffer (originalMessage); 544 545 int currentCR = originalMessage.lastIndexOf('\n', originalMessage.length()); 546 while (currentCR != -1) { 547 newValue.insert(currentCR+1, prefix); 548 currentCR=originalMessage.lastIndexOf('\n', currentCR-1); 549 } 550 newValue.insert(0, prefix); 551 newValue.insert(0, intro); 552 553 return newValue.toString(); 554 } 555 556 563 public String parseMsgString(MimeMessage m, String introTemplate, boolean addLF) { 564 StringBuffer intro = new StringBuffer (introTemplate); 565 int index = introTemplate.lastIndexOf('%', introTemplate.length()); 566 try { 567 while (index > -1) { 568 try { 569 char nextChar = introTemplate.charAt(index + 1); 570 String replaceMe = null; 571 if (nextChar == Pooka.getProperty("Pooka.parsedString.nameChar", "n").charAt(0)) { 572 573 Address[] fromAddresses = m.getFrom(); 574 if (fromAddresses.length > 0 && fromAddresses[0] != null) { 575 replaceMe = MailUtilities.decodeAddressString(fromAddresses); 576 if (replaceMe == null) 577 replaceMe = ""; 578 intro.replace(index, index +2, replaceMe); 579 } 580 } else if (nextChar == Pooka.getProperty("Pooka.parsedString.dateChar", "d").charAt(0)) { 581 replaceMe = Pooka.getDateFormatter().fullDateFormat.format(m.getSentDate()); 582 if (replaceMe == null) 583 replaceMe = ""; 584 intro.replace(index, index + 2, replaceMe); 585 } else if (nextChar == Pooka.getProperty("Pooka.parsedString.subjChar", "s").charAt(0)) { 586 replaceMe = m.getSubject(); 587 if (replaceMe == null) 588 replaceMe = ""; 589 intro.replace(index, index + 2, replaceMe); 590 } else if (nextChar == '%') { 591 intro.replace(index, index+1, "%"); 592 } 593 index = introTemplate.lastIndexOf('%', index -1); 594 } catch (StringIndexOutOfBoundsException e) { 595 index = introTemplate.lastIndexOf('%', index -1); 596 } 597 } 598 } catch (MessagingException me) { 599 return null; 600 } 601 602 if (addLF) 603 if (intro.charAt(intro.length()-1) != '\n') 604 intro.append('\n'); 605 606 return intro.toString(); 607 } 608 609 613 public NewMessageInfo populateReply(boolean replyAll, boolean withAttachments) 614 throws MessagingException { 615 MimeMessage newMsg = (MimeMessage ) getMessage().reply(replyAll); 616 617 MimeMessage mMsg = (MimeMessage ) getMessage(); 618 619 String textPart = getTextPart(false, false, getMaxMessageDisplayLength(), getTruncationMessage()); 620 if (textPart == null) { 621 textPart = ""; 622 } 623 624 if (isHtml()) { 625 net.suberic.pooka.htmlparser.PookaStringBean psb = new net.suberic.pooka.htmlparser.PookaStringBean(); 626 psb.setContent(textPart, null); 627 textPart = psb.getStrings(); 628 } 629 630 if (textPart == null) { 631 textPart = ""; 632 } 633 634 UserProfile up = getDefaultProfile(); 635 if (up == null) 636 up = Pooka.getPookaManager().getUserProfileManager().getDefaultProfile(); 637 638 String parsedText; 639 String replyPrefix; 640 String parsedIntro; 641 642 if (up != null && up.getMailProperties() != null) { 643 replyPrefix = up.getMailProperties().getProperty("replyPrefix", Pooka.getProperty("Pooka.replyPrefix", "> ")); 644 parsedIntro = parseMsgString(mMsg, up.getMailProperties().getProperty("replyIntro", Pooka.getProperty("Pooka.replyIntro", "On %d, %n wrote:")), true); 645 } else { 646 replyPrefix = Pooka.getProperty("Pooka.replyPrefix", "> "); 647 parsedIntro = parseMsgString(mMsg, Pooka.getProperty("Pooka.replyIntro", "On %d, %n wrote:"), true); 648 } 649 parsedText = prefixMessage(textPart, replyPrefix, parsedIntro); 650 newMsg.setText(parsedText); 651 652 if (replyAll && Pooka.getProperty("Pooka.excludeSelfInReply", "true").equalsIgnoreCase("true")) { 653 up.removeFromAddress(newMsg); 654 } 655 656 NewMessageInfo returnValue = new NewMessageInfo(newMsg); 657 658 if (withAttachments) { 659 returnValue.attachments = new AttachmentBundle(); 660 returnValue.attachments.addAll(attachments); 661 returnValue.attachmentsLoaded=true; 662 } 663 664 return returnValue; 665 } 666 667 671 public NewMessageInfo populateReply(boolean replyAll) 672 throws MessagingException { 673 return populateReply(replyAll, false); 674 } 675 676 680 public NewMessageInfo populateForward(boolean withAttachments, int method) 681 throws MessagingException { 682 MimeMessage mMsg = (MimeMessage ) getMessage(); 683 MimeMessage newMsg = new MimeMessage (Pooka.getDefaultSession()); 684 685 String parsedText = ""; 686 687 if (method == FORWARD_QUOTED) { 688 String textPart = getTextPart(false, false, getMaxMessageDisplayLength(), getTruncationMessage()); 689 690 UserProfile up = getDefaultProfile(); 691 if (up == null) { 692 up = Pooka.getPookaManager().getUserProfileManager().getDefaultProfile(); 693 } 694 695 String forwardPrefix; 696 String parsedIntro; 697 698 if (up != null && up.getMailProperties() != null) { 699 forwardPrefix = up.getMailProperties().getProperty("forwardPrefix", Pooka.getProperty("Pooka.forwardPrefix", "> ")); 700 parsedIntro = parseMsgString(mMsg, up.getMailProperties().getProperty("forwardIntro", Pooka.getProperty("Pooka.forwardIntro", "Forwarded message from %n:")), true); 701 } else { 702 forwardPrefix = Pooka.getProperty("Pooka.forwardPrefix", "> "); 703 parsedIntro = parseMsgString(mMsg, Pooka.getProperty("Pooka.forwardIntro", "Forwarded message from %n:"), true); 704 } 705 parsedText = prefixMessage(textPart, forwardPrefix, parsedIntro); 706 707 } else if (method == FORWARD_AS_INLINE) { 708 709 String textPart = getTextPart(true, false, getMaxMessageDisplayLength(), getTruncationMessage()); 710 711 parsedText = Pooka.getProperty("Pooka.forwardInlineIntro", "---------- Original Message ----------\n") + textPart; 712 713 } 714 715 newMsg.setText(parsedText); 716 newMsg.setSubject(parseMsgString(mMsg, Pooka.getProperty("Pooka.forwardSubject", "Fwd: %s"), false)); 717 718 NewMessageInfo returnValue = new NewMessageInfo(newMsg); 719 720 if (method == FORWARD_AS_ATTACHMENT) { 722 UpdatableMBP mbp = new UpdatableMBP(); 723 mbp.setContent(getRealMessage(), "message/rfc822"); 724 mbp.updateMyHeaders(); 725 String subject = (String ) getMessageProperty("Subject"); 726 if (subject != null && subject.length() > 0) { 727 mbp.setFileName(subject); 728 } else { 729 mbp.setFileName("forwarded message"); 730 } 731 mbp.setDisposition(Part.ATTACHMENT); 732 733 AttachmentBundle returnAttachments = returnValue.getAttachmentBundle(); 734 Attachment messageAttachment = new MBPAttachment(mbp); 735 returnAttachments.addAttachment(messageAttachment, false); 736 737 738 } else if (withAttachments) { 739 returnValue.attachments = new AttachmentBundle(); 740 Vector fromAttachments = attachments.getAttachments(); 741 if (fromAttachments != null) { 742 AttachmentBundle returnAttachments = returnValue.getAttachmentBundle(); 743 for (int i = 0; i < fromAttachments.size(); i++) { 744 Attachment current = (Attachment) fromAttachments.elementAt(i); 745 Attachment newAttachment = null; 746 747 MimeBodyPart mbp = new MimeBodyPart (); 748 mbp.setDataHandler(current.getDataHandler()); 749 newAttachment = new MBPAttachment(mbp); 750 returnAttachments.addAttachment(newAttachment, false); 751 } 752 } 753 } 754 755 return returnValue; 756 } 757 758 762 public NewMessageInfo populateForward() 763 throws MessagingException { 764 return populateForward(false, FORWARD_QUOTED); 765 } 766 767 770 public void runBackendFilters() { 771 FolderInfo fi = getFolderInfo(); 772 java.util.LinkedList list = new java.util.LinkedList (); 773 list.add(getMessageProxy()); 774 fi.applyFilters(list); 775 } 776 777 780 public void runSpamAction() { 781 FilterAction spamFilter = null; 782 try { 783 spamFilter = MessageFilter.generateFilterAction("Pooka.spamAction"); 784 } catch (Exception e) { 785 int configureNow = Pooka.getUIFactory().showConfirmDialog("Spam action currently not configured. Would you like to configure it now?", "Configure Spam action", javax.swing.JOptionPane.YES_NO_OPTION); 786 if (configureNow == javax.swing.JOptionPane.YES_OPTION) { 787 Pooka.getUIFactory().showEditorWindow(Pooka.getProperty("Preferences.Spam.label", "Spam"), "Pooka.spamAction"); 789 } 790 791 } 792 if (spamFilter != null) { 793 Vector v = new Vector (); 794 v.add(this.getMessageProxy()); 795 java.util.List removed = spamFilter.performFilter(v); 796 if (removed != null && removed.size() > 0) { 797 try { 798 getFolderInfo().expunge(); 799 } catch (MessagingException me) { 800 } 802 } 803 return; 804 } 805 } 806 807 810 public void cacheMessage() throws MessagingException { 811 FolderInfo fi = getFolderInfo(); 812 if (fi != null && fi instanceof net.suberic.pooka.cache.CachingFolderInfo) { 813 ((net.suberic.pooka.cache.CachingFolderInfo) fi).cacheMessage(this, net.suberic.pooka.cache.MessageCache.MESSAGE); 814 815 } 816 } 817 818 824 public UserProfile getDefaultProfile() { 825 if (getFolderInfo() != null) { 826 return getFolderInfo().getDefaultProfile(); 827 } else 828 return null; 829 } 830 831 834 public void saveMessageAs(File saveFile) throws MessagingException{ 835 try { 836 FileOutputStream fos = new FileOutputStream(saveFile); 837 ((MimeMessage )getMessage()).writeTo(fos); 838 } catch (IOException ioe) { 839 MessagingException me = new MessagingException(Pooka.getProperty("error.errorCreatingAttachment", "Error attaching message")); 840 me.setNextException(ioe); 841 throw me; 842 843 } 844 } 845 846 849 public void addAddress(AddressBook book, boolean useVcard) throws MessagingException { 850 boolean found = false; 851 if (useVcard) { 852 Attachment vcard = null; 853 854 Vector attachList = getAttachments(); 856 if (attachList != null) { 857 for (int i = 0; i < attachList.size() && vcard==null; i++) { 858 Attachment current = (Attachment)attachList.get(i); 859 if (current.getMimeType().match("text/x-vcard")) { 860 vcard = current; 861 } 862 } 863 864 if (vcard != null) { 865 try { 866 String vcardText = (String ) vcard.getContent(); 867 BufferedReader reader = new BufferedReader(new StringReader(vcardText)); 868 net.suberic.pooka.vcard.Vcard addressEntry = net.suberic.pooka.vcard.Vcard.parse(reader); 869 book.addAddress(addressEntry); 870 found = true; 871 } catch (Exception e) { 872 getMessageProxy().showError(Pooka.getProperty("error.parsingVcard", "Error parsing Vcard"), e); 876 } 877 } 878 } 879 } 880 881 if (!found) { 882 Address[] fromAddresses = getMessage().getFrom(); 883 javax.mail.internet.InternetAddress addr = (javax.mail.internet.InternetAddress ) fromAddresses[0]; 884 885 AddressBookEntry entry = book.newAddressBookEntry(); 888 889 String personalName = addr.getPersonal(); 890 if (personalName == null) 891 personalName = addr.getAddress(); 892 893 entry.setPersonalName(personalName); 894 entry.setAddress(addr); 895 book.addAddress(entry); 896 } 897 } 898 899 902 public Message getMessage() { 903 return message; 904 } 905 906 910 public Message getRealMessage() throws MessagingException { 911 if (getFolderInfo() != null) { 912 return getFolderInfo().getRealMessage(this); 913 } 914 return message; 915 } 916 917 920 public FolderInfo getFolderInfo() { 921 return folderInfo; 922 } 923 924 928 public boolean isSeen() { 929 930 if (folderInfo != null && ! folderInfo.tracksUnreadMessages()) { 931 return true; 932 } else 933 try { 934 return flagIsSet("FLAG.SEEN"); 935 } catch (MessagingException me) { 936 return true; 937 } 938 } 939 940 944 public void setSeen(boolean newValue) throws MessagingException { 945 if (folderInfo != null && ! folderInfo.tracksUnreadMessages()) 946 return; 947 else { 948 boolean seen = isSeen(); 949 if (newValue != seen) { 950 Message m = getMessage(); 952 m.setFlag(Flags.Flag.SEEN, newValue); 953 getFolderInfo().fireMessageChangedEvent(new MessageChangedEvent(this, MessageChangedEvent.FLAGS_CHANGED, getMessage())); 954 } 955 } 956 } 957 958 public boolean isLoaded() { 959 return loaded; 960 } 961 962 967 public void unloadTableInfo() { 968 loaded=false; 969 } 970 971 public boolean hasLoadedAttachments() { 972 return attachmentsLoaded; 973 } 974 975 boolean mHasAttachments = false; 976 boolean mHasCheckedAttachments = false; 977 978 981 public boolean hasAttachments() throws MessagingException { 982 if (mHasCheckedAttachments) { 983 return mHasAttachments; 984 } else { 985 if (hasLoadedAttachments()) { 986 if (getAttachments() != null && getAttachments().size() > 0) 987 mHasAttachments = true; 988 989 mHasCheckedAttachments = true; 990 991 return mHasAttachments; 992 993 } else { 994 try { 995 javax.mail.internet.ContentType type = new javax.mail.internet.ContentType (getMessage().getContentType()); 996 if (new String ("multipart").equalsIgnoreCase(type.getPrimaryType()) && ! new String ("alternative").equalsIgnoreCase(type.getSubType())) { 997 return true; 998 } else { 999 return false; 1000 } 1001 } catch (javax.mail.internet.ParseException pe) { 1002 if (Pooka.isDebug()) { 1003 System.out.println("unable to parse content-type: " + getMessage().getContentType()); 1004 } 1005 mHasAttachments = false; 1006 } 1007 } 1008 } 1009 1010 return mHasAttachments; 1011 } 1012 1013 1016 public boolean hasEncryption() throws MessagingException { 1017 return (cryptoInfo.isEncrypted() || cryptoInfo.isSigned()); 1018 } 1019 1020 1023 public MessageCryptoInfo getCryptoInfo() { 1024 return cryptoInfo; 1025 } 1026 1027 1031 public Vector getAttachments() throws MessagingException { 1032 if (hasLoadedAttachments()) 1033 return attachments.getAttachments(getMaxMessageDisplayLength()); 1034 else { 1035 loadAttachmentInfo(); 1036 return attachments.getAttachments(getMaxMessageDisplayLength()); 1037 } 1038 1039 } 1040 1041 1044 AttachmentBundle getAttachmentBundle() throws MessagingException { 1045 if (hasLoadedAttachments()) 1046 return attachments; 1047 else { 1048 loadAttachmentInfo(); 1049 return attachments; 1050 } 1051 } 1052 1053 1056 public MessageProxy getMessageProxy() { 1057 return messageProxy; 1058 } 1059 1060 1063 public void setMessageProxy(MessageProxy newMp) { 1064 messageProxy = newMp; 1065 } 1066 1067 1070 public int getMaxMessageDisplayLength() { 1071 int displayLength = 10000; 1072 try { 1073 displayLength = Integer.parseInt(Pooka.getProperty("Pooka.attachmentDisplayMaxLength", "100000")); 1074 } catch (NumberFormatException nfe) { 1075 } 1076 return displayLength; 1077 } 1078 1079 1083 public String getTruncationMessage() { 1084 return Pooka.getProperty("Pooka.messageTruncation", "------ Message truncated ------"); 1085 } 1086 1087 1091 public String getHtmlTruncationMessage() { 1092 return Pooka.getProperty("Pooka.html.messageTruncation", "<br><br><b>------ Message truncated ------</b><br><br>"); 1093 } 1094 1095 public String getAttachmentSeparator() { 1096 return Pooka.getProperty("Pooka.attachmentSeparator", "\n\n"); 1097 } 1098 1099 public String getHtmlAttachmentSeparator() { 1100 return Pooka.getProperty("Pooka.html.attachmentSeparator", "<br><hr><br>"); 1101 } 1102 1103 1106 public boolean containsHtml() throws MessagingException { 1107 if (!hasLoadedAttachments()) 1108 loadAttachmentInfo(); 1109 1110 return attachments.containsHtml(); 1111 } 1112 1113 1117 public boolean isHtml() throws MessagingException { 1118 if (!hasLoadedAttachments()) 1119 loadAttachmentInfo(); 1120 1121 return attachments.isHtml(); 1122 } 1123 1124 1128 public boolean hasBeenFetched() { 1129 return fetched; 1130 } 1131 1132 1136 public void setFetched(boolean newValue) { 1137 fetched = newValue; 1138 } 1139} 1140 1141 1142 1143 1144 1145 1146 1147 | Popular Tags |