1 package com.ozacc.mail.impl;
2
3 import java.io.UnsupportedEncodingException;
4 import java.util.Date;
5 import java.util.Properties;
6
7 import javax.mail.AuthenticationFailedException;
8 import javax.mail.MessagingException;
9 import javax.mail.Session;
10 import javax.mail.Transport;
11 import javax.mail.internet.MimeMessage;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15
16 import com.ozacc.mail.Mail;
17 import com.ozacc.mail.MailAuthenticationException;
18 import com.ozacc.mail.MailBuildException;
19 import com.ozacc.mail.MailException;
20 import com.ozacc.mail.MailSendException;
21 import com.ozacc.mail.SendMail;
22
23 /***
24 * SendMail¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Î¼ÂÁõ¥¯¥é¥¹¡£
25 *
26 * @since 1.0
27 * @author Tomohiro Otsuka
28 * @version $Id: SendMailImpl.java,v 1.7 2004/09/20 21:43:15 otsuka Exp $
29 */
30 public class SendMailImpl implements SendMail {
31
32 private static Log log = LogFactory.getLog(SendMailImpl.class);
33
34 /*** ¥Ç¥Õ¥©¥?¥È¤Î¥×¥úÁÈ¥³¥?¡£¡Ösmtp¡× */
35 public static final String DEFAULT_PROTOCOL = "smtp";
36
37 /***
38 * ¥Ç¥Õ¥©¥?¥È¤Î¥Ý¡¼¥È¡£¡Ö-1¡×<br>
39 * -1¤Ï¥×¥úÁÈ¥³¥?¤Ë±?¤¸¤¿Å¬Àڤʥݡ¼¥È¤òÀßÄꤹ¤?ÆÃÊ̤ÊÃÍ¡£
40 * */
41 public static final int DEFAULT_PORT = -1;
42
43 /*** ¥Ç¥Õ¥©¥?¥È¤ÎSMTP¥µ¡¼¥Ð¡£¡Ölocalhost¡× */
44 public static final String DEFAULT_HOST = "localhost";
45
46 /*** ISO-2022-JP */
47 public static final String JIS_CHARSET = "ISO-2022-JP";
48
49 private static final String RETURN_PATH_KEY = "mail.smtp.from";
50
51 private String protocol = DEFAULT_PROTOCOL;
52
53 private String host = DEFAULT_HOST;
54
55 private int port = DEFAULT_PORT;
56
57 private String username;
58
59 private String password;
60
61 private String charset = JIS_CHARSET;
62
63 private String returnPath;
64
65 private String messageId;
66
67 /***
68 * ¥³¥ó¥¹¥È¥é¥¯¥¿¡£
69 */
70 public SendMailImpl() {}
71
72 /***
73 * ¥³¥ó¥¹¥È¥é¥¯¥¿¡£»ÈÍѤ¹¤?SMTP¥µ¡¼¥Ð¤ò»ØÄꤷ¤Þ¤¹¡£
74 *
75 * @param host SMTP¥µ¡¼¥Ð¤Î¥Û¥¹¥È̾¡¢¤Þ¤¿¤ÏIP¥¢¥É¥?¥¹
76 */
77 public SendMailImpl(String host) {
78 this();
79 setHost(host);
80 }
81
82 /***
83 * @see com.ozacc.mail.SendMail#send(com.ozacc.mail.Mail)
84 */
85 public void send(Mail mail) throws MailException {
86 send(new Mail[] { mail });
87 }
88
89 /***
90 * @see com.ozacc.mail.SendMail#send(com.ozacc.mail.Mail[])
91 */
92 public void send(Mail[] mails) throws MailException {
93 MimeMessageWrapper[] mmws = new MimeMessageWrapper[mails.length];
94 Session session = Session.getInstance(new Properties());
95 for (int i = 0; i < mails.length; i++) {
96 Mail mail = mails[i];
97
98
99 MimeMessage message = createMimeMessage(session);
100 MimeMessageBuilder builder = new MimeMessageBuilder(message);
101 try {
102 builder.buildMimeMessage(mail);
103 } catch (UnsupportedEncodingException e) {
104 throw new MailBuildException("¥µ¥Ý¡¼¥È¤µ¤?¤Æ¤¤¤Ê¤¤Ê¸»ú¥³¡¼¥É¤¬»ØÄꤵ¤?¤Þ¤·¤¿¡£", e);
105 } catch (MessagingException e) {
106 throw new MailBuildException("MimeMessage¤ÎÀ¸À®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", e);
107 }
108
109
110 String returnPath;
111 if (mail.getReturnPath() != null) {
112 returnPath = mail.getReturnPath().getAddress();
113 } else {
114 returnPath = this.returnPath;
115 }
116
117 mmws[i] = new MimeMessageWrapper(message, returnPath);
118 }
119 processSend(mmws);
120 }
121
122 /***
123 * @see com.ozacc.mail.SendMail#send(javax.mail.internet.MimeMessage)
124 */
125 public void send(MimeMessage message) throws MailException {
126 send(new MimeMessage[] { message });
127 }
128
129 /***
130 * @see com.ozacc.mail.SendMail#send(javax.mail.internet.MimeMessage[])
131 */
132 public void send(MimeMessage[] messages) throws MailException {
133 MimeMessageWrapper[] mmws = new MimeMessageWrapper[messages.length];
134 for (int i = 0; i < messages.length; i++) {
135 mmws[i] = new MimeMessageWrapper(messages[i], returnPath);
136 }
137 processSend(mmws);
138 }
139
140 private void processSend(MimeMessageWrapper[] mmws) throws MailException {
141
142 Session session = Session.getInstance(new Properties());
143
144 Transport transport = null;
145 try {
146
147 log.debug("SMTP¥µ¡¼¥Ð[" + host + "]¤ËÀܳ¤·¤Þ¤¹¡£");
148 transport = session.getTransport(protocol);
149 transport.connect(host, port, username, password);
150 log.debug("SMTP¥µ¡¼¥Ð[" + host + "]¤ËÀܳ¤·¤Þ¤·¤¿¡£");
151
152 for (int i = 0; i < mmws.length; i++) {
153 MimeMessage mimeMessage = mmws[i].getMimeMessage();
154 String returnPath = mmws[i].getReturnPath();
155
156
157 if (returnPath != null) {
158 session.getProperties().put(RETURN_PATH_KEY, returnPath);
159 log.debug("Return-Path[" + returnPath + "]¤òÀßÄꤷ¤Þ¤·¤¿¡£");
160 }
161
162
163 mimeMessage.setSentDate(new Date());
164
165 mimeMessage.saveChanges();
166
167
168 log.debug("¥á¡¼¥?¤òÁ÷¿®¤·¤Þ¤¹¡£");
169 transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
170 log.debug("¥á¡¼¥?¤òÁ÷¿®¤·¤Þ¤·¤¿¡£");
171
172
173 if (returnPath != null) {
174 session.getProperties().remove(RETURN_PATH_KEY);
175 log.debug("Return-PathÀßÄê¤ò¥¯¥?¥¢¤·¤Þ¤·¤¿¡£");
176 }
177 }
178 } catch (AuthenticationFailedException ex) {
179 log.error("SMTP¥µ¡¼¥Ð[" + host + "]¤Ø¤ÎÀܳǧ¾Ú¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", ex);
180 throw new MailAuthenticationException(ex);
181 } catch (MessagingException ex) {
182 log.error("¥á¡¼¥?¤ÎÁ÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", ex);
183 throw new MailSendException("¥á¡¼¥?¤ÎÁ÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", ex);
184 } finally {
185 if (transport != null && transport.isConnected()) {
186 log.debug("SMTP¥µ¡¼¥Ð[" + host + "]¤È¤ÎÀܳ¤òÀÚÃǤ·¤Þ¤¹¡£");
187 try {
188
189 transport.close();
190 } catch (MessagingException e) {
191 log.error("SMTP¥µ¡¼¥Ð[" + host + "]¤È¤ÎÀܳÀÚÃǤ˼ºÇÔ¤·¤Þ¤·¤¿¡£", e);
192 throw new MailException("SMTP¥µ¡¼¥Ð[" + host + "]¤È¤ÎÀܳÀÚÃǤ˼ºÇÔ¤·¤Þ¤·¤¿¡£");
193 }
194 log.debug("SMTP¥µ¡¼¥Ð[" + host + "]¤È¤ÎÀܳ¤òÀÚÃǤ·¤Þ¤·¤¿¡£");
195 }
196 }
197 }
198
199 /***
200 * ¿·¤·¤¤MimeMessage¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¤Þ¤¹¡£<br>
201 * messageId¥×¥úÁѥƥ£¤¬¥»¥Ã¥È¤µ¤?¤Æ¤¤¤?¾?¹ç¡¢OMLMimeMessage¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤òÀ¸À®¤·¤Þ¤¹¡£
202 *
203 * @return ¿·¤·¤¤MimeMessage¥ª¥Ö¥¸¥§¥¯¥È
204 */
205 private MimeMessage createMimeMessage(Session session) {
206 if (messageId == null) {
207 return new MimeMessage(session);
208 }
209 return new OMLMimeMessage(session, messageId);
210 }
211
212 /***
213 * ¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ë»ÈÍѤ¹¤?ʸ»ú¥³¡¼¥É¤òÊÖ¤·¤Þ¤¹¡£
214 *
215 * @return ¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ë»ÈÍѤ¹¤?ʸ»ú¥³¡¼¥É
216 */
217 public String getCharset() {
218 return charset;
219 }
220
221 /***
222 * ¥á¡¼¥?¤Î·?̾¤äËÜʸ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ë»ÈÍѤ¹¤?ʸ»ú¥³¡¼¥É¤ò»ØÄꤷ¤Þ¤¹¡£
223 * ¥Ç¥Õ¥©¥?¥È¤Ï<code>ISO-2022-JP</code>¤Ç¤¹¡£
224 * <p>
225 * Æ?Ëܸ?´Ä¶¤ÇÍøÍѤ¹¤?¾?¹ç¤ÏÄ̾?Êѹ¹¤¹¤?ɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
226 *
227 * @param charset ¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ë»ÈÍѤ¹¤?ʸ»ú¥³¡¼¥É
228 */
229 public void setCharset(String charset) {
230 this.charset = charset;
231 }
232
233 /***
234 * ¥»¥Ã¥È¤µ¤?¤¿SMTP¥µ¡¼¥Ð¤Î¥Û¥¹¥È̾¡¢¤Þ¤¿¤ÏIP¥¢¥É¥?¥¹¤òÊÖ¤·¤Þ¤¹¡£
235 *
236 * @return SMTP¥µ¡¼¥Ð¤Î¥Û¥¹¥È̾¡¢¤Þ¤¿¤ÏIP¥¢¥É¥?¥¹
237 */
238 public String getHost() {
239 return host;
240 }
241
242 /***
243 * SMTP¥µ¡¼¥Ð¤Î¥Û¥¹¥È̾¡¢¤Þ¤¿¤ÏIP¥¢¥É¥?¥¹¤ò¥»¥Ã¥È¤·¤Þ¤¹¡£
244 * ¥Ç¥Õ¥©¥?¥È¤Ï localhost ¤Ç¤¹¡£
245 *
246 * @param host SMTP¥µ¡¼¥Ð¤Î¥Û¥¹¥È̾¡¢¤Þ¤¿¤ÏIP¥¢¥É¥?¥¹
247 */
248 public void setHost(String host) {
249 this.host = host;
250 }
251
252 /***
253 * @return SMTP¥µ¡¼¥Ðǧ¾Ú¥Ñ¥¹¥?¡¼¥É
254 */
255 public String getPassword() {
256 return password;
257 }
258
259 /***
260 * SMTP¥µ¡¼¥Ð¤ÎÀܳǧ¾Ú¤¬É¬Íפʾ?¹ç¤Ë¥Ñ¥¹¥?¡¼¥É¤ò¥»¥Ã¥È¤·¤Þ¤¹¡£
261 *
262 * @param password SMTP¥µ¡¼¥Ðǧ¾Ú¥Ñ¥¹¥?¡¼¥É
263 */
264 public void setPassword(String password) {
265 this.password = password;
266 }
267
268 /***
269 * @return SMTP¥µ¡¼¥Ð¤Î¥Ý¡¼¥ÈÈÖ¹?
270 */
271 public int getPort() {
272 return port;
273 }
274
275 /***
276 * SMTP¥µ¡¼¥Ð¤Î¥Ý¡¼¥ÈÈÖ¹æ¤ò¥»¥Ã¥È¤·¤Þ¤¹¡£
277 *
278 * @param port SMTP¥µ¡¼¥Ð¤Î¥Ý¡¼¥ÈÈÖ¹?
279 */
280 public void setPort(int port) {
281 this.port = port;
282 }
283
284 /***
285 * @return Returns the protocol.
286 */
287 public String getProtocol() {
288 return protocol;
289 }
290
291 /***
292 * @param protocol The protocol to set.
293 */
294 public void setProtocol(String protocol) {
295 this.protocol = protocol;
296 }
297
298 /***
299 * @return Return-Path¥¢¥É¥?¥¹
300 */
301 public String getReturnPath() {
302 return returnPath;
303 }
304
305 /***
306 * Return-Path¥¢¥É¥?¥¹¤ò¥»¥Ã¥È¤·¤Þ¤¹¡£
307 * <p>
308 * Á÷¿®¤¹¤?Mail¥¤¥ó¥¹¥¿¥ó¥¹¤Ë»ØÄꤵ¤?¤¿From¥¢¥É¥?¥¹°Ê³°¤Î¥¢¥É¥?¥¹¤òReturn-Path¤È¤·¤¿¤¤¾?¹ç¤Ë»ÈÍѤ·¤Þ¤¹¡£
309 * ¤³¤³¤Ç¥»¥Ã¥È¤µ¤?¤¿Return-Path¤è¤ê¡¢Mail¥¤¥ó¥¹¥¿¥ó¥¹¤Ë¥»¥Ã¥È¤µ¤?¤¿Return-Path¤¬Í¥À褵¤?¤Þ¤¹¡£
310 *
311 * @param returnPath Return-Path¥¢¥É¥?¥¹
312 */
313 public void setReturnPath(String returnPath) {
314 this.returnPath = returnPath;
315 }
316
317 /***
318 * @return SMTP¥µ¡¼¥Ðǧ¾Ú¥æ¡¼¥¶Ì¾
319 */
320 public String getUsername() {
321 return username;
322 }
323
324 /***
325 * SMTP¥µ¡¼¥Ð¤ÎÀܳǧ¾Ú¤¬É¬Íפʾ?¹ç¤Ë¥æ¡¼¥¶Ì¾¤ò¥»¥Ã¥È¤·¤Þ¤¹¡£
326 *
327 * @param username SMTP¥µ¡¼¥Ðǧ¾Ú¥æ¡¼¥¶Ì¾
328 */
329 public void setUsername(String username) {
330 this.username = username;
331 }
332
333 /***
334 * À¸À®¤µ¤?¤?MimeMessage¤ËÉÕ¤±¤é¤?¤?Message-Id¥Ø¥Ã¥À¤Î¥É¥á¥¤¥óÉôʬ¤ò»ØÄꤷ¤Þ¤¹¡£<br>
335 * »ØÄꤵ¤?¤Ê¤¤¾?¹?(null¤ä¶õʸ»úÎó¤Î¾?¹?)¤Ï¡¢JavaMail¤¬Message-Id¥Ø¥Ã¥À¤òÀ¸À®¤·¤Þ¤¹¡£
336 * JavaMail¤¬À¸À®¤¹¤?¡ÖJavaMail.¼Â¹Ô¥æ¡¼¥¶Ì¾@¥Û¥¹¥È̾¡×¤ÎMessage-Id¤òÈò¤±¤¿¤¤¾?¹ç¤Ë¡¢¤³¤Î¥á¥½¥Ã¥É¤ò»ÈÍѤ·¤Þ¤¹¡£
337 * <p>
338 * messageId¥×¥úÁѥƥ£¤¬¥»¥Ã¥È¤µ¤?¤Æ¤¤¤?¾?¹ç¡¢Mail¤«¤éÀ¸À®¤µ¤?¤?MimeMessage¤ÎMessage-Id¤Ë¤Ï
339 * <code>¥¿¥¤¥à¥¹¥¿¥ó¥× + ¥é¥ó¥À¥à¤ËÀ¸À®¤µ¤?¤?16·å¤Î¿ôÃÍ + ¤³¤³¤Ç¥»¥Ã¥È¤µ¤?¤¿ÃÍ</code>
340 * ¤¬»ÈÍѤµ¤?¤Þ¤¹¡£
341 * <p>
342 * À¸À®¤µ¤?¤?Message-Id¤ÎÎã¡£ (¼ÂºÝ¤Î¿ôÃÍÉôʬ¤ÏÁ÷¿®¥á¡¼¥?Ëè¤ËÊѤ?¤ê¤Þ¤¹)<ul>
343 * <li>messageId¤Ë'example.com'¤ò»ØÄꤷ¤¿¾?¹ç¡¦¡¦¡¦1095714924963.5619528074501343@example.com</li>
344 * <li>messageId¤Ë'@example.com'¤ò»ØÄꤷ¤¿¾?¹ç¡¦¡¦¡¦1095714924963.5619528074501343@example.com (¾å¤ÈƱ¤¸)</li>
345 * <li>messageId¤Ë'OML@example.com'¤ò»ØÄꤷ¤¿¾?¹ç¡¦¡¦¡¦1095714924963.5619528074501343.OML@example.com</li>
346 * <li>messageId¤Ë'.OML@example.com'¤ò»ØÄꤷ¤¿¾?¹ç¡¦¡¦¡¦1095714924963.5619528074501343.OML@example.com (¾å¤ÈƱ¤¸)</li>
347 * </ul>
348 * <p>
349 * <strong>Ã?:</strong> ¤³¤ÎMessage-Id¤Ï<code>send(Mail)</code>¤«<code>send(Mail[])</code>¥á¥½¥Ã¥É¤¬¸Æ¤Ó¤À¤?¤¿»?¤Ë¤Î¤ß͸ú¤Ç¤¹¡£MimeMessage¤òľÀÜÁ÷¿®¤¹¤?¾?¹ç¤Ë¤ÏŬÍѤµ¤?¤Þ¤»¤ó¡£
350 *
351 * @param messageId ¥á¡¼¥?¤ËÉÕ¤±¤é¤?¤?Message-Id¥Ø¥Ã¥À¤Î¥É¥á¥¤¥óÉôʬ
352 * @throws IllegalArgumentException @¤òÊ£¿ô´Þ¤ó¤Àʸ»úÎó¤ò»ØÄꤷ¤¿¾?¹?
353 */
354 public void setMessageId(String messageId) {
355 if (messageId == null || messageId.length() < 1) {
356 return;
357 }
358
359 String[] parts = messageId.split("@");
360 if (parts.length > 2) {
361 throw new IllegalArgumentException("messageId¥×¥úÁѥƥ£¤Ë'@'¤òÊ£¿ô´Þ¤à¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó¡£[" + messageId
362 + "]");
363 }
364
365 this.messageId = messageId;
366 }
367
368 /***
369 * MimeMessage¥¤¥ó¥¹¥¿¥ó¥¹¤È¡¢¤½¤Î¥á¡¼¥?¤ËÂб?¤¹¤?Return-Path¤ò¥é¥Ã¥×¤¹¤?¥¯¥é¥¹¡£
370 *
371 * @author Tomohiro Otsuka
372 * @version $Id: SendMailImpl.java,v 1.7 2004/09/20 21:43:15 otsuka Exp $
373 */
374 private static class MimeMessageWrapper {
375
376 private MimeMessage mimeMessage;
377
378 private String returnPath;
379
380 public MimeMessageWrapper(MimeMessage mimeMessage, String returnPath) {
381 this.mimeMessage = mimeMessage;
382 this.returnPath = returnPath;
383 }
384
385 public MimeMessage getMimeMessage() {
386 return mimeMessage;
387 }
388
389 public String getReturnPath() {
390 return returnPath;
391 }
392
393 }
394
395 }