View Javadoc

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   * @author Tomohiro Otsuka
27   * @version $Id: SendMailImpl.java,v 1.5 2004/09/05 16:16:23 otsuka Exp $
28   */
29  public class SendMailImpl implements SendMail {
30  
31  	private static Log log = LogFactory.getLog(SendMailImpl.class);
32  
33  	/*** デフォ�?トのプ��組コ�?。「smtp」 */
34  	public static final String DEFAULT_PROTOCOL = "smtp";
35  
36  	/***
37  	 * デフォ�?トのポート。「-1」<br>
38  	 * -1はプ��組コ�?に�?じた適切なポートを設定す�?特別な値。
39  	 * */
40  	public static final int DEFAULT_PORT = -1;
41  
42  	/*** デフォ�?トのSMTPサーバ。「localhost」 */
43  	public static final String DEFAULT_HOST = "localhost";
44  
45  	/*** ISO-2022-JP */
46  	public static final String JIS_CHARSET = "ISO-2022-JP";
47  
48  	private static final String RETURN_PATH_KEY = "mail.smtp.from";
49  
50  	private String protocol = DEFAULT_PROTOCOL;
51  
52  	private String host = DEFAULT_HOST;
53  
54  	private int port = DEFAULT_PORT;
55  
56  	private String username;
57  
58  	private String password;
59  
60  	private String charset = JIS_CHARSET;
61  
62  	private String returnPath;
63  
64  	/***
65  	 * コンストラクタ。
66  	 */
67  	public SendMailImpl() {}
68  
69  	/***
70  	 * コンストラクタ。使用す�?SMTPサーバを指定します。
71  	 * 
72  	 * @param host SMTPサーバのホスト名、またはIPアド�?ス
73  	 */
74  	public SendMailImpl(String host) {
75  		this();
76  		setHost(host);
77  	}
78  
79  	/***
80  	 * @see com.ozacc.mail.SendMail#send(com.ozacc.mail.Mail)
81  	 */
82  	public void send(Mail mail) throws MailException {
83  		send(new Mail[] { mail });
84  	}
85  
86  	/***
87  	 * @see com.ozacc.mail.SendMail#send(com.ozacc.mail.Mail[])
88  	 */
89  	public void send(Mail[] mails) throws MailException {
90  		MimeMessageWrapper[] mmws = new MimeMessageWrapper[mails.length];
91  		Session session = Session.getInstance(new Properties());
92  		for (int i = 0; i < mails.length; i++) {
93  			Mail mail = mails[i];
94  
95  			// MimeMessageを生成
96  			MimeMessage message = createMimeMessage(session);
97  			MimeMessageBuilder builder = new MimeMessageBuilder(message);
98  			try {
99  				builder.buildMimeMessage(mail);
100 			} catch (UnsupportedEncodingException e) {
101 				throw new MailBuildException("サポートさ�?ていない文字コードが指定さ�?ました。", e);
102 			} catch (MessagingException e) {
103 				throw new MailBuildException("MimeMessageの生成に失敗しました。", e);
104 			}
105 
106 			// Return-Pathを取得
107 			String returnPath;
108 			if (mail.getReturnPath() != null) {
109 				returnPath = mail.getReturnPath().getAddress();
110 			} else {
111 				returnPath = this.returnPath;
112 			}
113 
114 			mmws[i] = new MimeMessageWrapper(message, returnPath);
115 		}
116 		processSend(mmws);
117 	}
118 
119 	/***
120 	 * @see com.ozacc.mail.SendMail#send(javax.mail.internet.MimeMessage)
121 	 */
122 	public void send(MimeMessage message) throws MailException {
123 		send(new MimeMessage[] { message });
124 	}
125 
126 	/***
127 	 * @see com.ozacc.mail.SendMail#send(javax.mail.internet.MimeMessage[])
128 	 */
129 	public void send(MimeMessage[] messages) throws MailException {
130 		MimeMessageWrapper[] mmws = new MimeMessageWrapper[messages.length];
131 		for (int i = 0; i < messages.length; i++) {
132 			mmws[i] = new MimeMessageWrapper(messages[i], returnPath);
133 		}
134 		processSend(mmws);
135 	}
136 
137 	private void processSend(MimeMessageWrapper[] mmws) throws MailException {
138 
139 		Session session = Session.getInstance(new Properties());
140 
141 		Transport transport = null;
142 		try {
143 			// SMTPサーバに接続
144 			log.debug("SMTPサーバ[" + host + "]に接続します。");
145 			transport = session.getTransport(protocol);
146 			transport.connect(host, port, username, password);
147 			log.debug("SMTPサーバ[" + host + "]に接続しました。");
148 
149 			for (int i = 0; i < mmws.length; i++) {
150 				MimeMessage mimeMessage = mmws[i].getMimeMessage();
151 				String returnPath = mmws[i].getReturnPath();
152 
153 				// Return-Pathをセット
154 				if (returnPath != null) {
155 					session.getProperties().put(RETURN_PATH_KEY, returnPath);
156 					log.debug("Return-Path[" + returnPath + "]を設定しました。");
157 				}
158 
159 				// 送信�?�?をセット
160 				mimeMessage.setSentDate(new Date());
161 				mimeMessage.saveChanges();
162 				// 送信
163 				log.debug("メー�?を送信します。");
164 				transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
165 				log.debug("メー�?を送信しました。");
166 
167 				// Return-Pathを解�?
168 				if (returnPath != null) {
169 					session.getProperties().remove(RETURN_PATH_KEY);
170 					log.debug("Return-Path設定をク�?アしました。");
171 				}
172 			}
173 		} catch (AuthenticationFailedException ex) {
174 			log.error("SMTPサーバ[" + host + "]への接続認証に失敗しました。", ex);
175 			throw new MailAuthenticationException(ex);
176 		} catch (MessagingException ex) {
177 			log.error("メー�?の送信に失敗しました。", ex);
178 			throw new MailSendException("メー�?の送信に失敗しました。", ex);
179 		} finally {
180 			if (transport != null && transport.isConnected()) {
181 				log.debug("SMTPサーバ[" + host + "]との接続を切断します。");
182 				try {
183 					// SMTPサーバとの接続を切断
184 					transport.close();
185 				} catch (MessagingException e) {
186 					log.error("SMTPサーバ[" + host + "]との接続切断に失敗しました。", e);
187 					throw new MailException("SMTPサーバ[" + host + "]との接続切断に失敗しました。");
188 				}
189 				log.debug("SMTPサーバ[" + host + "]との接続を切断しました。");
190 			}
191 		}
192 	}
193 
194 	/***
195 	 * 新しいMimeMessageオブジェクトを生成します。
196 	 * 
197 	 * @return 新しいMimeMessageオブジェクト
198 	 */
199 	private MimeMessage createMimeMessage(Session session) {
200 		return new MimeMessage(session);
201 	}
202 
203 	/***
204 	 * エンコーディングに使用す�?文字コードを返します。
205 	 * 
206 	 * @return エンコーディングに使用す�?文字コード
207 	 */
208 	public String getCharset() {
209 		return charset;
210 	}
211 
212 	/***
213 	 * メー�?の�?名や本文のエンコーディングに使用す�?文字コードを指定します。
214 	 * デフォ�?トは<code>ISO-2022-JP</code>です。
215 	 * <p>
216 	 * �?本�?環境で利用す�?�?合は通�?変更す�?必要はありません。
217 	 * 
218 	 * @param charset エンコーディングに使用す�?文字コード
219 	 */
220 	public void setCharset(String charset) {
221 		this.charset = charset;
222 	}
223 
224 	/***
225 	 * セットさ�?たSMTPサーバのホスト名、またはIPアド�?スを返します。
226 	 * 
227 	 * @return SMTPサーバのホスト名、またはIPアド�?ス
228 	 */
229 	public String getHost() {
230 		return host;
231 	}
232 
233 	/***
234 	 * SMTPサーバのホスト名、またはIPアド�?スをセットします。
235 	 * デフォ�?トは localhost です。
236 	 * 
237 	 * @param host SMTPサーバのホスト名、またはIPアド�?ス
238 	 */
239 	public void setHost(String host) {
240 		this.host = host;
241 	}
242 
243 	/***
244 	 * @return SMTPサーバ認証パス�?ード
245 	 */
246 	public String getPassword() {
247 		return password;
248 	}
249 
250 	/***
251 	 * SMTPサーバの接続認証が必要な�?合にパス�?ードをセットします。
252 	 * 
253 	 * @param password SMTPサーバ認証パス�?ード
254 	 */
255 	public void setPassword(String password) {
256 		this.password = password;
257 	}
258 
259 	/***
260 	 * @return SMTPサーバのポート番�?
261 	 */
262 	public int getPort() {
263 		return port;
264 	}
265 
266 	/***
267 	 * SMTPサーバのポート番号をセットします。
268 	 * 
269 	 * @param port SMTPサーバのポート番�?
270 	 */
271 	public void setPort(int port) {
272 		this.port = port;
273 	}
274 
275 	/***
276 	 * @return Returns the protocol.
277 	 */
278 	public String getProtocol() {
279 		return protocol;
280 	}
281 
282 	/***
283 	 * @param protocol The protocol to set.
284 	 */
285 	public void setProtocol(String protocol) {
286 		this.protocol = protocol;
287 	}
288 
289 	/***
290 	 * @return Return-Pathアド�?ス
291 	 */
292 	public String getReturnPath() {
293 		return returnPath;
294 	}
295 
296 	/***
297 	 * Return-Pathアド�?スをセットします。
298 	 * <p>
299 	 * 送信す�?Mailインスタンスに指定さ�?たFromアド�?ス以外のアド�?スをReturn-Pathとしたい�?合に使用します。
300 	 * ここでセットさ�?たReturn-Pathより、Mailインスタンスにセットさ�?たReturn-Pathが優先さ�?ます。
301 	 * 
302 	 * @param returnPath Return-Pathアド�?ス
303 	 */
304 	public void setReturnPath(String returnPath) {
305 		this.returnPath = returnPath;
306 	}
307 
308 	/***
309 	 * @return SMTPサーバ認証ユーザ名
310 	 */
311 	public String getUsername() {
312 		return username;
313 	}
314 
315 	/***
316 	 * SMTPサーバの接続認証が必要な�?合にユーザ名をセットします。
317 	 * 
318 	 * @param username SMTPサーバ認証ユーザ名
319 	 */
320 	public void setUsername(String username) {
321 		this.username = username;
322 	}
323 
324 	/***
325 	 * MimeMessageインスタンスと、そのメー�?に対�?す�?Return-Pathをラップす�?クラス。
326 	 * 
327 	 * @author Tomohiro Otsuka
328 	 * @version $Id: SendMailImpl.java,v 1.5 2004/09/05 16:16:23 otsuka Exp $
329 	 */
330 	private static class MimeMessageWrapper {
331 
332 		private MimeMessage mimeMessage;
333 
334 		private String returnPath;
335 
336 		public MimeMessageWrapper(MimeMessage mimeMessage, String returnPath) {
337 			this.mimeMessage = mimeMessage;
338 			this.returnPath = returnPath;
339 		}
340 
341 		public MimeMessage getMimeMessage() {
342 			return mimeMessage;
343 		}
344 
345 		public String getReturnPath() {
346 			return returnPath;
347 		}
348 
349 	}
350 
351 }