Coverage report

  %line %branch
com.ozacc.mail.impl.SendMailImpl$MimeMessageWrapper
62% 
100% 

 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.InternetAddress;
 12  
 import javax.mail.internet.MimeMessage;
 13  
 
 14  
 import org.apache.commons.logging.Log;
 15  
 import org.apache.commons.logging.LogFactory;
 16  
 
 17  
 import com.ozacc.mail.Mail;
 18  
 import com.ozacc.mail.MailAuthenticationException;
 19  
 import com.ozacc.mail.MailBuildException;
 20  
 import com.ozacc.mail.MailException;
 21  
 import com.ozacc.mail.MailSendException;
 22  
 import com.ozacc.mail.SendMail;
 23  
 
 24  
 /**
 25  
  * SendMailインターフェースの実装クラス。
 26  
  * 
 27  
  * @since 1.0
 28  
  * @author Tomohiro Otsuka
 29  
  * @version $Id: SendMailImpl.java,v 1.7.2.3 2005/01/29 23:09:36 otsuka Exp $
 30  
  */
 31  
 public class SendMailImpl implements SendMail {
 32  
 
 33  
 	private static Log log = LogFactory.getLog(SendMailImpl.class);
 34  
 
 35  
 	/** デフォ�?トのプ��組コ�?。「smtp」 */
 36  
 	public static final String DEFAULT_PROTOCOL = "smtp";
 37  
 
 38  
 	/**
 39  
 	 * デフォ�?トのポート。「-1」<br>
 40  
 	 * -1はプ��組コ�?に�?じた適切なポートを設定す�?特別な値。
 41  
 	 * */
 42  
 	public static final int DEFAULT_PORT = -1;
 43  
 
 44  
 	/** デフォ�?トのSMTPサーバ。「localhost」 */
 45  
 	public static final String DEFAULT_HOST = "localhost";
 46  
 
 47  
 	/** ISO-2022-JP */
 48  
 	public static final String JIS_CHARSET = "ISO-2022-JP";
 49  
 
 50  
 	private static final String RETURN_PATH_KEY = "mail.smtp.from";
 51  
 
 52  
 	/** 接続タイムアウト */
 53  
 	private static final int DEFAULT_CONNECTION_TIMEOUT = 5000;
 54  
 
 55  
 	/** 読�?タイムアウト */
 56  
 	private static final int DEFAULT_READ_TIMEOUT = 5000;
 57  
 
 58  
 	private String protocol = DEFAULT_PROTOCOL;
 59  
 
 60  
 	private String host = DEFAULT_HOST;
 61  
 
 62  
 	private int port = DEFAULT_PORT;
 63  
 
 64  
 	private String username;
 65  
 
 66  
 	private String password;
 67  
 
 68  
 	private String charset = JIS_CHARSET;
 69  
 
 70  
 	private String returnPath;
 71  
 
 72  
 	private String messageId;
 73  
 
 74  
 	private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
 75  
 
 76  
 	private int readTimeout = DEFAULT_READ_TIMEOUT;
 77  
 
 78  
 	/**
 79  
 	 * コンストラクタ。
 80  
 	 */
 81  
 	public SendMailImpl() {}
 82  
 
 83  
 	/**
 84  
 	 * コンストラクタ。使用す�?SMTPサーバを指定します。
 85  
 	 * 
 86  
 	 * @param host SMTPサーバのホスト名、またはIPアド�?ス
 87  
 	 */
 88  
 	public SendMailImpl(String host) {
 89  
 		this();
 90  
 		setHost(host);
 91  
 	}
 92  
 
 93  
 	/**
 94  
 	 * @see com.ozacc.mail.SendMail#send(com.ozacc.mail.Mail)
 95  
 	 */
 96  
 	public void send(Mail mail) throws MailException {
 97  
 		send(new Mail[] { mail });
 98  
 	}
 99  
 
 100  
 	/**
 101  
 	 * @see com.ozacc.mail.SendMail#send(com.ozacc.mail.Mail[])
 102  
 	 */
 103  
 	public void send(Mail[] mails) throws MailException {
 104  
 		MimeMessageWrapper[] mmws = new MimeMessageWrapper[mails.length];
 105  
 		Session session = Session.getInstance(new Properties());
 106  
 		for (int i = 0; i < mails.length; i++) {
 107  
 			Mail mail = mails[i];
 108  
 
 109  
 			// MimeMessageを生成
 110  
 			MimeMessage message = createMimeMessage(session);
 111  
 			MimeMessageBuilder builder = new MimeMessageBuilder(message);
 112  
 			try {
 113  
 				builder.buildMimeMessage(mail);
 114  
 			} catch (UnsupportedEncodingException e) {
 115  
 				throw new MailBuildException("サポートさ�?ていない文字コードが指定さ�?ました。", e);
 116  
 			} catch (MessagingException e) {
 117  
 				throw new MailBuildException("MimeMessageの生成に失敗しました。", e);
 118  
 			}
 119  
 
 120  
 			// Return-Pathを取得
 121  
 			String returnPath;
 122  
 			if (mail.getReturnPath() != null) {
 123  
 				returnPath = mail.getReturnPath().getAddress();
 124  
 			} else {
 125  
 				returnPath = this.returnPath;
 126  
 			}
 127  
 
 128  
 			mmws[i] = new MimeMessageWrapper(message, returnPath, mail.getEnvelopeTo());
 129  
 		}
 130  
 		processSend(mmws);
 131  
 	}
 132  
 
 133  
 	/**
 134  
 	 * @see com.ozacc.mail.SendMail#send(javax.mail.internet.MimeMessage)
 135  
 	 */
 136  
 	public void send(MimeMessage message) throws MailException {
 137  
 		send(new MimeMessage[] { message });
 138  
 	}
 139  
 
 140  
 	/**
 141  
 	 * @see com.ozacc.mail.SendMail#send(javax.mail.internet.MimeMessage[])
 142  
 	 */
 143  
 	public void send(MimeMessage[] messages) throws MailException {
 144  
 		MimeMessageWrapper[] mmws = new MimeMessageWrapper[messages.length];
 145  
 		for (int i = 0; i < messages.length; i++) {
 146  
 			mmws[i] = new MimeMessageWrapper(messages[i], returnPath);
 147  
 		}
 148  
 		processSend(mmws);
 149  
 	}
 150  
 
 151  
 	private void processSend(MimeMessageWrapper[] mmws) throws MailException {
 152  
 
 153  
 		Properties prop = new Properties();
 154  
 		// タイムアウトの設�?
 155  
 		prop.put("mail.smtp.connectiontimeout", String.valueOf(connectionTimeout));
 156  
 		prop.put("mail.smtp.timeout", String.valueOf(readTimeout));
 157  
 		Session session = Session.getInstance(prop);
 158  
 
 159  
 		Transport transport = null;
 160  
 		try {
 161  
 			// SMTPサーバに接続
 162  
 			log.debug("SMTPサーバ[" + host + "]に接続します。");
 163  
 			transport = session.getTransport(protocol);
 164  
 			transport.connect(host, port, username, password);
 165  
 			log.debug("SMTPサーバ[" + host + "]に接続しました。");
 166  
 
 167  
 			for (int i = 0; i < mmws.length; i++) {
 168  
 				MimeMessage mimeMessage = mmws[i].getMimeMessage();
 169  
 				//	Return-Pathをセット
 170  
 				String returnPath = mmws[i].getReturnPath();
 171  
 				if (returnPath != null) {
 172  
 					session.getProperties().put(RETURN_PATH_KEY, returnPath);
 173  
 					log.debug("Return-Path[" + returnPath + "]を設定しました。");
 174  
 				}
 175  
 				// 送信�?�?をセット
 176  
 				mimeMessage.setSentDate(new Date());
 177  
 				mimeMessage.saveChanges();
 178  
 
 179  
 				// 送信
 180  
 				log.debug("メー�?を送信します。");
 181  
 				if (mmws[i].hasEnvelopeTo()) {
 182  
 					log.debug("メー�?はenvelope-toアド�?スに送信さ�?ます。");
 183  
 					transport.sendMessage(mimeMessage, mmws[i].getEnvelopeTo());
 184  
 				} else {
 185  
 					transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
 186  
 				}
 187  
 				log.debug("メー�?を送信しました。");
 188  
 
 189  
 				// Return-Pathを解�?
 190  
 				if (returnPath != null) {
 191  
 					session.getProperties().remove(RETURN_PATH_KEY);
 192  
 					log.debug("Return-Path設定をク�?アしました。");
 193  
 				}
 194  
 			}
 195  
 		} catch (AuthenticationFailedException ex) {
 196  
 			log.error("SMTPサーバ[" + host + "]への接続認証に失敗しました。", ex);
 197  
 			throw new MailAuthenticationException(ex);
 198  
 		} catch (MessagingException ex) {
 199  
 			log.error("メー�?の送信に失敗しました。", ex);
 200  
 			throw new MailSendException("メー�?の送信に失敗しました。", ex);
 201  
 		} finally {
 202  
 			if (transport != null && transport.isConnected()) {
 203  
 				log.debug("SMTPサーバ[" + host + "]との接続を切断します。");
 204  
 				try {
 205  
 					// SMTPサーバとの接続を切断
 206  
 					transport.close();
 207  
 				} catch (MessagingException e) {
 208  
 					log.error("SMTPサーバ[" + host + "]との接続切断に失敗しました。", e);
 209  
 					throw new MailException("SMTPサーバ[" + host + "]との接続切断に失敗しました。");
 210  
 				}
 211  
 				log.debug("SMTPサーバ[" + host + "]との接続を切断しました。");
 212  
 			}
 213  
 		}
 214  
 	}
 215  
 
 216  
 	/**
 217  
 	 * 新しいMimeMessageオブジェクトを生成します。<br>
 218  
 	 * messageIdプ��叢ティがセットさ�?てい�?�?合、OMLMimeMessageのインスタンスを生成します。
 219  
 	 * 
 220  
 	 * @return 新しいMimeMessageオブジェクト
 221  
 	 */
 222  
 	private MimeMessage createMimeMessage(Session session) {
 223  
 		if (isMessageIdCustomized()) {
 224  
 			return new OMLMimeMessage(session, messageId);
 225  
 		}
 226  
 		return new MimeMessage(session);
 227  
 	}
 228  
 
 229  
 	/**
 230  
 	 * Message-Idヘッダのドメイン部分を独自にセットしてい�?かどうか判定します。
 231  
 	 * 
 232  
 	 * @return Message-Idヘッダのドメイン部分を独自にセットしてい�?�?�? true
 233  
 	 */
 234  
 	private boolean isMessageIdCustomized() {
 235  
 		return messageId != null;
 236  
 	}
 237  
 
 238  
 	/**
 239  
 	 * エンコーディングに使用す�?文字コードを返します。
 240  
 	 * 
 241  
 	 * @return エンコーディングに使用す�?文字コード
 242  
 	 */
 243  
 	public String getCharset() {
 244  
 		return charset;
 245  
 	}
 246  
 
 247  
 	/**
 248  
 	 * メー�?の�?名や本文のエンコーディングに使用す�?文字コードを指定します。
 249  
 	 * デフォ�?トは<code>ISO-2022-JP</code>です。
 250  
 	 * <p>
 251  
 	 * �?本�?環境で利用す�?�?合は通�?変更す�?必要はありません。
 252  
 	 * 
 253  
 	 * @param charset エンコーディングに使用す�?文字コード
 254  
 	 */
 255  
 	public void setCharset(String charset) {
 256  
 		this.charset = charset;
 257  
 	}
 258  
 
 259  
 	/**
 260  
 	 * セットさ�?たSMTPサーバのホスト名、またはIPアド�?スを返します。
 261  
 	 * 
 262  
 	 * @return SMTPサーバのホスト名、またはIPアド�?ス
 263  
 	 */
 264  
 	public String getHost() {
 265  
 		return host;
 266  
 	}
 267  
 
 268  
 	/**
 269  
 	 * SMTPサーバのホスト名、またはIPアド�?スをセットします。
 270  
 	 * デフォ�?トは localhost です。
 271  
 	 * 
 272  
 	 * @param host SMTPサーバのホスト名、またはIPアド�?ス
 273  
 	 */
 274  
 	public void setHost(String host) {
 275  
 		this.host = host;
 276  
 	}
 277  
 
 278  
 	/**
 279  
 	 * @return SMTPサーバ認証パス�?ード
 280  
 	 */
 281  
 	public String getPassword() {
 282  
 		return password;
 283  
 	}
 284  
 
 285  
 	/**
 286  
 	 * SMTPサーバの接続認証が必要な�?合にパス�?ードをセットします。
 287  
 	 * 
 288  
 	 * @param password SMTPサーバ認証パス�?ード
 289  
 	 */
 290  
 	public void setPassword(String password) {
 291  
 		this.password = password;
 292  
 	}
 293  
 
 294  
 	/**
 295  
 	 * @return SMTPサーバのポート番�?
 296  
 	 */
 297  
 	public int getPort() {
 298  
 		return port;
 299  
 	}
 300  
 
 301  
 	/**
 302  
 	 * SMTPサーバのポート番号をセットします。
 303  
 	 * 
 304  
 	 * @param port SMTPサーバのポート番�?
 305  
 	 */
 306  
 	public void setPort(int port) {
 307  
 		this.port = port;
 308  
 	}
 309  
 
 310  
 	/**
 311  
 	 * プ��組コ�?を返します。
 312  
 	 * 
 313  
 	 * @return プ��組コ�?
 314  
 	 */
 315  
 	public String getProtocol() {
 316  
 		return protocol;
 317  
 	}
 318  
 
 319  
 	/**
 320  
 	 * プ��組コ�?をセットします。デフォ�?トは「smtp」。
 321  
 	 * 
 322  
 	 * @param protocol プ��組コ�?
 323  
 	 */
 324  
 	public void setProtocol(String protocol) {
 325  
 		this.protocol = protocol;
 326  
 	}
 327  
 
 328  
 	/**
 329  
 	 * @return Return-Pathアド�?ス
 330  
 	 */
 331  
 	public String getReturnPath() {
 332  
 		return class="keyword">returnPath;
 333  
 	}
 334  
 
 335  
 	/**
 336  
 	 * Return-Pathアド�?スをセットします。
 337  
 	 * <p>
 338  
 	 * 送信す�?Mailインスタンスに指定さ�?たFromアド�?ス以外のアド�?スをReturn-Pathとしたい�?合に使用します。
 339  
 	 * ここでセットさ�?たReturn-Pathより、Mailインスタンスにセットさ�?たReturn-Pathが優先さ�?ます。
 340  
 	 * 
 341  
 	 * @param returnPath Return-Pathアド�?ス
 342  
 	 */
 343  
 	public void setReturnPath(String returnPath) {
 344  
 		this.returnPath = returnPath;
 345  
 	}
 346  
 
 347  
 	/**
 348  
 	 * @return SMTPサーバ認証ユーザ名
 349  
 	 */
 350  
 	public String getUsername() {
 351  
 		return username;
 352  
 	}
 353  
 
 354  
 	/**
 355  
 	 * SMTPサーバの接続認証が必要な�?合にユーザ名をセットします。
 356  
 	 * 
 357  
 	 * @param username SMTPサーバ認証ユーザ名
 358  
 	 */
 359  
 	public void setUsername(String username) {
 360  
 		this.username = username;
 361  
 	}
 362  
 
 363  
 	/**
 364  
 	 * SMTPサーバとの接続タイムアウトをセットします。
 365  
 	 * 単位はミ�?秒。デフォ�?トは5,000ミ�?秒(5秒)です。
 366  
 	 * <p>
 367  
 	 * -1を指定す�?と無限大になりますが、お薦めしません。
 368  
 	 * 
 369  
 	 * @since 1.1.4
 370  
 	 * @param connectionTimeout SMTPサーバとの接続タイムアウト
 371  
 	 */
 372  
 	public void setConnectionTimeout(int connectionTimeout) {
 373  
 		this.connectionTimeout = connectionTimeout;
 374  
 	}
 375  
 
 376  
 	/**
 377  
 	 * SMTPサーバへの送信�?のタイムアウトをセットします。
 378  
 	 * 単位はミ�?秒。デフォ�?トは5,000ミ�?秒(5秒)です。<br>
 379  
 	 * 送信�?にタイムアウトす�?と、<code>com.ozacc.mail.MailSendException</code>がス��充さ�?ます。
 380  
 	 * <p>
 381  
 	 * -1を指定す�?と無限大になりますが、お薦めしません。
 382  
 	 * 
 383  
 	 * @since 1.1.4
 384  
 	 * @param readTimeout SMTPサーバへの送受信�?のタイムアウト
 385  
 	 */
 386  
 	public void setReadTimeout(int readTimeout) {
 387  
 		this.readTimeout = readTimeout;
 388  
 	}
 389  
 
 390  
 	/**
 391  
 	 * 生成さ�?�?MimeMessageに付けら�?�?Message-Idヘッダのドメイン部分を指定します。<br>
 392  
 	 * 指定さ�?ない�?�?(nullや空文字列の�?�?)は、JavaMailがMessage-Idヘッダを生成します。
 393  
 	 * JavaMailが生成す�?「JavaMail.実行ユーザ名@ホスト名」のMessage-Idを避けたい�?合に、このメソッドを使用します。
 394  
 	 * <p>
 395  
 	 * messageIdプ��叢ティがセットさ�?てい�?�?合、Mailから生成さ�?�?MimeMessageのMessage-Idには
 396  
 	 * <code>タイムスタンプ + ランダムに生成さ�?�?16桁の数値 + ここでセットさ�?た値</code>
 397  
 	 * が使用さ�?ます。
 398  
 	 * <p>
 399  
 	 * 生成さ�?�?Message-Idの例。 (実際の数値部分は送信メー�?毎に変�?ります)<ul>
 400  
 	 * <li>messageIdに'example.com'を指定した�?合・・・1095714924963.5619528074501343@example.com</li>
 401  
 	 * <li>messageIdに'@example.com'を指定した�?合・・・1095714924963.5619528074501343@example.com (上と同じ)</li>
 402  
 	 * <li>messageIdに'OML@example.com'を指定した�?合・・・1095714924963.5619528074501343.OML@example.com</li>
 403  
 	 * <li>messageIdに'.OML@example.com'を指定した�?合・・・1095714924963.5619528074501343.OML@example.com (上と同じ)</li>
 404  
 	 * </ul>
 405  
 	 * <p>
 406  
 	 * <strong>�?:</strong> このMessage-Idは<code>send(Mail)</code>か<code>send(Mail[])</code>メソッドが呼びだ�?た�?にのみ有効です。MimeMessageを直接送信す�?�?合には適用さ�?ません。
 407  
 	 * 
 408  
 	 * @param messageId メー�?に付けら�?�?Message-Idヘッダのドメイン部分
 409  
 	 * @throws IllegalArgumentException @を複数含んだ文字列を指定した�?�?
 410  
 	 */
 411  
 	public void setMessageId(String messageId) {
 412  
 		if (messageId == null || messageId.length() < 1) {
 413  
 			return;
 414  
 		}
 415  
 
 416  
 		String[] parts = messageId.split("@");
 417  
 		if (parts.length > 2) {
 418  
 			throw new IllegalArgumentException("messageIdプ��叢ティに'@'を複数含むことはできません。[" + messageId
 419  
 					+ "]");
 420  
 		}
 421  
 
 422  
 		this.messageId = messageId;
 423  
 	}
 424  
 
 425  
 	/**
 426  
 	 * MimeMessageインスタンスと、そのメー�?に対�?す�?Return-Path、envelope-toアド�?スをラップす�?クラス。
 427  
 	 * 
 428  
 	 * @author Tomohiro Otsuka
 429  
 	 * @version $Id: SendMailImpl.java,v 1.7.2.3 2005/01/29 23:09:36 otsuka Exp $
 430  
 	 */
 431  
 	private static class MimeMessageWrapper {
 432  
 
 433  
 		private MimeMessage mimeMessage;
 434  
 
 435  
 		private String returnPath;
 436  
 
 437  
 		private InternetAddress[] envelopeTo;
 438  
 
 439  0
 		public MimeMessageWrapper(MimeMessage mimeMessage, String returnPath) {
 440  0
 			this.mimeMessage = mimeMessage;
 441  0
 			this.returnPath = returnPath;
 442  0
 		}
 443  
 
 444  3
 		public MimeMessageWrapper(MimeMessage mimeMessage, String returnPath,
 445  
 				InternetAddress[] envelopeTo) {
 446  3
 			this.mimeMessage = mimeMessage;
 447  3
 			this.returnPath = returnPath;
 448  3
 			this.envelopeTo = envelopeTo;
 449  3
 		}
 450  
 
 451  
 		public MimeMessage getMimeMessage() {
 452  3
 			return mimeMessage;
 453  
 		}
 454  
 
 455  
 		public String getReturnPath() {
 456  3
 			return class="keyword">returnPath;
 457  
 		}
 458  
 
 459  
 		public boolean hasEnvelopeTo() {
 460  3
 			return envelopeTo.length > 0;
 461  
 		}
 462  
 
 463  
 		public InternetAddress[] getEnvelopeTo() {
 464  0
 			return envelopeTo;
 465  
 		}
 466  
 	}
 467  
 
 468  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.