1 11 12 package org.jivesoftware.util; 13 14 import java.security.Security ; 15 import java.text.SimpleDateFormat ; 16 import java.util.*; 17 import java.util.concurrent.ThreadPoolExecutor ; 18 import java.util.concurrent.TimeUnit ; 19 import java.util.concurrent.ArrayBlockingQueue ; 20 21 import javax.mail.Address ; 22 import javax.mail.*; 23 import javax.mail.internet.*; 24 25 66 public class EmailService { 67 68 private static final String SSL_FACTORY = "org.jivesoftware.util.SimpleSSLSocketFactory"; 69 70 private static EmailService instance = new EmailService(); 71 72 public static EmailService getInstance() { 73 return instance; 74 } 75 76 private String host; 77 private int port; 78 private String username; 79 private String password; 80 private boolean sslEnabled; 81 private boolean debugEnabled; 82 83 private ThreadPoolExecutor executor; 84 private Session session = null; 85 86 89 private EmailService() { 90 executor = new ThreadPoolExecutor (1, Integer.MAX_VALUE, 60, 91 TimeUnit.SECONDS, new ArrayBlockingQueue <Runnable >(5)); 92 93 host = JiveGlobals.getProperty("mail.smtp.host", "localhost"); 94 port = JiveGlobals.getIntProperty("mail.smtp.port", 25); 95 username = JiveGlobals.getProperty("mail.smtp.username"); 96 password = JiveGlobals.getProperty("mail.smtp.password"); 97 sslEnabled = JiveGlobals.getBooleanProperty("mail.smtp.ssl"); 98 debugEnabled = JiveGlobals.getBooleanProperty("mail.debug"); 99 } 100 101 108 public MimeMessage createMimeMessage() { 109 if (session == null) { 110 createSession(); 111 } 112 return new MimeMessage(session); 113 } 114 115 121 public void sendMessage(MimeMessage message) { 122 if (message != null) { 123 sendMessages(Collections.singletonList(message)); 124 } 125 else { 126 Log.error("Cannot add null email message to queue."); 127 } 128 } 129 130 136 public void sendMessages(Collection<MimeMessage> messages) { 137 if (messages.size() == 0) { 139 return; 140 } 141 executor.execute(new EmailTask(messages)); 142 } 143 144 165 public void sendMessage(String toName, String toEmail, String fromName, 166 String fromEmail, String subject, String textBody, String htmlBody) 167 { 168 if (toEmail == null || fromEmail == null || subject == null || 170 (textBody == null && htmlBody == null)) 171 { 172 Log.error("Error sending email: Invalid fields: " 173 + ((toEmail == null) ? "toEmail " : "") 174 + ((fromEmail == null) ? "fromEmail " : "") 175 + ((subject == null) ? "subject " : "") 176 + ((textBody == null && htmlBody == null) ? "textBody or htmlBody " : "") 177 ); 178 } 179 else { 180 try { 181 String encoding = MimeUtility.mimeCharset("iso-8859-1"); 182 MimeMessage message = createMimeMessage(); 183 Address to = null; 184 Address from = null; 185 186 if (toName != null) { 187 to = new InternetAddress(toEmail, toName, encoding); 188 } 189 else { 190 to = new InternetAddress(toEmail, "", encoding); 191 } 192 193 if (fromName != null) { 194 from = new InternetAddress(fromEmail, fromName, encoding); 195 } 196 else { 197 from = new InternetAddress(fromEmail, "", encoding); 198 } 199 200 SimpleDateFormat format = new SimpleDateFormat ("EEE, dd MMM yyyy HH:mm:ss Z", 202 java.util.Locale.US); 203 format.setTimeZone(JiveGlobals.getTimeZone()); 204 message.setHeader("Date", format.format(new Date())); 205 message.setHeader("Content-Transfer-Encoding", "8bit"); 206 message.setRecipient(Message.RecipientType.TO, to); 207 message.setFrom(from); 208 message.setSubject(StringUtils.replace(subject, "\n", ""), encoding); 209 if (textBody != null && htmlBody != null) { 211 MimeMultipart content = new MimeMultipart("alternative"); 212 MimeBodyPart text = new MimeBodyPart(); 214 text.setText(textBody, encoding); 215 text.setDisposition(Part.INLINE); 216 content.addBodyPart(text); 217 MimeBodyPart html = new MimeBodyPart(); 219 html.setContent(htmlBody, "text/html"); 220 html.setDisposition(Part.INLINE); 221 content.addBodyPart(html); 222 message.setContent(content); 224 message.setDisposition(Part.INLINE); 225 sendMessage(message); 226 } 227 else if (textBody != null) { 228 MimeBodyPart bPart = new MimeBodyPart(); 229 bPart.setText(textBody, encoding); 230 bPart.setDisposition(Part.INLINE); 231 MimeMultipart mPart = new MimeMultipart(); 232 mPart.addBodyPart(bPart); 233 message.setContent(mPart); 234 message.setDisposition(Part.INLINE); 235 sendMessage(message); 237 } 238 else if (htmlBody != null) { 239 MimeBodyPart bPart = new MimeBodyPart(); 240 bPart.setContent(htmlBody, "text/html"); 241 bPart.setDisposition(Part.INLINE); 242 MimeMultipart mPart = new MimeMultipart(); 243 mPart.addBodyPart(bPart); 244 message.setContent(mPart); 245 message.setDisposition(Part.INLINE); 246 sendMessage(message); 248 } 249 } 250 catch (Exception e) { 251 Log.error(e); 252 } 253 } 254 } 255 256 264 public void sendMessagesImmediately(Collection<MimeMessage> messages) 265 throws MessagingException 266 { 267 EmailTask task = new EmailTask(messages); 268 task.sendMessages(); 269 } 270 271 276 public String getHost() { 277 return host; 278 } 279 280 285 public void setHost(String host) { 286 this.host = host; 287 JiveGlobals.setProperty("mail.smtp.host", host); 288 session = null; 289 } 290 291 297 public int getPort() { 298 return port; 299 } 300 301 307 public void setPort(int port) { 308 if (port < 0) { 309 throw new IllegalArgumentException ("Invalid port value: " + port); 310 } 311 this.port = port; 312 JiveGlobals.setProperty("mail.smtp.port", Integer.toString(port)); 313 session = null; 314 } 315 316 323 public String getUsername() { 324 return username; 325 } 326 327 333 public void setUsername(String username) { 334 this.username = username; 335 if (username == null) { 336 JiveGlobals.deleteProperty("mail.smtp.username"); 337 } 338 else { 339 JiveGlobals.setProperty("mail.smtp.username", username); 340 } 341 session = null; 342 } 343 344 351 public String getPassword() { 352 return password; 353 } 354 355 361 public void setPassword(String password) { 362 this.password = password; 363 if (password == null) { 364 JiveGlobals.deleteProperty("mail.smtp.password"); 365 } 366 else { 367 JiveGlobals.setProperty("mail.smtp.password", password); 368 } 369 session = null; 370 } 371 372 378 public boolean isDebugEnabled() { 379 return debugEnabled; 380 } 381 382 388 public void setDebugEnabled(boolean debugEnabled) { 389 this.debugEnabled = debugEnabled; 390 JiveGlobals.setProperty("mail.debug", Boolean.toString(debugEnabled)); 391 session = null; 392 } 393 394 399 public boolean isSSLEnabled() { 400 return sslEnabled; 401 } 402 403 409 public void setSSLEnabled(boolean sslEnabled) { 410 this.sslEnabled = sslEnabled; 411 JiveGlobals.setProperty("mail.smtp.ssl", Boolean.toString(sslEnabled)); 412 session = null; 413 } 414 415 418 private synchronized void createSession() { 419 if (host == null) { 420 throw new IllegalArgumentException ("Host cannot be null."); 421 } 422 423 Properties mailProps = new Properties(); 424 mailProps.setProperty("mail.smtp.host", host); 425 mailProps.setProperty("mail.smtp.port", String.valueOf(port)); 426 mailProps.setProperty("mail.smtp.sendpartial", "true"); 428 mailProps.setProperty("mail.debug", String.valueOf(debugEnabled)); 429 430 if (sslEnabled) { 434 Security.setProperty("ssl.SocketFactory.provider", SSL_FACTORY); 436 437 mailProps.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY); 438 mailProps.setProperty("mail.smtp.socketFactory.fallback", "true"); 439 } 440 441 if (username != null) { 443 mailProps.put("mail.smtp.auth", "true"); 444 } 445 session = Session.getInstance(mailProps, null); 446 } 447 448 451 private class EmailTask implements Runnable { 452 453 private Collection<MimeMessage> messages; 454 455 public EmailTask(Collection<MimeMessage> messages) { 456 this.messages = messages; 457 } 458 459 public void run() { 460 try { 461 sendMessages(); 462 } 463 catch (MessagingException me) { 464 Log.error(me); 465 } 466 } 467 468 public void sendMessages() throws MessagingException { 469 Transport transport = null; 470 try { 471 URLName url = new URLName("smtp", host, port, "", username, password); 472 if (session == null) { 473 createSession(); 474 } 475 transport = new com.sun.mail.smtp.SMTPTransport(session, url); 476 transport.connect(host, port, username, password); 477 for (MimeMessage message : messages) { 478 try { 481 transport.sendMessage(message, 482 message.getRecipients(MimeMessage.RecipientType.TO)); 483 } 484 catch (AddressException ae) { 485 Log.error(ae); 486 } 487 catch (SendFailedException sfe) { 488 Log.error(sfe); 489 } 490 } 491 } 492 finally { 493 if (transport != null) { 494 try { 495 transport.close(); 496 } 497 catch (MessagingException e) { } 498 } 499 } 500 } 501 } 502 } | Popular Tags |