1 56 package org.opencrx.mail.servlet; 57 58 import java.io.BufferedReader ; 59 import java.io.ByteArrayOutputStream ; 60 import java.io.IOException ; 61 import java.io.InputStream ; 62 import java.io.InputStreamReader ; 63 import java.util.ArrayList ; 64 import java.util.Collection ; 65 import java.util.Date ; 66 import java.util.Enumeration ; 67 import java.util.Iterator ; 68 import java.util.List ; 69 70 import javax.mail.Address ; 71 import javax.mail.Flags ; 72 import javax.mail.Message ; 73 import javax.mail.MessagingException ; 74 import javax.mail.Part ; 75 import javax.mail.internet.AddressException ; 76 import javax.mail.internet.InternetAddress ; 77 import javax.mail.internet.MimeBodyPart ; 78 import javax.mail.internet.MimeMessage ; 79 import javax.mail.internet.MimeMultipart ; 80 81 import org.openmdx.application.log.AppLog; 82 import org.openmdx.base.exception.ServiceException; 83 import org.openmdx.kernel.id.UUIDs; 84 85 89 public class SimpleMimeMessage { 90 91 97 public SimpleMimeMessage( 98 MimeMessage theMessage 99 ) { 100 this(theMessage, false); 101 } 102 103 115 public SimpleMimeMessage( 116 MimeMessage theMessage, 117 boolean initAttributes 118 ) { 119 this.mimeMsg = theMessage; 120 if(initAttributes) { 121 this.getBody(); 122 this.getDate(); 123 this.getFrom(); 124 this.getMessageID(); 125 this.getPriority(); 126 this.getRecipients(); 127 this.getSubject(); 128 this.getAllHeaderLinesAsString(); 129 this.getMessageIdentity(); 130 } 131 } 132 133 147 public String [] getHeader( 148 String name 149 ) { 150 try { 151 return this.mimeMsg.getHeader(name); 153 } catch (MessagingException e) { 154 AppLog.warning("Could not extract header element '" + name 155 + "' of message " + getMessageID()); 156 ServiceException e0 = new ServiceException(e); 157 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 158 } 159 return null; 160 } 161 162 169 public String getAllHeaderLinesAsString() { 170 171 if(this.headerLines == null) { 172 try { 173 StringBuffer text = new StringBuffer (); 174 Enumeration lines = this.mimeMsg.getAllHeaderLines(); 175 while (lines.hasMoreElements()) { 176 text.append((String ) lines.nextElement()); 177 text.append(System.getProperty("line.separator", "\n")); 178 } 179 this.headerLines = text.toString(); 180 } catch (MessagingException e) { 181 AppLog.warning("Could not extract header lines for message " + getMessageID()); 182 ServiceException e0 = new ServiceException(e); 183 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 184 } 185 } 186 return this.headerLines; 187 } 188 189 203 public String getBody() { 204 if (this.messageBody == null) { 205 try { 206 Object content = this.mimeMsg.getContent(); 207 if (content instanceof String ) { 208 this.messageBody = (String ) content; 209 this.bodyType = this.mimeMsg.getContentType(); 210 } 211 else if (content instanceof MimeMultipart ) { 212 MimeMultipart multipart = (MimeMultipart )content; 213 for ( int i = 0; i < multipart.getCount(); i++ ) { 214 this.parsePart((MimeBodyPart )multipart.getBodyPart(i)); 215 } 216 } 217 else if (content instanceof MimeBodyPart ) { 218 this.parsePart((MimeBodyPart )content); 219 } 220 else if (content instanceof InputStream ) { 221 String mimeType = mimeMsg.getContentType(); 222 if (this.mimeMsg.isMimeType("text/plain") || mimeMsg.isMimeType("text/html")) { 223 this.bodyType = mimeMsg.getContentType(); 224 BufferedReader in = new BufferedReader (new InputStreamReader ( 225 this.mimeMsg.getInputStream()) 226 ); 227 StringBuffer msgBody = new StringBuffer (); 228 while (in.ready()) { 229 msgBody.append(in.readLine()); 230 if (in.ready()) { 231 msgBody.append(System.getProperty("line.separator", "\n")); 232 } 233 } 234 this.messageBody = msgBody.toString(); 235 } 236 else { 237 AppLog.info("Content of type '" + mimeType + "' is handled as binary type" 238 + " for message " +getMessageID()); 239 } 240 } 241 else { 242 AppLog.warning("Not a supported content format for message " 243 + getMessageID()); 244 } 245 } catch (IOException e) { 246 AppLog.warning("Could not read message content " + getMessageID()); 247 ServiceException e0 = new ServiceException(e); 248 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 249 } catch (MessagingException e) { 250 AppLog.warning("Could not read message content " + getMessageID()); 251 ServiceException e0 = new ServiceException(e); 252 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 253 } 254 } 255 return this.messageBody; 256 } 257 258 public String getMessageIdentity() { 259 if (this.messageIdentity == null) { 260 try { 261 this.messageIdentity = this.mimeMsg.getHeader(OPENCRX_MESSAGE_IDENTITY,null); 263 if(this.messageIdentity == null) { 264 this.messageIdentity = ""; 265 } 266 } catch (MessagingException e) { 267 AppLog.warning("Could not extract message identity for message " + getMessageID()); 268 ServiceException e0 = new ServiceException(e); 269 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 270 } 271 } 272 return messageIdentity; 273 } 274 279 public String getMessageID( 280 ) { 281 if (this.messageId == null) { 282 try { 283 this.messageId = this.mimeMsg.getMessageID(); 285 if(this.messageId == null || this.messageId.length() == 0) { 286 this.messageId = OPENCRX_MESSAGE_ID + UUIDs.getGenerator().next(); 287 } 288 } catch (MessagingException e) { 289 AppLog.warning("Could not extract message ID for message " + getMessageID()); 290 ServiceException e0 = new ServiceException(e); 291 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 292 } 293 } 294 return this.messageId; 295 } 296 297 304 public String getSubject( 305 ) { 306 if (this.subject == null) { 307 try { 308 String [] subjects = this.mimeMsg.getHeader("Subject"); 313 if (subjects != null && subjects.length > 0) { 314 StringBuffer msgSubject = new StringBuffer (); 315 for (int i = 0; i < subjects.length; i++) { 316 msgSubject.append(subjects[i]); 317 if ((i + 1) < subjects.length) { 318 msgSubject.append(System.getProperty("line.separator", "\n")); 319 } 320 } 321 this.subject = msgSubject.toString(); 322 } 323 } catch (MessagingException e) { 324 AppLog.warning("Could not extract subject for message " + getMessageID()); 325 ServiceException e0 = new ServiceException(e); 326 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 327 } 328 } 329 return this.subject; 330 } 331 332 338 public Date getDate( 339 ) { 340 Date date = null; 341 try { 342 date = this.mimeMsg.getSentDate(); 343 } catch (MessagingException e) { 344 AppLog.warning("Could not extract the send date of message " + getMessageID()); 345 ServiceException e0 = new ServiceException(e); 346 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 347 } 348 return date; 349 } 350 351 357 public String [] getFrom( 358 ) { 359 if(this.from == null) { 360 try { 361 Address [] headerFromAddresses = this.mimeMsg.getFrom(); 363 this.from = getAddresses(headerFromAddresses); 364 } catch (MessagingException e) { 365 e.printStackTrace(); 366 AppLog.warning("Could not extract the sender's 'from' address of message " + getMessageID()); 367 ServiceException e0 = new ServiceException(e); 368 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 369 } 370 } 371 return this.from; 372 } 373 374 380 public String [] getRecipients( 381 ) { 382 return this.getRecipients(Message.RecipientType.TO); 383 } 384 385 392 public String [] getRecipients( 393 Message.RecipientType type 394 ) { 395 if(Message.RecipientType.TO.toString().equalsIgnoreCase(type.toString())) { 396 if(this.to == null) { 397 this.to = getRecipientsByType(type); 398 } 399 return this.to; 400 } 401 else if (Message.RecipientType.CC.toString().equalsIgnoreCase(type.toString())) { 402 if (this.cc == null) { 403 this.cc = getRecipientsByType(type); 404 } 405 return this.cc; 406 } 407 else if (Message.RecipientType.BCC.toString().equalsIgnoreCase(type.toString())) { 408 if(this.bcc == null) { 409 this.bcc = getRecipientsByType(type); 410 } 411 return this.bcc; 412 } 413 return null; 414 } 415 416 433 public short getPriority( 434 ) { 435 String priority = "normal"; 436 short priorityAsShort = PRIORITY_NORMAL; 437 try { 438 String [] values = this.mimeMsg.getHeader("Importance"); 439 if (values != null && values.length > 0) { 440 priority = values[0]; 441 } 442 values = this.mimeMsg.getHeader("X-Priority"); 443 if (values != null && values.length > 0) { 444 priority = values[0]; 445 } 446 values = this.mimeMsg.getHeader("Priority"); 447 if (values != null && values.length > 0) { 448 priority = values[0]; 449 } 450 } catch (MessagingException e) { 451 AppLog.warning("Could not extract message priority for message " + getMessageID()); 452 ServiceException e0 = new ServiceException(e); 453 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 454 } 455 if (priority.equalsIgnoreCase("normal") || priority.equalsIgnoreCase("3")) { 456 priorityAsShort = PRIORITY_NORMAL; 457 } else if (priority.equalsIgnoreCase("high") 458 || priority.equalsIgnoreCase("1") 459 || priority.equalsIgnoreCase("Urgent")) { 460 priorityAsShort = PRIORITY_HIGH; 461 } else if (priority.equalsIgnoreCase("low") 462 || priority.equalsIgnoreCase("5") 463 || priority.equalsIgnoreCase("Non-Urgent")) { 464 priorityAsShort = PRIORITY_LOW; 465 } 466 return priorityAsShort; 467 } 468 469 474 public boolean isPlainText( 475 ) { 476 return this.bodyType.startsWith("text/plain"); 477 } 478 479 480 485 public boolean isHtmlText( 486 ) { 487 return this.bodyType.startsWith("text/html"); 488 } 489 490 491 496 public boolean containsAttachments( 497 ) { 498 return this.content.size() > 0; 499 } 500 501 502 507 public boolean containsNestedMessage( 508 ) { 509 return this.containsNestedMessageAttachment; 510 } 511 512 513 518 public boolean hasIdentity( 519 ) { 520 return !(this.messageIdentity == null || this.messageIdentity.length() == 0); 521 } 522 523 524 530 public Collection getContents( 531 ) { 532 return this.content.size() > 0 533 ? this.content 534 : null; 535 } 536 537 543 public Collection getTextContents( 544 ) { 545 ArrayList textContents = new ArrayList (); 546 if(this.content.size() > 0) { 547 Iterator binContents = this.content.iterator(); 548 while (binContents.hasNext()) { 549 MessageContent contentElem = (MessageContent) binContents.next(); 550 if(contentElem.getContent() instanceof String ) { 551 textContents.add(contentElem); 552 } 553 } 554 } 555 return textContents.size() > 0 556 ? textContents 557 : null; 558 } 559 560 566 public Collection getBinaryContents( 567 ) { 568 ArrayList binaryContents = new ArrayList (); 569 if(this.content.size() > 0) { 570 Iterator binContents = this.content.iterator(); 571 while (binContents.hasNext()) { 572 MessageContent contentElem = (MessageContent) binContents.next(); 573 if(!(contentElem.getContent() instanceof String )) { 574 binaryContents.add(contentElem); 575 } 576 } 577 } 578 return binaryContents.size() > 0 579 ? binaryContents 580 : null; 581 } 582 583 586 public String toString( 587 ) { 588 StringBuffer buffer = new StringBuffer (); 589 buffer.append("send date='").append(getDate()); 590 buffer.append("', from={'"); 591 if(this.from == null) { 592 this.getFrom(); 593 } 594 if(this.from != null) { 595 for (int i = 0; i < this.from.length; i++) { 596 buffer.append(this.from[i]).append("',"); 597 } 598 } 599 else { 600 buffer.append("',"); 601 } 602 buffer.append("}, to={'"); 603 if(this.to == null) { 604 this.getRecipients(Message.RecipientType.TO); 605 } 606 if(this.to != null) { 607 for (int i = 0; i < this.to.length; i++) { 608 buffer.append(this.to[i]).append("',"); 609 } 610 } 611 else { 612 buffer.append("',"); 613 } 614 buffer.append("}, cc={'"); 615 if(this.cc == null) { 616 this.getRecipients(Message.RecipientType.CC); 617 } 618 if(this.cc != null) { 619 for (int i = 0; i < this.cc.length; i++) { 620 buffer.append(this.cc[i]).append("',"); 621 } 622 } 623 buffer.append("}, bcc={'"); 624 if(this.bcc == null) { 625 this.getRecipients(Message.RecipientType.BCC); 626 } 627 if(this.bcc != null) { 628 for (int i = 0; i < this.bcc.length; i++) { 629 buffer.append(this.bcc[i]).append("',"); 630 } 631 } 632 else { 633 buffer.append("',"); 634 } 635 buffer.append("}', messageId='").append(this.getMessageID()); 636 buffer.append("', subject='").append(this.getSubject()); 637 buffer.append("', priority='").append(this.getPriority()); 638 buffer.append("', body='").append(this.getBody()).append("'"); 639 if(this.containsAttachments()) { 640 Iterator contents = this.content.iterator(); 641 while(contents.hasNext()) { 642 MessageContent contentElem = (MessageContent) contents.next(); 643 buffer.append(" [included content element '" + contentElem.toString() + "' included.] "); 644 } 645 } 646 return buffer.toString(); 648 } 649 650 654 private String [] getAddresses( 655 Address [] headerAddresses 656 ) throws AddressException { 657 String addresses[] = null; 658 if (headerAddresses != null && headerAddresses.length > 0) { 659 addresses = new String [headerAddresses.length]; 660 for (int i = 0; i < headerAddresses.length; i++) { 661 if (headerAddresses[0] instanceof InternetAddress ) { 662 addresses[i] = ((InternetAddress )headerAddresses[i]).getAddress(); 663 } else { 664 InternetAddress temp = new InternetAddress (headerAddresses[i].toString()); 665 addresses[i] = temp.getAddress(); 666 } 667 } 668 } else { 669 addresses = new String []{UNSPECIFIED_ADDRESS}; 670 } 671 return addresses; 672 } 673 674 677 private void parsePart( 678 MimeBodyPart part 679 ) { 680 try { 681 String disposition = part.getDisposition(); 682 if ( disposition == null ) { 683 if (part.isMimeType("text/plain") || part.isMimeType("text/html")) { 684 if (this.messageBody == null) { 685 this.messageBody = (String )part.getContent(); 686 this.bodyType = part.getContentType(); 687 } 688 else { 689 MessageContent cont = new MessageContent(part.getContentID(), part.getContentType(), part.getContent()); 690 this.content.add(cont); 691 } 692 } 693 } 694 else if (disposition.equals(Part.ATTACHMENT) || disposition.equals(Part.INLINE) ) { 695 if(AppLog.isTraceOn()) { 696 AppLog.trace("Reading Attachment for message " + getMessageID() 697 + ", (type='" + part.getContentType() + "'"); 698 } 699 Object partContent = part.getContent(); 700 InputStream is = null; 701 if (partContent instanceof MimeMessage ) { 704 SimpleMimeMessage nestedMsg = new SimpleMimeMessage((MimeMessage )partContent, true); 708 MessageContent cont = new MessageContent(part.getFileName(), part.getContentType(), nestedMsg); 709 content.add(cont); 710 containsNestedMessageAttachment = true; 712 if(AppLog.isTraceOn()) { 713 AppLog.trace("attached MimeMessage imported '" + part.getFileName() + "'"); 714 } 715 } 716 else if (partContent instanceof MimeMultipart ) { 717 MimeMultipart multipart = (MimeMultipart )partContent; 718 for ( int i = 0; i < multipart.getCount(); i++ ) { 719 parsePart((MimeBodyPart )multipart.getBodyPart(i)); 720 } 721 } 722 else { 723 if (partContent instanceof InputStream ) { 724 is = (InputStream ) partContent; 725 } 726 else { 727 is = part.getInputStream(); 728 } 729 ByteArrayOutputStream bos = new ByteArrayOutputStream (); 730 int readByte = is.read(); 731 while (readByte != -1) { 732 bos.write(readByte); 733 readByte = is.read(); 734 } 735 MessageContent cont = new MessageContent(part.getFileName(), part.getContentType(), bos.toByteArray()); 736 content.add(cont); 737 if(AppLog.isTraceOn()) { 738 AppLog.trace("attachment of type '" + part.getContentType() 739 + "', filename '" + part.getFileName() + "' read"); 740 } 741 } 742 } 743 else { 744 AppLog.warning("Unsupported message part for message " + getMessageID()); 747 } 748 } catch (IOException e) { 749 AppLog.warning("Could not read message content part " + getMessageID()); 750 ServiceException e0 = new ServiceException(e); 751 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 752 } catch (MessagingException e) { 753 AppLog.warning("Could not read message content part" + getMessageID()); 754 ServiceException e0 = new ServiceException(e); 755 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 756 } 757 } 758 759 766 private String [] getRecipientsByType( 767 Message.RecipientType type 768 ) { 769 String recipients[] = null; 770 try { 771 Address headerToAddresses[] = this.mimeMsg.getRecipients(type); 773 recipients = getAddresses(headerToAddresses); 774 } catch (MessagingException e) { 775 AppLog.warning("Could not extract the addresses of message " + getMessageID() + 776 " of type '" + type.toString() + "'"); 777 ServiceException e0 = new ServiceException(e); 778 AppLog.warning(e0.getMessage(), e0.getCause(), 1); 779 } 780 return recipients; 781 } 782 783 public void markAsDeleted( 785 ) { 786 try { 787 this.mimeMsg.setFlag( 788 Flags.Flag.DELETED, 789 true 790 ); 791 } 792 catch(MessagingException e) {} 793 } 794 795 public static final String OPENCRX_MESSAGE_ID = "openCRX:MsgID:"; 799 public static final String OPENCRX_MESSAGE_IDENTITY = "X-openCrxMsgIdentity"; 800 public static final String UNSPECIFIED_ADDRESS = "NO_ADDRESS_SPECIFIED"; 801 802 public static final short PRIORITY_LOW = 1; 803 public static final short PRIORITY_NORMAL = 2; 804 public static final short PRIORITY_HIGH = 3; 805 public static final short PRIORITY_URGENT = 4; 806 public static final short PRIORITY_IMMEDIATE = 5; 807 808 private final MimeMessage mimeMsg; 809 810 811 private String messageIdentity = null; 812 813 814 private String messageId = null; 815 816 817 private String subject = null; 818 819 820 private String messageBody = null; 821 822 private String bodyType = null; 823 824 825 private List content = new ArrayList (); 826 827 828 private String headerLines = null; 829 830 831 private String from[] = null; 832 private String to[] = null; 833 private String cc[] = null; 834 private String bcc[] = null; 835 836 837 private boolean containsNestedMessageAttachment = false; 838 839 } 840 | Popular Tags |