001 package railo.runtime.net.smtp; 002 003 import java.io.FileNotFoundException; 004 import java.io.Serializable; 005 import java.io.UnsupportedEncodingException; 006 import java.net.URL; 007 import java.text.SimpleDateFormat; 008 import java.util.ArrayList; 009 import java.util.Collections; 010 import java.util.Date; 011 import java.util.HashMap; 012 import java.util.Enumeration; 013 import java.util.Iterator; 014 import java.util.Locale; 015 import java.util.Map; 016 import java.util.Map.Entry; 017 import java.util.Properties; 018 import java.util.TimeZone; 019 020 import javax.activation.DataHandler; 021 import javax.mail.Authenticator; 022 import javax.mail.BodyPart; 023 import javax.mail.Message; 024 import javax.mail.MessagingException; 025 import javax.mail.Multipart; 026 import javax.mail.internet.AddressException; 027 import javax.mail.internet.InternetAddress; 028 import javax.mail.internet.MimeBodyPart; 029 import javax.mail.internet.MimeMessage; 030 import javax.mail.internet.MimeMultipart; 031 import javax.mail.internet.MimePart; 032 033 import org.apache.commons.collections.ReferenceMap; 034 035 import railo.commons.activation.ResourceDataSource; 036 import railo.commons.digest.MD5; 037 import railo.commons.io.SystemUtil; 038 import railo.commons.io.log.LogAndSource; 039 import railo.commons.io.log.LogUtil; 040 import railo.commons.io.res.Resource; 041 import railo.commons.io.res.util.ResourceUtil; 042 import railo.commons.lang.SerializableObject; 043 import railo.commons.lang.StringUtil; 044 import railo.runtime.config.Config; 045 import railo.runtime.config.ConfigWeb; 046 import railo.runtime.config.ConfigWebImpl; 047 import railo.runtime.engine.ThreadLocalPageContext; 048 import railo.runtime.exp.ExpressionException; 049 import railo.runtime.exp.PageException; 050 import railo.runtime.net.mail.MailException; 051 import railo.runtime.net.mail.MailPart; 052 import railo.runtime.net.mail.MailUtil; 053 import railo.runtime.net.mail.Server; 054 import railo.runtime.net.mail.ServerImpl; 055 import railo.runtime.net.proxy.Proxy; 056 import railo.runtime.net.proxy.ProxyData; 057 import railo.runtime.net.proxy.ProxyDataImpl; 058 import railo.runtime.net.smtp.SMTPConnectionPool.SessionAndTransport; 059 import railo.runtime.op.Caster; 060 import railo.runtime.spooler.mail.MailSpoolerTask; 061 import railo.runtime.type.util.ArrayUtil; 062 import railo.runtime.type.util.ListUtil; 063 064 import com.sun.mail.smtp.SMTPMessage; 065 066 public final class SMTPClient implements Serializable { 067 068 069 070 /** 071 * 072 */ 073 private static final long serialVersionUID = 5227282806519740328L; 074 075 private static final int SPOOL_UNDEFINED=0; 076 private static final int SPOOL_YES=1; 077 private static final int SPOOL_NO=2; 078 079 private static final int SSL_NONE=0; 080 private static final int SSL_YES=1; 081 private static final int SSL_NO=2; 082 083 private static final int TLS_NONE=0; 084 private static final int TLS_YES=1; 085 private static final int TLS_NO=2; 086 087 private static final String TEXT_HTML = "text/html"; 088 private static final String TEXT_PLAIN = "text/plain"; 089 private static final SerializableObject LOCK = new SerializableObject(); 090 091 private static Map<TimeZone, SimpleDateFormat> formatters=new ReferenceMap(ReferenceMap.SOFT,ReferenceMap.SOFT); 092 //private static final int PORT = 25; 093 094 private int spool=SPOOL_UNDEFINED; 095 096 private int timeout=-1; 097 098 private String plainText; 099 private String plainTextCharset; 100 101 private String htmlText; 102 103 104 private String htmlTextCharset; 105 106 private Attachment[] attachmentz; 107 108 private String[] host; 109 private String charset="UTF-8"; 110 private InternetAddress from; 111 private InternetAddress[] tos; 112 private InternetAddress[] bccs; 113 private InternetAddress[] ccs; 114 private InternetAddress[] rts; 115 private InternetAddress[] fts; 116 private String subject=""; 117 private String xmailer="Railo Mail"; 118 private Map<String,String> headers=new HashMap<String,String>(); 119 private int port=-1; 120 121 private String username; 122 private String password=""; 123 124 125 126 127 private int ssl=SSL_NONE; 128 private int tls=TLS_NONE; 129 130 ProxyData proxyData=new ProxyDataImpl(); 131 private ArrayList<MailPart> parts; 132 133 private TimeZone timeZone; 134 135 136 public static String getNow(TimeZone tz){ 137 tz = ThreadLocalPageContext.getTimeZone(tz); 138 SimpleDateFormat df=formatters.get(tz); 139 if(df==null) { 140 df = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z (z)",Locale.US); 141 df.setTimeZone(tz); 142 formatters.put(tz, df); 143 } 144 return df.format(new Date()); 145 } 146 147 148 public void setSpoolenable(boolean spoolenable) { 149 spool=spoolenable?SPOOL_YES:SPOOL_NO; 150 } 151 152 /** 153 * set port of the mailserver 154 * @param port 155 */ 156 public void setPort(int port) { 157 this.port=port; 158 } 159 160 /** 161 * @param charset the charset to set 162 */ 163 public void setCharset(String charset) { 164 this.charset = charset; 165 } 166 167 168 public static ServerImpl toServerImpl(String server,int port, String usr,String pwd) throws MailException { 169 int index; 170 171 // username/password 172 index=server.indexOf('@'); 173 if(index!=-1) { 174 usr=server.substring(0,index); 175 server=server.substring(index+1); 176 index=usr.indexOf(':'); 177 if(index!=-1) { 178 pwd=usr.substring(index+1); 179 usr=usr.substring(0,index); 180 } 181 } 182 183 // port 184 index=server.indexOf(':'); 185 if(index!=-1) { 186 try { 187 port=Caster.toIntValue(server.substring(index+1)); 188 } catch (ExpressionException e) { 189 throw new MailException(e.getMessage()); 190 } 191 server=server.substring(0,index); 192 } 193 194 195 ServerImpl srv = ServerImpl.getInstance(server, port, usr, pwd, false, false); 196 return srv; 197 } 198 199 public void setHost(String host) throws PageException { 200 if(!StringUtil.isEmpty(host,true))this.host = ListUtil.toStringArray(ListUtil.listToArrayRemoveEmpty(host, ',')); 201 } 202 203 /** 204 * @param password the password to set 205 */ 206 public void setPassword(String password) { 207 this.password = password; 208 } 209 210 /** 211 * @param username the username to set 212 */ 213 public void setUsername(String username) { 214 this.username = username; 215 } 216 217 218 public void addHeader(String name, String value) { 219 headers.put(name, value); 220 } 221 222 public void addTo(InternetAddress to) { 223 tos=add(tos,to); 224 } 225 226 public void addTo(Object to) throws UnsupportedEncodingException, PageException, MailException { 227 InternetAddress[] tmp = MailUtil.toInternetAddresses(to); 228 for(int i=0;i<tmp.length;i++) { 229 addTo(tmp[i]); 230 } 231 } 232 233 public void setFrom(InternetAddress from) { 234 this.from=from; 235 } 236 237 public void setFrom(Object from) throws UnsupportedEncodingException, MailException, PageException { 238 InternetAddress[] addrs = MailUtil.toInternetAddresses(from); 239 if(addrs.length==0) return; 240 setFrom(addrs[0]); 241 } 242 243 public void addBCC(InternetAddress bcc) { 244 bccs=add(bccs,bcc); 245 } 246 247 public void addBCC(Object bcc) throws UnsupportedEncodingException, MailException, PageException { 248 InternetAddress[] tmp = MailUtil.toInternetAddresses(bcc); 249 for(int i=0;i<tmp.length;i++) { 250 addBCC(tmp[i]); 251 } 252 } 253 254 public void addCC(InternetAddress cc) { 255 ccs=add(ccs,cc); 256 } 257 258 public void addCC(Object cc) throws UnsupportedEncodingException, MailException, PageException { 259 InternetAddress[] tmp = MailUtil.toInternetAddresses(cc); 260 for(int i=0;i<tmp.length;i++) { 261 addCC(tmp[i]); 262 } 263 } 264 265 public void addReplyTo(InternetAddress rt) { 266 rts=add(rts,rt); 267 } 268 269 public void addReplyTo(Object rt) throws UnsupportedEncodingException, MailException, PageException { 270 InternetAddress[] tmp = MailUtil.toInternetAddresses(rt); 271 for(int i=0;i<tmp.length;i++) { 272 addReplyTo(tmp[i]); 273 } 274 } 275 276 public void addFailTo(InternetAddress ft) { 277 fts=add(fts,ft); 278 } 279 280 public String getHTMLTextAsString() { 281 return htmlText; 282 } 283 public String getPlainTextAsString() { 284 return plainText; 285 } 286 287 public void addFailTo(Object ft) throws UnsupportedEncodingException, MailException, PageException { 288 InternetAddress[] tmp = MailUtil.toInternetAddresses(ft); 289 for(int i=0;i<tmp.length;i++) { 290 addFailTo(tmp[i]); 291 } 292 } 293 294 /** 295 * @param timeout the timeout to set 296 */ 297 public void setTimeout(int timeout) { 298 this.timeout = timeout; 299 } 300 301 public void setSubject(String subject) { 302 this.subject=subject; 303 } 304 305 public void setXMailer(String xmailer) { 306 this.xmailer=xmailer; 307 } 308 309 /** 310 * creates a new expanded array and return it; 311 * @param oldArr 312 * @param newValue 313 * @return new expanded array 314 */ 315 protected static InternetAddress[] add(InternetAddress[] oldArr, InternetAddress newValue) { 316 if(oldArr==null) return new InternetAddress[] {newValue}; 317 //else { 318 InternetAddress[] tmp=new InternetAddress[oldArr.length+1]; 319 for(int i=0;i<oldArr.length;i++) { 320 tmp[i]=oldArr[i]; 321 } 322 tmp[oldArr.length]=newValue; 323 return tmp; 324 //} 325 } 326 327 protected static Attachment[] add(Attachment[] oldArr, Attachment newValue) { 328 if(oldArr==null) return new Attachment[] {newValue}; 329 //else { 330 Attachment[] tmp=new Attachment[oldArr.length+1]; 331 for(int i=0;i<oldArr.length;i++) { 332 tmp[i]=oldArr[i]; 333 } 334 tmp[oldArr.length]=newValue; 335 return tmp; 336 //} 337 } 338 339 public static class MimeMessageAndSession { 340 public final MimeMessage message; 341 public final SessionAndTransport session; 342 343 public MimeMessageAndSession(MimeMessage message,SessionAndTransport session){ 344 this.message=message; 345 this.session=session; 346 } 347 } 348 349 350 private MimeMessageAndSession createMimeMessage(railo.runtime.config.Config config,String hostName, int port, String username, String password, 351 boolean tls,boolean ssl) throws MessagingException { 352 353 Properties props = (Properties) System.getProperties().clone(); 354 355 props.put("mail.smtp.host", hostName); 356 props.put("mail.smtp.timeout", Caster.toString(timeout)); 357 props.put("mail.smtp.connectiontimeout", Caster.toString(timeout)); 358 if(port>0){ 359 props.put("mail.smtp.port", Caster.toString(port)); 360 } 361 if(ssl) { 362 props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 363 props.put("mail.smtp.socketFactory.port", Caster.toString(port)); 364 props.put("mail.smtp.socketFactory.fallback", "false"); 365 } 366 else { 367 props.put("mail.smtp.socketFactory.class", "javax.net.SocketFactory"); 368 props.remove("mail.smtp.socketFactory.port"); 369 props.remove("mail.smtp.socketFactory.fallback"); 370 } 371 Authenticator auth=null; 372 if(!StringUtil.isEmpty(username)) { 373 props.put("mail.smtp.auth", "true"); 374 props.put("mail.smtp.starttls.enable",tls?"true":"false"); 375 376 props.put("mail.smtp.user", username); 377 props.put("mail.smtp.password", password); 378 props.put("password", password); 379 auth=new SMTPAuthenticator( username, password ); 380 } 381 else { 382 props.put("mail.smtp.auth", "false"); 383 props.remove("mail.smtp.starttls.enable"); 384 385 props.remove("mail.smtp.user"); 386 props.remove("mail.smtp.password"); 387 props.remove("password"); 388 } 389 SessionAndTransport sat = SMTPConnectionPool.getSessionAndTransport(props,hash(props),auth); 390 391 // Contacts 392 SMTPMessage msg = new SMTPMessage(sat.session); 393 if(from==null)throw new MessagingException("you have do define the from for the mail"); 394 //if(tos==null)throw new MessagingException("you have do define the to for the mail"); 395 396 checkAddress(from,charset); 397 //checkAddress(tos,charset); 398 399 msg.setFrom(from); 400 //msg.setRecipients(Message.RecipientType.TO, tos); 401 402 if(tos!=null){ 403 checkAddress(tos,charset); 404 msg.setRecipients(Message.RecipientType.TO, tos); 405 } 406 if(ccs!=null){ 407 checkAddress(ccs,charset); 408 msg.setRecipients(Message.RecipientType.CC, ccs); 409 } 410 if(bccs!=null){ 411 checkAddress(bccs,charset); 412 msg.setRecipients(Message.RecipientType.BCC, bccs); 413 } 414 if(rts!=null){ 415 checkAddress(rts,charset); 416 msg.setReplyTo(rts); 417 } 418 if(fts!=null){ 419 checkAddress(fts,charset); 420 msg.setEnvelopeFrom(fts[0].toString()); 421 } 422 423 // Subject and headers 424 try { 425 msg.setSubject(MailUtil.encode(subject, charset)); 426 } catch (UnsupportedEncodingException e) { 427 throw new MessagingException("the encoding "+charset+" is not supported"); 428 } 429 msg.setHeader("X-Mailer", xmailer); 430 431 msg.setHeader("Date",getNow(timeZone)); 432 //msg.setSentDate(new Date()); 433 434 Multipart mp=null; 435 436 // Only HTML 437 if(plainText==null) { 438 if(ArrayUtil.isEmpty(attachmentz) && ArrayUtil.isEmpty(parts)){ 439 fillHTMLText(msg); 440 setHeaders(msg,headers); 441 return new MimeMessageAndSession(msg,sat); 442 } 443 mp = new MimeMultipart(); 444 mp.addBodyPart(getHTMLText()); 445 } 446 // only Plain 447 else if(htmlText==null) { 448 if(ArrayUtil.isEmpty(attachmentz) && ArrayUtil.isEmpty(parts)){ 449 fillPlainText(msg); 450 setHeaders(msg,headers); 451 return new MimeMessageAndSession(msg,sat); 452 } 453 mp = new MimeMultipart(); 454 mp.addBodyPart(getPlainText()); 455 } 456 // Plain and HTML 457 else { 458 mp=new MimeMultipart("alternative"); 459 mp.addBodyPart(getPlainText()); 460 mp.addBodyPart(getHTMLText()); 461 462 if(!ArrayUtil.isEmpty(attachmentz) || !ArrayUtil.isEmpty(parts)){ 463 MimeBodyPart content = new MimeBodyPart(); 464 content.setContent(mp); 465 mp = new MimeMultipart(); 466 mp.addBodyPart(content); 467 } 468 } 469 470 // parts 471 if(!ArrayUtil.isEmpty(parts)){ 472 Iterator<MailPart> it = parts.iterator(); 473 if(mp instanceof MimeMultipart) 474 ((MimeMultipart)mp).setSubType("alternative"); 475 while(it.hasNext()){ 476 mp.addBodyPart(toMimeBodyPart(it.next())); 477 } 478 } 479 480 // Attachments 481 if(!ArrayUtil.isEmpty(attachmentz)){ 482 for(int i=0;i<attachmentz.length;i++) { 483 mp.addBodyPart(toMimeBodyPart(mp,config,attachmentz[i])); 484 } 485 } 486 msg.setContent(mp); 487 setHeaders(msg,headers); 488 489 return new MimeMessageAndSession(msg,sat); 490 } 491 492 private static String hash(Properties props) { 493 Enumeration<?> e = props.propertyNames(); 494 java.util.List<String> names=new ArrayList<String>(); 495 String str; 496 while(e.hasMoreElements()){ 497 str=Caster.toString(e.nextElement(),null); 498 if(!StringUtil.isEmpty(str) && str.startsWith("mail.smtp.")) 499 names.add(str); 500 501 } 502 Collections.sort(names); 503 StringBuilder sb=new StringBuilder(); 504 Iterator<String> it = names.iterator(); 505 while(it.hasNext()){ 506 str=it.next(); 507 sb.append(str).append(':').append(props.getProperty(str)).append(';'); 508 } 509 str=sb.toString(); 510 return MD5.getDigestAsString(str,str); 511 512 } 513 514 private static void setHeaders(SMTPMessage msg, Map<String,String> headers) throws MessagingException { 515 Iterator<Entry<String, String>> it = headers.entrySet().iterator(); 516 Entry<String, String> e; 517 while(it.hasNext()) { 518 e = it.next(); 519 msg.setHeader(e.getKey(),e.getValue()); 520 } 521 } 522 523 private void checkAddress(InternetAddress[] ias,String charset) { // DIFF 23 524 for(int i=0;i<ias.length;i++) { 525 checkAddress(ias[i], charset); 526 } 527 } 528 private void checkAddress(InternetAddress ia,String charset) { // DIFF 23 529 try { 530 if(!StringUtil.isEmpty(ia.getPersonal())) { 531 String personal = MailUtil.encode(ia.getPersonal(), charset); 532 if(!personal.equals(ia.getPersonal())) 533 ia.setPersonal(personal); 534 } 535 } catch (UnsupportedEncodingException e) {} 536 } 537 538 /** 539 * @param plainText 540 */ 541 public void setPlainText(String plainText) { 542 this.plainText=plainText; 543 this.plainTextCharset=charset; 544 } 545 546 /** 547 * @param plainText 548 * @param plainTextCharset 549 */ 550 public void setPlainText(String plainText, String plainTextCharset) { 551 this.plainText=plainText; 552 this.plainTextCharset=plainTextCharset; 553 } 554 555 /** 556 * @param htmlText 557 */ 558 public void setHTMLText(String htmlText) { 559 this.htmlText=htmlText; 560 this.htmlTextCharset=charset; 561 } 562 563 564 565 public boolean hasHTMLText() { 566 return htmlText!=null; 567 } 568 569 public boolean hasPlainText() { 570 return plainText!=null; 571 } 572 573 /** 574 * @param htmlText 575 * @param htmlTextCharset 576 */ 577 public void setHTMLText(String htmlText, String htmlTextCharset) { 578 this.htmlText=htmlText; 579 this.htmlTextCharset=htmlTextCharset; 580 } 581 582 public void addAttachment(URL url) { 583 Attachment mbp = new Attachment(url); 584 attachmentz=add(attachmentz, mbp); 585 } 586 587 public void addAttachment(Resource resource, String type, String disposition, String contentID,boolean removeAfterSend) { 588 Attachment att = new Attachment(resource, type, disposition, contentID,removeAfterSend); 589 attachmentz=add(attachmentz, att); 590 } 591 592 public MimeBodyPart toMimeBodyPart(Multipart mp, railo.runtime.config.Config config,Attachment att) throws MessagingException { 593 594 MimeBodyPart mbp = new MimeBodyPart(); 595 596 // set Data Source 597 String strRes = att.getAbsolutePath(); 598 if(!StringUtil.isEmpty(strRes)){ 599 600 mbp.setDataHandler(new DataHandler(new ResourceDataSource(config.getResource(strRes)))); 601 } 602 else mbp.setDataHandler(new DataHandler(new URLDataSource2(att.getURL()))); 603 604 mbp.setFileName(att.getFileName()); 605 if(!StringUtil.isEmpty(att.getType())) mbp.setHeader("Content-Type", att.getType()); 606 if(!StringUtil.isEmpty(att.getDisposition())){ 607 mbp.setDisposition(att.getDisposition()); 608 if(mp instanceof MimeMultipart) 609 ((MimeMultipart)mp).setSubType("related"); 610 611 } 612 if(!StringUtil.isEmpty(att.getContentID()))mbp.setContentID(att.getContentID()); 613 614 return mbp; 615 } 616 617 /** 618 * @param file 619 * @throws MessagingException 620 * @throws FileNotFoundException 621 */ 622 public void addAttachment(Resource file) throws MessagingException { 623 addAttachment(file,null,null,null,false); 624 } 625 626 627 628 629 public void send(ConfigWeb config) throws MailException { 630 if(ArrayUtil.isEmpty(config.getMailServers()) && ArrayUtil.isEmpty(host)) 631 throw new MailException("no SMTP Server defined"); 632 633 if(plainText==null && htmlText==null) 634 throw new MailException("you must define plaintext or htmltext"); 635 636 if(timeout<1)timeout=config.getMailTimeout()*1000; 637 638 if(spool==SPOOL_YES || (spool==SPOOL_UNDEFINED && config.isMailSpoolEnable())) { 639 config.getSpoolerEngine().add(new MailSpoolerTask(this)); 640 } 641 else 642 _send(config); 643 } 644 645 646 public void _send(railo.runtime.config.ConfigWeb config) throws MailException { 647 long start=System.nanoTime(); 648 try { 649 650 Proxy.start(proxyData); 651 LogAndSource log = config.getMailLogger(); 652 // Server 653 Server[] servers = config.getMailServers(); 654 if(host!=null) { 655 int prt; 656 String usr,pwd; 657 ServerImpl[] nServers = new ServerImpl[host.length]; 658 for(int i=0;i<host.length;i++) { 659 usr=null;pwd=null; 660 prt=ServerImpl.DEFAULT_PORT; 661 662 if(port>0)prt=port; 663 if(!StringUtil.isEmpty(username)) { 664 usr=username; 665 pwd=password; 666 } 667 668 nServers[i]=toServerImpl(host[i],prt,usr,pwd); 669 if(ssl==SSL_YES) nServers[i].setSSL(true); 670 if(tls==TLS_YES) nServers[i].setTLS(true); 671 672 } 673 servers=nServers; 674 } 675 if(servers.length==0) { 676 //return; 677 throw new MailException("no SMTP Server defined"); 678 } 679 680 boolean _ssl,_tls; 681 for(int i=0;i<servers.length;i++) { 682 683 Server server = servers[i]; 684 String _username=null,_password=""; 685 //int _port; 686 687 // username/password 688 689 if(server.hasAuthentication()) { 690 _username=server.getUsername(); 691 _password=server.getPassword(); 692 } 693 694 695 // tls 696 if(tls!=TLS_NONE)_tls=tls==TLS_YES; 697 else _tls=((ServerImpl)server).isTLS(); 698 699 // ssl 700 if(ssl!=SSL_NONE)_ssl=ssl==SSL_YES; 701 else _ssl=((ServerImpl)server).isSSL(); 702 703 704 MimeMessageAndSession msgSess; 705 706 synchronized(LOCK) { 707 try { 708 msgSess = createMimeMessage(config,server.getHostName(),server.getPort(),_username,_password,_tls,_ssl); 709 } catch (MessagingException e) { 710 // listener 711 listener(config,server,log,e,System.nanoTime()-start); 712 MailException me = new MailException(e.getMessage()); 713 me.setStackTrace(e.getStackTrace()); 714 throw me; 715 } 716 try { 717 SerializableObject lock = new SerializableObject(); 718 SMTPSender sender=new SMTPSender(lock,msgSess,server.getHostName(),server.getPort(),_username,_password); 719 sender.start(); 720 SystemUtil.wait(lock, timeout); 721 722 if(!sender.hasSended()) { 723 Throwable t = sender.getThrowable(); 724 if(t!=null) throw Caster.toPageException(t); 725 726 // stop when still running 727 try{ 728 if(sender.isAlive())sender.stop(); 729 } 730 catch(Throwable t2){} 731 732 // after thread s stopped check send flag again 733 if(!sender.hasSended()){ 734 throw new MessagingException("timeout occurred after "+(timeout/1000)+" seconds while sending mail message"); 735 } 736 } 737 clean(config,attachmentz); 738 739 listener(config,server,log,null,System.nanoTime()-start); 740 break; 741 } 742 catch (Exception e) {e.printStackTrace(); 743 if(i+1==servers.length) { 744 745 listener(config,server,log,e,System.nanoTime()-start); 746 MailException me = new MailException(server.getHostName()+" "+LogUtil.toMessage(e)+":"+i); 747 me.setStackTrace(e.getStackTrace()); 748 749 throw me; 750 } 751 } 752 } 753 } 754 } 755 finally { 756 Proxy.end(); 757 } 758 } 759 760 private void listener(ConfigWeb config,Server server, LogAndSource log, Exception e, long exe) { 761 StringBuilder sbTos=new StringBuilder(); 762 for(int i=0;i<tos.length;i++){ 763 if(sbTos.length()>0)sbTos.append(", "); 764 sbTos.append(tos[i].toString()); 765 } 766 767 if(e==null) log.info("mail","mail sended (from:"+from.toString()+"; to:"+sbTos+" subject:"+subject+")"); 768 else log.error("mail",LogUtil.toMessage(e)); 769 770 // listener 771 Map<String,Object> props=new HashMap<String,Object>(); 772 props.put("attachments", this.attachmentz); 773 props.put("bccs", this.bccs); 774 props.put("ccs", this.ccs); 775 props.put("charset", this.charset); 776 props.put("from", this.from); 777 props.put("fts", this.fts); 778 props.put("headers", this.headers); 779 props.put("host", server.getHostName()); 780 props.put("htmlText", this.htmlText); 781 props.put("htmlTextCharset", this.htmlTextCharset); 782 props.put("parts", this.parts); 783 props.put("password", this.password); 784 props.put("plainText", this.plainText); 785 props.put("plainTextCharset", this.plainTextCharset); 786 props.put("port", server.getPort()); 787 props.put("proxyData", this.proxyData); 788 props.put("rts", this.rts); 789 props.put("subject", this.subject); 790 props.put("timeout", this.timeout); 791 props.put("timezone", this.timeZone); 792 props.put("tos", this.tos); 793 props.put("username", this.username); 794 props.put("xmailer", this.xmailer); 795 ((ConfigWebImpl)config).getActionMonitorCollector() 796 .log(config, "mail", "Mail", exe, props); 797 798 } 799 800 801 // remove all atttachements that are marked to remove 802 private static void clean(Config config, Attachment[] attachmentz) { 803 if(attachmentz!=null)for(int i=0;i<attachmentz.length;i++){ 804 if(attachmentz[i].isRemoveAfterSend()){ 805 Resource res = config.getResource(attachmentz[i].getAbsolutePath()); 806 ResourceUtil.removeEL(res,true); 807 } 808 } 809 } 810 811 private MimeBodyPart getHTMLText() throws MessagingException { 812 MimeBodyPart html = new MimeBodyPart(); 813 fillHTMLText(html); 814 return html; 815 } 816 817 private void fillHTMLText(MimePart mp) throws MessagingException { 818 mp.setDataHandler(new DataHandler(new StringDataSource(htmlText,TEXT_HTML ,htmlTextCharset))); 819 mp.setHeader("Content-Transfer-Encoding", "7bit"); 820 mp.setHeader("Content-Type", TEXT_HTML+"; charset="+htmlTextCharset); 821 } 822 823 private MimeBodyPart getPlainText() throws MessagingException { 824 MimeBodyPart plain = new MimeBodyPart(); 825 fillPlainText(plain); 826 return plain; 827 } 828 private void fillPlainText(MimePart mp) throws MessagingException { 829 mp.setDataHandler(new DataHandler(new StringDataSource(plainText,TEXT_PLAIN ,plainTextCharset))); 830 mp.setHeader("Content-Transfer-Encoding", "7bit"); 831 mp.setHeader("Content-Type", TEXT_PLAIN+"; charset="+plainTextCharset); 832 } 833 834 private BodyPart toMimeBodyPart(MailPart part) throws MessagingException { 835 MimeBodyPart mbp = new MimeBodyPart(); 836 mbp.setDataHandler(new DataHandler(new StringDataSource(part.getBody(),part.getType() ,part.getCharset()))); 837 //mbp.setHeader("Content-Transfer-Encoding", "7bit"); 838 //mbp.setHeader("Content-Type", TEXT_PLAIN+"; charset="+plainTextCharset); 839 return mbp; 840 } 841 842 /** 843 * @return the proxyData 844 */ 845 public ProxyData getProxyData() { 846 return proxyData; 847 } 848 849 /** 850 * @param proxyData the proxyData to set 851 */ 852 public void setProxyData(ProxyData proxyData) { 853 this.proxyData = proxyData; 854 } 855 856 /** 857 * @param ssl the ssl to set 858 */ 859 public void setSSL(boolean ssl) { 860 this.ssl = ssl?SSL_YES:SSL_NO; 861 } 862 863 /** 864 * @param tls the tls to set 865 */ 866 public void setTLS(boolean tls) { 867 this.tls = tls?TLS_YES:TLS_NO; 868 } 869 870 /** 871 * @return the subject 872 */ 873 public String getSubject() { 874 return subject; 875 } 876 877 /** 878 * @return the from 879 */ 880 public InternetAddress getFrom() { 881 return from; 882 } 883 884 /** 885 * @return the tos 886 */ 887 public InternetAddress[] getTos() { 888 return tos; 889 } 890 891 /** 892 * @return the bccs 893 */ 894 public InternetAddress[] getBccs() { 895 return bccs; 896 } 897 898 /** 899 * @return the ccs 900 */ 901 public InternetAddress[] getCcs() { 902 return ccs; 903 } 904 905 public void setPart(MailPart part) { 906 if(parts==null) parts=new ArrayList<MailPart>(); 907 parts.add(part); 908 } 909 910 911 public void setTimeZone(TimeZone timeZone) { 912 this.timeZone=timeZone; 913 } 914 }