1 14 package org.compiere.util; 15 16 import java.sql.*; 17 import java.io.*; 18 import java.net.*; 19 import java.util.*; 20 21 import javax.mail.*; 22 import javax.mail.internet.*; 23 import javax.activation.*; 24 25 import com.sun.mail.smtp.*; 26 27 28 44 public final class EMail implements Serializable 45 { 46 55 public EMail (Properties ctx, boolean fromCurrentOrRequest, 56 String to, String subject, String message) 57 { 58 this (EMailUtil.getSmtpHost(ctx), 59 fromCurrentOrRequest ? EMailUtil.getEMail(ctx, false) : EMailUtil.getEMail_User(ctx, false), 60 to, subject, message); 61 m_ctx = ctx; 62 } 64 72 public EMail (String smtpHost, String from, String to) 73 { 74 setSmtpHost(smtpHost); 76 setFrom(from); 77 addTo(to); 78 } 80 89 public EMail (String smtpHost, String from, String to, String subject, String message) 90 { 91 setSmtpHost(smtpHost); 93 setFrom(from); 94 addTo(to); 95 setSubject (subject); 96 setMessageText (message); 97 m_valid = isValid (true); 98 } 100 101 public static final String CTX_SMTP = "#Client_SMTP"; 102 103 public static final String CTX_EMAIL = "#User_EMail"; 104 public static final String CTX_EMAIL_USER = "#User_EMailUser"; 105 public static final String CTX_EMAIL_USERPW = "#User_EMailUserPw"; 106 107 public static final String CTX_REQUEST_EMAIL = "#Request_EMail"; 108 public static final String CTX_REQUEST_EMAIL_USER = "#Request_EMailUser"; 109 public static final String CTX_REQUEST_EMAIL_USERPW = "#Request_EMailUserPw"; 110 111 112 private InternetAddress m_from; 113 114 private ArrayList m_to; 115 116 private ArrayList m_cc; 117 118 private ArrayList m_bcc; 119 120 private InternetAddress m_replyTo; 121 122 private String m_subject; 123 124 private String m_messageText; 125 126 private String m_messageHTML; 127 128 private String m_smtpHost; 129 130 private ArrayList m_attachments; 131 132 private EMailAuthenticator m_auth = null; 133 134 private SMTPMessage m_msg = null; 135 136 private Properties m_ctx; 137 138 139 private boolean m_valid = false; 140 141 142 public static final String SENT_OK = "OK"; 143 144 145 protected Logger log = Logger.getCLogger (getClass()); 146 147 protected static Logger s_log = Logger.getCLogger (EMail.class); 148 149 153 public String send () 154 { 155 log.info("send (" + m_smtpHost + ") " + m_from + " -> " + m_to); 156 if (!isValid(true)) 158 return "Invalid Data"; 159 Properties props = System.getProperties(); 161 props.put("mail.store.protocol", "smtp"); 162 props.put("mail.transport.protocol", "smtp"); 163 props.put("mail.host", m_smtpHost); 164 setEMailUser(); 166 if (m_auth != null) 167 props.put("mail.smtp.auth","true"); 168 Session session = Session.getDefaultInstance(props, m_auth); 169 session.setDebug(Log.isTraceLevel(10)); 170 171 try 172 { 173 m_msg = new SMTPMessage(session); 175 m_msg.setFrom(m_from); 177 InternetAddress[] rec = getTos(); 178 if (rec.length == 1) 179 m_msg.setRecipient (Message.RecipientType.TO, rec[0]); 180 else 181 m_msg.setRecipients (Message.RecipientType.TO, rec); 182 rec = getCcs(); 183 if (rec != null && rec.length > 0) 184 m_msg.setRecipients (Message.RecipientType.CC, rec); 185 rec = getBccs(); 186 if (rec != null && rec.length > 0) 187 m_msg.setRecipients (Message.RecipientType.BCC, rec); 188 if (m_replyTo != null) 189 m_msg.setReplyTo(new Address[] {m_replyTo}); 190 m_msg.setSentDate(new java.util.Date ()); 192 m_msg.setHeader("Comments", "CompiereMail"); 193 m_msg.setAllow8bitMIME(true); 196 m_msg.setNotifyOptions (SMTPMessage.NOTIFY_FAILURE | SMTPMessage.NOTIFY_SUCCESS); 198 m_msg.setReturnOption (SMTPMessage.RETURN_HDRS); 200 setContent(); 203 m_msg.saveChanges(); 204 Transport t = session.getTransport("smtp"); 208 t.connect(); 210 Transport.send(m_msg); 213 log.debug("send - success - MessageID=" + m_msg.getMessageID()); 215 } 216 catch (MessagingException me) 217 { 218 Exception ex = me; 219 StringBuffer sb = new StringBuffer ("send(ME)"); 220 boolean printed = false; 221 do 222 { 223 if (ex instanceof SendFailedException) 224 { 225 SendFailedException sfex = (SendFailedException)ex; 226 Address[] invalid = sfex.getInvalidAddresses(); 227 if (!printed) 228 { 229 if (invalid != null && invalid.length > 0) 230 { 231 sb.append (" - Invalid:"); 232 for (int i = 0; i < invalid.length; i++) 233 sb.append (" ").append (invalid[i]); 234 235 } 236 Address[] validUnsent = sfex.getValidUnsentAddresses (); 237 if (validUnsent != null && validUnsent.length > 0) 238 { 239 sb.append (" - ValidUnsent:"); 240 for (int i = 0; i < validUnsent.length; i++) 241 sb.append (" ").append (validUnsent[i]); 242 } 243 Address[] validSent = sfex.getValidSentAddresses (); 244 if (validSent != null && validSent.length > 0) 245 { 246 sb.append (" - ValidSent:"); 247 for (int i = 0; i < validSent.length; i++) 248 sb.append (" ").append (validSent[i]); 249 } 250 printed = true; 251 } 252 if (sfex.getNextException() == null) 253 sb.append(" ").append(sfex.getLocalizedMessage()); 254 } 255 else if (ex instanceof AuthenticationFailedException) 256 { 257 sb.append(" - Invalid Username/Password - " + m_auth); 258 } 259 else 260 { 261 String msg = ex.getLocalizedMessage(); 262 if (msg == null) 263 msg = ex.toString(); 264 sb.append(" ").append(msg); 265 } 266 if (ex instanceof MessagingException) 267 ex = ((MessagingException)ex).getNextException(); 268 else 269 ex = null; 270 } while (ex != null); 271 log.error(sb.toString(), me); 272 return sb.toString(); 273 } 274 catch (Exception e) 275 { 276 log.error("send", e); 277 return "EMail.send: " + e.getLocalizedMessage(); 278 } 279 if (Log.isTraceLevel(9)) 281 dumpMessage(); 282 return SENT_OK; 283 } 285 288 private void dumpMessage() 289 { 290 if (m_msg == null) 291 return; 292 try 293 { 294 Enumeration e = m_msg.getAllHeaderLines (); 295 while (e.hasMoreElements ()) 296 log.debug("- " + e.nextElement ()); 297 } 298 catch (MessagingException ex) 299 { 300 log.error("dumpMessage", ex); 301 } 302 } 304 308 protected MimeMessage getMimeMessage() 309 { 310 return m_msg; 311 } 313 318 public String getMessageID() 319 { 320 try 321 { 322 if (m_msg != null) 323 return m_msg.getMessageID (); 324 } 325 catch (MessagingException ex) 326 { 327 log.error("getMessageID", ex); 328 } 329 return null; 330 } 332 333 334 339 public void setEMailUser (String username, String password) 340 { 341 if (username == null || password == null) 342 log.warn("setEMailUser ignored - " + username + "/" + password); 343 else 344 { 345 m_auth = new EMailAuthenticator (username, password); 347 } 348 } 350 353 private void setEMailUser () 354 { 355 if (m_auth != null) 357 return; 358 String from = m_from.getAddress(); 360 Properties ctx = m_ctx == null ? Env.getCtx() : m_ctx; 361 String email = Env.getContext(ctx, CTX_EMAIL); 363 String usr = Env.getContext(ctx, CTX_EMAIL_USER); 364 String pwd = Env.getContext(ctx, CTX_EMAIL_USERPW); 365 if (from.equals(email) && usr.length() > 0 && pwd.length() > 0) 366 { 367 setEMailUser (usr, pwd); 368 return; 369 } 370 email = Env.getContext(ctx, CTX_REQUEST_EMAIL); 371 usr = Env.getContext(ctx, CTX_REQUEST_EMAIL_USER); 372 pwd = Env.getContext(ctx, CTX_REQUEST_EMAIL_USERPW); 373 if (from.equals(email) && usr.length() > 0 && pwd.length() > 0) 374 setEMailUser (usr, pwd); 375 } 377 378 382 public InternetAddress getFrom() 383 { 384 return m_from; 385 } 387 391 public void setFrom(String newFrom) 392 { 393 if (newFrom == null) 394 { 395 m_valid = false; 396 return; 397 } 398 try 399 { 400 m_from = new InternetAddress (newFrom, true); 401 } 402 catch (Exception e) 403 { 404 log.error("setFrom", e); 405 m_valid = false; 406 } 407 } 409 414 public boolean addTo (String newTo) 415 { 416 if (newTo == null || newTo.length() == 0) 417 { 418 m_valid = false; 419 return false; 420 } 421 InternetAddress ia = null; 422 try 423 { 424 ia = new InternetAddress (newTo, true); 425 } 426 catch (Exception e) 427 { 428 log.error("addTo - " + e.toString()); 429 m_valid = false; 430 return false; 431 } 432 if (m_to == null) 433 m_to = new ArrayList(); 434 m_to.add(ia); 435 return true; 436 } 438 442 public InternetAddress getTo() 443 { 444 if (m_to == null || m_to.size() == 0) 445 return null; 446 InternetAddress ia = (InternetAddress)m_to.get(0); 447 return ia; 448 } 450 454 public InternetAddress[] getTos() 455 { 456 if (m_to == null || m_to.size() == 0) 457 return null; 458 InternetAddress[] ias = new InternetAddress[m_to.size()]; 459 m_to.toArray(ias); 460 return ias; 461 } 463 468 public boolean addCc (String newCc) 469 { 470 if (newCc == null || newCc.length() == 0) 471 return false; 472 InternetAddress ia = null; 473 try 474 { 475 ia = new InternetAddress (newCc, true); 476 } 477 catch (Exception e) 478 { 479 log.error("addCc", e); 480 return false; 481 } 482 if (m_cc == null) 483 m_cc = new ArrayList(); 484 m_cc.add (ia); 485 return true; 486 } 488 492 public InternetAddress[] getCcs() 493 { 494 if (m_cc == null || m_cc.size() == 0) 495 return null; 496 InternetAddress[] ias = new InternetAddress[m_cc.size()]; 497 m_cc.toArray(ias); 498 return ias; 499 } 501 506 public boolean addBcc (String newBcc) 507 { 508 if (newBcc == null || newBcc.length() == 0) 509 return false; 510 InternetAddress ia = null; 511 try 512 { 513 ia = new InternetAddress (newBcc, true); 514 } 515 catch (Exception e) 516 { 517 log.error("addBcc", e); 518 return false; 519 } 520 if (m_bcc == null) 521 m_bcc = new ArrayList(); 522 m_bcc.add (ia); 523 return true; 524 } 526 530 public InternetAddress[] getBccs() 531 { 532 if (m_bcc == null || m_bcc.size() == 0) 533 return null; 534 InternetAddress[] ias = new InternetAddress[m_bcc.size()]; 535 m_bcc.toArray(ias); 536 return ias; 537 } 539 544 public boolean setReplyTo (String newTo) 545 { 546 if (newTo == null || newTo.length() == 0) 547 return false; 548 InternetAddress ia = null; 549 try 550 { 551 ia = new InternetAddress (newTo, true); 552 } 553 catch (Exception e) 554 { 555 log.error("setReplyTo", e); 556 return false; 557 } 558 m_replyTo = ia; 559 return true; 560 } 562 566 public InternetAddress getReplyTo() 567 { 568 return m_replyTo; 569 } 571 572 573 577 public void setSubject(String newSubject) 578 { 579 if (newSubject == null || newSubject.length() == 0) 580 m_valid = false; 581 else 582 m_subject = newSubject; 583 } 585 589 public String getSubject() 590 { 591 return m_subject; 592 } 594 598 public void setMessageText (String newMessage) 599 { 600 if (newMessage == null || newMessage.length() == 0) 601 m_valid = false; 602 else 603 { 604 m_messageText = newMessage; 605 if (!m_messageText.endsWith("\n")) 606 m_messageText += "\n"; 607 } 608 } 610 614 public String getMessageCRLF() 615 { 616 if (m_messageText == null) 617 return ""; 618 char[] chars = m_messageText.toCharArray(); 619 StringBuffer sb = new StringBuffer (); 620 for (int i = 0; i < chars.length; i++) 621 { 622 char c = chars[i]; 623 if (c == '\n') 624 { 625 int previous = i-1; 626 if (previous >= 0 && chars[previous] == '\r') 627 sb.append(c); 628 else 629 sb.append("\r\n"); 630 } 631 else 632 sb.append(c); 633 } 634 return sb.toString(); 637 } 639 643 public void setMessageHTML (String html) 644 { 645 if (html == null || html.length() == 0) 646 m_valid = false; 647 else 648 { 649 m_messageHTML = html; 650 if (!m_messageHTML.endsWith("\n")) 651 m_messageHTML += "\n"; 652 } 653 } 655 660 public void setMessageHTML (String subject, String message) 661 { 662 m_subject = subject; 663 StringBuffer sb = new StringBuffer ("<HTML>\n") 664 .append("<HEAD>\n") 665 .append("<TITLE>\n") 666 .append(subject + "\n") 667 .append("</TITLE>\n") 668 .append("</HEAD>\n"); 669 sb.append("<BODY>\n") 670 .append("<H2>" + subject + "</H2>" + "\n") 671 .append(message) 672 .append("\n") 673 .append("</BODY>\n"); 674 sb.append("</HTML>\n"); 675 m_messageHTML = sb.toString(); 676 } 678 682 public String getMessageHTML() 683 { 684 return m_messageHTML; 685 } 687 691 public void addAttachment (File file) 692 { 693 if (file == null) 694 return; 695 if (m_attachments == null) 696 m_attachments = new ArrayList(); 697 m_attachments.add(file); 698 } 700 704 public void addAttachment (URL url) 705 { 706 if (url == null) 707 return; 708 if (m_attachments == null) 709 m_attachments = new ArrayList(); 710 m_attachments.add(url); 711 } 713 720 public void addAttachment (byte[] data, String type, String name) 721 { 722 ByteArrayDataSource byteArray = new ByteArrayDataSource (data, type).setName(name); 723 addAttachment (byteArray); 724 } 726 730 public void addAttachment (DataSource dataSource) 731 { 732 if (dataSource == null) 733 return; 734 if (m_attachments == null) 735 m_attachments = new ArrayList(); 736 m_attachments.add(dataSource); 737 } 739 744 private void setContent () 745 throws MessagingException, IOException 746 { 747 m_msg.setSubject (getSubject ()); 748 749 if (m_attachments == null || m_attachments.size() == 0) 751 { 752 if (m_messageHTML == null || m_messageHTML.length () == 0) 753 m_msg.setContent (getMessageCRLF(), "text/plain"); 754 else 755 m_msg.setDataHandler (new DataHandler 756 (new ByteArrayDataSource (m_messageHTML, "text/html"))); 757 log.debug("setContent (simple) " + getSubject()); 759 } 760 else { 762 MimeBodyPart mbp_1 = new MimeBodyPart(); 764 mbp_1.setText(""); 765 if (m_messageHTML == null || m_messageHTML.length () == 0) 766 mbp_1.setContent (getMessageCRLF(), "text/plain"); 767 else 768 mbp_1.setDataHandler (new DataHandler 769 (new ByteArrayDataSource (m_messageHTML, "text/html"))); 770 771 Multipart mp = new MimeMultipart(); 773 mp.addBodyPart(mbp_1); 774 log.debug("setContent (multi) " + getSubject() + " - " + mbp_1); 775 776 for (int i = 0; i < m_attachments.size(); i++) 778 { 779 Object attachment = m_attachments.get(i); 780 DataSource ds = null; 781 if (attachment instanceof File) 782 { 783 File file = (File)attachment; 784 if (file.exists()) 785 ds = new FileDataSource (file); 786 else 787 { 788 log.error("setContent - File does not exist: " + file); 789 continue; 790 } 791 } 792 else if (attachment instanceof URL) 793 { 794 URL url = (URL)attachment; 795 ds = new URLDataSource (url); 796 } 797 else if (attachment instanceof DataSource) 798 ds = (DataSource)attachment; 799 else 800 { 801 log.error("setContent - Attachement type unknown: " + attachment); 802 continue; 803 } 804 MimeBodyPart mbp_2 = new MimeBodyPart(); 806 mbp_2.setDataHandler(new DataHandler(ds)); 807 mbp_2.setFileName(ds.getName()); 808 log.debug("setContent - Added Attachment " + ds.getName() + " - " + mbp_2); 809 mp.addBodyPart(mbp_2); 810 } 811 812 m_msg.setContent(mp); 814 } } 817 818 819 823 public void setSmtpHost(String newSmtpHost) 824 { 825 if (newSmtpHost == null || newSmtpHost.length() == 0) 826 m_valid = false; 827 else 828 m_smtpHost = newSmtpHost; 829 } 831 835 public String getSmtpHost() 836 { 837 return m_smtpHost; 838 } 840 844 public boolean isValid() 845 { 846 return m_valid; 847 } 849 854 public boolean isValid (boolean recheck) 855 { 856 if (m_from == null || m_from.getAddress().length() == 0) 858 { 859 log.warn("isValid - From is invalid=" + m_from); 860 return false; 861 } 862 InternetAddress ia = getTo(); 863 if (ia == null || ia.getAddress().length() == 0) 864 { 865 log.warn("isValid - To is invalid=" + m_to); 866 return false; 867 } 868 if (m_smtpHost == null || m_smtpHost.length() == 0) 869 { 870 log.warn("isValid - SMTP Host is invalid" + m_smtpHost); 871 return false; 872 } 873 if (m_subject == null || m_subject.length() == 0) 874 { 875 log.warn("isValid - Subject is invalid=" + m_subject); 876 return false; 877 } 878 return true; 879 } 881 882 883 884 889 public static void main (String [] args) 890 { 891 org.compiere.Compiere.startupClient (); 892 Log.setTraceLevel(9); 893 894 EMail emailTest = new EMail("main", "jjanke@compiere.org", "jjanke@compiere.org", "TestSubject", "TestMessage"); 895 emailTest.setEMailUser("info", "test"); 901 emailTest.send(); 902 System.exit(0); 903 904 905 if (args.length != 5) 906 { 907 System.out.println("Parameters: smtpHost from to subject message"); 908 System.out.println("Example: java org.compiere.util.EMail mail.acme.com joe@acme.com sue@acme.com HiThere CheersJoe"); 909 System.exit(1); 910 } 911 EMail email = new EMail(args[0], args[1], args[2], args[3], args[4]); 912 email.send(); 913 } 915 } | Popular Tags |