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