1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.mail.javamail;
  17. import java.io.IOException;
  18. import java.util.ArrayList;
  19. import java.util.HashMap;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.Properties;
  23. import javax.mail.AuthenticationFailedException;
  24. import javax.mail.MessagingException;
  25. import javax.mail.NoSuchProviderException;
  26. import javax.mail.Session;
  27. import javax.mail.Transport;
  28. import javax.mail.internet.MimeMessage;
  29. import org.apache.commons.logging.Log;
  30. import org.apache.commons.logging.LogFactory;
  31. import org.springframework.mail.MailAuthenticationException;
  32. import org.springframework.mail.MailException;
  33. import org.springframework.mail.MailParseException;
  34. import org.springframework.mail.MailSendException;
  35. import org.springframework.mail.SimpleMailMessage;
  36. /**
  37. * Implementation of the JavaMailSender interface.
  38. * Can also be used as plain MailSender implementation.
  39. *
  40. * <p>Allows for defining all settings locally as bean properties.
  41. * Alternatively, a pre-configured JavaMail Session can be specified,
  42. * possibly pulled from an application server's JNDI environment.
  43. *
  44. * <p>Non-default properties in this object will always override the settings
  45. * in the JavaMail Session. Note that if overriding all values locally, there
  46. * is no value in setting a pre-configured Session.
  47. *
  48. * @author Dmitriy Kopylenko
  49. * @author Juergen Hoeller
  50. * @since 10.09.2003
  51. * @see JavaMailSender
  52. * @see org.springframework.mail.MailSender
  53. * @version $Id: JavaMailSenderImpl.java,v 1.12 2004/03/18 02:46:14 trisberg Exp $
  54. */
  55. public class JavaMailSenderImpl implements JavaMailSender {
  56. public static final String DEFAULT_PROTOCOL = "smtp";
  57. public static final int DEFAULT_PORT = -1;
  58. protected final Log logger = LogFactory.getLog(getClass());
  59. private Session session = Session.getInstance(new Properties());
  60. private String protocol = DEFAULT_PROTOCOL;
  61. private String host;
  62. private int port = DEFAULT_PORT;
  63. private String username;
  64. private String password;
  65. /**
  66. * Set the JavaMail Session, possibly pulled from JNDI. Default is a new Session
  67. * without defaults, i.e. completely configured via this object's properties.
  68. * <p>If using a pre-configured Session, non-default properties in this
  69. * MailSender will override the settings in the Session.
  70. * @see #setJavaMailProperties
  71. */
  72. public void setSession(Session session) {
  73. if (session == null) {
  74. throw new IllegalArgumentException("Cannot work with a null Session");
  75. }
  76. this.session = session;
  77. }
  78. /**
  79. * Set JavaMail properties for the Session. A new Session will be created
  80. * with those properties. Use either this or setSession, not both.
  81. * <p>Non-default properties in this MailSender will override given
  82. * JavaMail properties.
  83. * @see #setSession
  84. */
  85. public void setJavaMailProperties(Properties javaMailProperties) {
  86. this.session = Session.getInstance(javaMailProperties);
  87. }
  88. /**
  89. * Set the mail protocol. Default is SMTP.
  90. */
  91. public void setProtocol(String protocol) {
  92. this.protocol = protocol;
  93. }
  94. /**
  95. * Set the mail server host, typically an SMTP host.
  96. */
  97. public void setHost(String host) {
  98. this.host = host;
  99. }
  100. /**
  101. * Set the mail server port. Default is -1, letting JavaMail
  102. * use the default SMTP port (25).
  103. */
  104. public void setPort(int port) {
  105. this.port = port;
  106. }
  107. /**
  108. * Set the username for the account at the mail host, if any.
  109. */
  110. public void setUsername(String username) {
  111. this.username = username;
  112. }
  113. /**
  114. * Set the password for the account at the mail host, if any.
  115. */
  116. public void setPassword(String password) {
  117. this.password = password;
  118. }
  119. //---------------------------------------------------------------------
  120. // Implementation of MailSender
  121. //---------------------------------------------------------------------
  122. public void send(SimpleMailMessage simpleMessage) throws MailException {
  123. send(new SimpleMailMessage[] { simpleMessage });
  124. }
  125. public void send(SimpleMailMessage[] simpleMessages) throws MailException {
  126. try {
  127. List mimeMessages = new ArrayList();
  128. for (int i = 0; i < simpleMessages.length; i++) {
  129. SimpleMailMessage simpleMessage = simpleMessages[i];
  130. if (logger.isDebugEnabled()) {
  131. logger.debug("Creating new MIME message using the following mail properties: " + simpleMessage);
  132. }
  133. MimeMessageHelper message = new MimeMessageHelper(createMimeMessage());
  134. if (simpleMessage.getFrom() != null) {
  135. message.setFrom(simpleMessage.getFrom());
  136. }
  137. if (simpleMessage.getTo() != null) {
  138. message.setTo(simpleMessage.getTo());
  139. }
  140. if (simpleMessage.getCc() != null) {
  141. message.setCc(simpleMessage.getCc());
  142. }
  143. if (simpleMessage.getBcc() != null) {
  144. message.setBcc(simpleMessage.getBcc());
  145. }
  146. if (simpleMessage.getSubject() != null) {
  147. message.setSubject(simpleMessage.getSubject());
  148. }
  149. if (simpleMessage.getText() != null) {
  150. message.setText(simpleMessage.getText());
  151. }
  152. mimeMessages.add(message.getMimeMessage());
  153. }
  154. send((MimeMessage[]) mimeMessages.toArray(new MimeMessage[mimeMessages.size()]), simpleMessages);
  155. }
  156. catch (MessagingException ex) {
  157. throw new MailParseException(ex);
  158. }
  159. }
  160. //---------------------------------------------------------------------
  161. // Implementation of JavaMailSender
  162. //---------------------------------------------------------------------
  163. public MimeMessage createMimeMessage() {
  164. return new MimeMessage(this.session);
  165. }
  166. public void send(MimeMessage mimeMessage) throws MailException {
  167. send(new MimeMessage[] { mimeMessage });
  168. }
  169. public void send(MimeMessage[] mimeMessages) throws MailException {
  170. send(mimeMessages, null);
  171. }
  172. public void send(MimeMessage[] mimeMessages, Object[] originalMessages) throws MailException {
  173. Map failedMessages = new HashMap();
  174. try {
  175. Transport transport = getTransport(this.session);
  176. transport.connect(this.host, this.port, this.username, this.password);
  177. try {
  178. for (int i = 0; i < mimeMessages.length; i++) {
  179. MimeMessage mimeMessage = mimeMessages[i];
  180. try {
  181. mimeMessage.saveChanges();
  182. transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
  183. }
  184. catch (MessagingException ex) {
  185. Object original = (originalMessages != null) ? originalMessages[i] : mimeMessage;
  186. failedMessages.put(original, ex);
  187. }
  188. }
  189. }
  190. finally {
  191. transport.close();
  192. }
  193. }
  194. catch (AuthenticationFailedException ex) {
  195. throw new MailAuthenticationException(ex);
  196. }
  197. catch (MessagingException ex) {
  198. throw new MailSendException("Mail server connection failed", ex);
  199. }
  200. if (!failedMessages.isEmpty()) {
  201. throw new MailSendException(failedMessages);
  202. }
  203. }
  204. public void send(MimeMessagePreparator mimeMessagePreparator) throws MailException {
  205. send(new MimeMessagePreparator[] { mimeMessagePreparator });
  206. }
  207. public void send(MimeMessagePreparator[] mimeMessagePreparators) throws MailException {
  208. try {
  209. List mimeMessages = new ArrayList();
  210. for (int i = 0; i < mimeMessagePreparators.length; i++) {
  211. MimeMessage mimeMessage = createMimeMessage();
  212. mimeMessagePreparators[i].prepare(mimeMessage);
  213. mimeMessages.add(mimeMessage);
  214. }
  215. send((MimeMessage[]) mimeMessages.toArray(new MimeMessage[mimeMessages.size()]));
  216. }
  217. catch (MessagingException ex) {
  218. throw new MailParseException(ex);
  219. }
  220. catch (IOException ex) {
  221. throw new MailParseException(ex);
  222. }
  223. }
  224. /**
  225. * Get a Transport object for the given JavaMail Session.
  226. * Can be overridden in subclasses, e.g. to return a mock Transport object.
  227. */
  228. protected Transport getTransport(Session session) throws NoSuchProviderException {
  229. return session.getTransport(this.protocol);
  230. }
  231. }